@NotNull public static Collection<ClassDescriptor> getClassOrObjectDescriptorsByFqName( @NotNull ResolveSession resolveSession, @NotNull FqName fqName, boolean includeObjectDeclarations) { if (fqName.isRoot()) { return Collections.emptyList(); } Collection<ClassDescriptor> classDescriptors = Lists.newArrayList(); FqName packageFqName = fqName.parent(); while (true) { NamespaceDescriptor packageDescriptor = resolveSession.getPackageDescriptorByFqName(packageFqName); if (packageDescriptor != null) { FqName classInPackagePath = new FqName(QualifiedNamesUtil.tail(packageFqName, fqName)); Collection<ClassDescriptor> descriptors = getClassOrObjectDescriptorsByFqName( packageDescriptor, classInPackagePath, includeObjectDeclarations); classDescriptors.addAll(descriptors); } if (packageFqName.isRoot()) { break; } else { packageFqName = packageFqName.parent(); } } return classDescriptors; }
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull FqName fqName) { if (alreadyImported.isAllUnder() && !fqName.isRoot()) { return alreadyImported.fqnPart().equals(fqName.parent()); } return alreadyImported.fqnPart().equals(fqName); }
@NotNull private static Set<DeclarationDescriptor> getTopLevelDescriptorsByFqName( @NotNull KotlinCodeAnalyzer resolveSession, @NotNull FqName fqName) { FqName parentFqName = fqName.parent(); Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>(); LazyPackageDescriptor parentFragment = resolveSession.getPackageFragment(parentFqName); if (parentFragment != null) { // Filter out extension properties descriptors.addAll( KotlinPackage.filter( parentFragment.getMemberScope().getProperties(fqName.shortName()), new Function1<VariableDescriptor, Boolean>() { @Override public Boolean invoke(VariableDescriptor descriptor) { return descriptor.getReceiverParameter() == null; } })); } ContainerUtil.addIfNotNull(descriptors, resolveSession.getPackageFragment(fqName)); descriptors.addAll(resolveSession.getTopLevelClassDescriptors(fqName)); return descriptors; }
@NotNull public static Collection<FqName> getTopLevelFunctionFqNames( @NotNull Project project, @NotNull GlobalSearchScope scope, boolean shouldBeExtension) { Collection<FqName> result = Sets.newHashSet(); Collection<PsiClass> packageClasses = getClassesByAnnotation(KotlinPackage.class.getSimpleName(), project, scope); for (PsiClass psiClass : packageClasses) { String qualifiedName = psiClass.getQualifiedName(); if (qualifiedName == null) { continue; } FqName packageFqName = new FqName(qualifiedName).parent(); PackageData data = getPackageData(psiClass); if (data == null) { continue; } NameResolver nameResolver = data.getNameResolver(); for (ProtoBuf.Callable callable : data.getPackageProto().getMemberList()) { if (callable.hasReceiverType() == shouldBeExtension) { Name name = nameResolver.getName(callable.getName()); result.add(packageFqName.child(name)); } } } return result; }
@NotNull @Override public Collection<DeclarationDescriptor> getAllDescriptors() { List<DeclarationDescriptor> result = Lists.newArrayList(); for (FqName subFqName : module.getPackageFragmentProvider().getSubPackagesOf(fqName)) { ContainerUtil.addIfNotNull(result, getPackage(subFqName.shortName())); } return result; }
@NotNull public static FqName withoutFirstSegment(@NotNull FqName fqName) { if (fqName.isRoot() || fqName.parent().isRoot()) { return FqName.ROOT; } String fqNameStr = fqName.getFqName(); return new FqName(fqNameStr.substring(fqNameStr.indexOf('.'), fqNameStr.length())); }
/** * Get tail part of the full fqn by subtracting head part. * * @param headFQN * @param fullFQN * @return tail fqn. If first part is not a begging of the full fqn, fullFQN will be returned. */ @NotNull public static String tail(@NotNull FqName headFQN, @NotNull FqName fullFQN) { if (!isSubpackageOf(fullFQN, headFQN) || headFQN.isRoot()) { return fullFQN.getFqName(); } return fullFQN.equals(headFQN) ? "" : fullFQN.getFqName().substring(headFQN.getFqName().length() + 1); // (headFQN + '.').length }
@Override public void serialize(@NotNull PsiJetParameterStub stub, @NotNull StubOutputStream dataStream) throws IOException { dataStream.writeName(stub.getName()); dataStream.writeBoolean(stub.isMutable()); dataStream.writeBoolean(stub.isVarArg()); dataStream.writeName(stub.getTypeText()); dataStream.writeName(stub.getDefaultValueText()); FqName name = stub.getFqName(); dataStream.writeName(name != null ? name.asString() : null); }
@Nullable public AnnotationDescriptor resolveAnnotation( @NotNull JavaAnnotation javaAnnotation, @NotNull PostponedTasks postponedTasks) { final AnnotationDescriptor annotation = new AnnotationDescriptor(); FqName fqName = javaAnnotation.getFqName(); if (fqName == null) { return null; } // Don't process internal jet annotations and jetbrains NotNull annotations if (fqName.asString().startsWith("jet.runtime.typeinfo.") || fqName.equals(JETBRAINS_NOT_NULL_ANNOTATION) || fqName.equals(JvmAnnotationNames.KOTLIN_CLASS) || fqName.equals(JvmAnnotationNames.KOTLIN_PACKAGE)) { return null; } AnnotationDescriptor mappedClassDescriptor = JavaToKotlinClassMap.getInstance().mapToAnnotationClass(fqName); if (mappedClassDescriptor != null) { return mappedClassDescriptor; } final ClassDescriptor annotationClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, postponedTasks); if (annotationClass == null) { return null; } postponedTasks.addTask( new Runnable() { @Override public void run() { annotation.setAnnotationType(annotationClass.getDefaultType()); } }); for (JavaAnnotationArgument argument : javaAnnotation.getArguments()) { CompileTimeConstant value = argumentResolver.resolveAnnotationArgument(fqName, argument, postponedTasks); if (value == null) continue; Name name = argument.getName(); ValueParameterDescriptor descriptor = DescriptorResolverUtils.getAnnotationParameterByName( name == null ? DEFAULT_ANNOTATION_MEMBER_NAME : name, annotationClass); if (descriptor != null) { annotation.setValueArgument(descriptor, value); } } return annotation; }
public Collection<ClassDescriptor> getJetClassesDescriptors( @NotNull Condition<String> acceptedShortNameCondition, @NotNull KotlinCodeAnalyzer analyzer) { Collection<ClassDescriptor> classDescriptors = new ArrayList<ClassDescriptor>(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { FqName classFQName = new FqName(fqName); if (acceptedShortNameCondition.value(classFQName.shortName().getName())) { classDescriptors.addAll( ResolveSessionUtils.getClassDescriptorsByFqName(analyzer, classFQName)); } } return classDescriptors; }
private void initPrimitives() { KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); String name = jvmPrimitiveType.getName(); FqName wrapperFqName = jvmPrimitiveType.getWrapperFqName(); register(wrapperFqName, builtIns.getPrimitiveClassDescriptor(primitiveType)); primitiveTypesMap.put(name, builtIns.getPrimitiveJetType(primitiveType)); primitiveTypesMap.put("[" + name, builtIns.getPrimitiveArrayJetType(primitiveType)); primitiveTypesMap.put( wrapperFqName.asString(), builtIns.getNullablePrimitiveJetType(primitiveType)); } primitiveTypesMap.put("void", KotlinBuiltIns.getInstance().getUnitType()); }
@Override public void indexProperty(PsiJetPropertyStub stub, IndexSink sink) { String propertyName = stub.getName(); if (propertyName != null) { if (stub.isTopLevel()) { FqName topFQName = stub.getTopFQName(); if (topFQName != null) { sink.occurrence( JetTopLevelPropertiesFqnNameIndex.getInstance().getKey(), topFQName.getFqName()); } } sink.occurrence(JetShortPropertiesNameIndex.getInstance().getKey(), propertyName); } }
@Override public void indexFile(PsiJetFileStub stub, IndexSink sink) { String packageName = stub.getPackageName(); FqName fqName = new FqName(packageName == null ? "" : packageName); sink.occurrence(JetPackageDeclarationIndex.getInstance().getKey(), fqName.getFqName()); while (true) { sink.occurrence(JetAllPackagesIndex.getInstance().getKey(), fqName.getFqName()); if (fqName.isRoot()) { return; } fqName = fqName.parent(); } }
// TODO: includeRuntime should be not a flag but a path to runtime public static void writeToJar( ClassFileFactory factory, final OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) { try { Manifest manifest = new Manifest(); final Attributes mainAttributes = manifest.getMainAttributes(); mainAttributes.putValue("Manifest-Version", "1.0"); mainAttributes.putValue("Created-By", "JetBrains Kotlin"); if (mainClass != null) { mainAttributes.putValue("Main-Class", mainClass.getFqName()); } JarOutputStream stream = new JarOutputStream(fos, manifest); for (String file : factory.files()) { stream.putNextEntry(new JarEntry(file)); stream.write(factory.asBytes(file)); } if (includeRuntime) { writeRuntimeToJar(stream); } stream.finish(); } catch (IOException e) { throw new CompileEnvironmentException("Failed to generate jar file", e); } }
/** Check that import is useless. */ private static boolean isImportedByDefault( @NotNull ImportPath importPath, @Nullable String aliasName, @NotNull FqName filePackageFqn) { if (importPath.fqnPart().isRoot()) { return true; } if (aliasName != null) { return false; } // Single element import without .* and alias is useless if (!importPath.isAllUnder() && QualifiedNamesUtil.isOneSegmentFQN(importPath.fqnPart())) { return true; } // There's no need to import a declaration from the package of current file if (!importPath.isAllUnder() && filePackageFqn.equals(importPath.fqnPart().parent())) { return true; } if (isImportedWithKotlinDefault(importPath)) return true; if (isImportedWithJavaDefault(importPath)) return true; return false; }
public static boolean isSubpackageOf( @NotNull final FqName subpackageName, @NotNull FqName packageName) { if (subpackageName.equals(packageName)) { return true; } if (packageName.isRoot()) { return true; } String subpackageNameStr = subpackageName.getFqName(); String packageNameStr = packageName.getFqName(); return (subpackageNameStr.startsWith(packageNameStr) && subpackageNameStr.charAt(packageNameStr.length()) == '.'); }
@NotNull @Override public Collection<Name> getClassNames(@NotNull FqName packageName) { return packageName.equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) ? classNames.invoke() : Collections.<Name>emptyList(); }
@Override public boolean isEqual(FqName val1, FqName val2) { if (val1 == null) { return val2 == null; } return val1.equals(val1); }
@Nullable public AnnotationDescriptor mapToAnnotationClass(@NotNull FqName fqName) { ClassDescriptor classDescriptor = classDescriptorMap.get(fqName); if (classDescriptor != null && fqName.equals(JAVA_LANG_DEPRECATED)) { return getAnnotationDescriptorForJavaLangDeprecated(classDescriptor); } return null; }
@NotNull @Override public Collection<FqName> getSubPackagesOf(@NotNull FqName fqName) { if (fqName.isRoot()) { return Collections.singleton(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME); } return Collections.emptyList(); }
@Override public void indexObject(PsiJetObjectStub stub, IndexSink sink) { String name = stub.getName(); assert name != null; sink.occurrence(JetShortClassNameIndex.getInstance().getKey(), name); if (stub.isTopLevel()) { sink.occurrence(JetTopLevelShortObjectNameIndex.getInstance().getKey(), name); } FqName fqName = stub.getFQName(); if (fqName != null) { sink.occurrence(JetFullClassNameIndex.getInstance().getKey(), fqName.getFqName()); } recordClassOrObjectByPackage(stub, sink); }
@Nullable public static ClassDescriptor getKotlinBuiltinClassDescriptor(@NotNull FqName qualifiedName) { if (!qualifiedName.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) return null; List<Name> segments = qualifiedName.pathSegments(); if (segments.size() < 2) return null; JetScope scope = KotlinBuiltIns.getInstance().getBuiltInsPackageScope(); for (int i = 1, size = segments.size(); i < size; i++) { ClassifierDescriptor classifier = scope.getClassifier(segments.get(i)); if (classifier == null) return null; assert classifier instanceof ClassDescriptor : "Unexpected classifier in built-ins: " + classifier; scope = ((ClassDescriptor) classifier).getUnsubstitutedInnerClassesScope(); } return (ClassDescriptor) scope.getContainingDeclaration(); }
public static void addImportDirectiveOrChangeToFqName( @NotNull FqName importFqn, @NotNull JetFile file, int refOffset, @NotNull PsiElement targetElement) { PsiReference reference = file.findReferenceAt(refOffset); if (reference instanceof JetPsiReference) { PsiElement target = reference.resolve(); if (target != null) { boolean same = file.getManager().areElementsEquivalent(target, targetElement); if (!same) { same = target instanceof PsiClass && importFqn.getFqName().equals(((PsiClass) target).getQualifiedName()); } if (!same) { if (target instanceof PsiMethod) { PsiMethod method = (PsiMethod) target; same = (method.isConstructor() && file.getManager() .areElementsEquivalent(method.getContainingClass(), targetElement)); } } if (!same) { if (target instanceof JetObjectDeclarationName) { same = file.getManager().areElementsEquivalent(target.getParent(), targetElement); } } if (!same) { Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); TextRange refRange = reference.getElement().getTextRange(); document.replaceString( refRange.getStartOffset(), refRange.getEndOffset(), importFqn.getFqName()); } return; } } addImportDirective(new ImportPath(importFqn, false), null, file); }
@Override public ClassDescriptor getObjectDescriptor(@NotNull Name name) { ClassDescriptor classDescriptor = getResolver() .resolveClass(packageFQN.child(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); if (classDescriptor != null && classDescriptor.getKind().isObject()) { return classDescriptor; } return null; }
@NotNull @Override public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) { if (fqName.isRoot()) { return Collections.singletonList(rootPackage); } else if (KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(fqName)) { return Collections.<PackageFragmentDescriptor>singletonList(BuiltinsPackageFragment.this); } return Collections.emptyList(); }
@Nullable @Override public ClassDescriptor getClass(@NotNull JavaClass javaClass) { FqName fqName = javaClass.getFqName(); if (fqName != null && KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(fqName.parent())) { if (javaClass.findAnnotation(ASSERT_INVISIBLE_IN_RESOLVER_ANNOTATION) != null) { if (ApplicationManager.getApplication().isInternal()) { LOG.error( "Classpath is configured incorrectly:" + " class " + fqName + " from runtime must not be loaded by compiler"); } return null; } } return trace.get(CLASS, ((JavaClassImpl) javaClass).getPsi()); }
@Override public void visitClassType(String name, boolean nullable, boolean forceReal) { FqName ourName = new FqName( name.replace('/', '.').replace('$', '.') // TODO: not sure ); this.classDescriptor = null; if (!forceReal) { classDescriptor = javaSemanticServices .getTypeTransformer() .getKotlinAnalog(ourName, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_INVARIANT); } if (classDescriptor == null) { // TODO: this is the worst code in Kotlin project Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1))); } } if (classDescriptor == null) { Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName.getFqName()); if (matcher.matches()) { classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1))); } } if (this.classDescriptor == null) { this.classDescriptor = javaDescriptorResolver.resolveClass(ourName, DescriptorSearchRule.INCLUDE_KOTLIN); } if (this.classDescriptor == null) { // TODO: report in to trace this.errorType = ErrorUtils.createErrorType("class not found by name: " + ourName); } this.nullable = nullable; this.typeArguments = new ArrayList<TypeProjection>(); }
@Nullable private static FqName getFQName(@Nullable JetExpression expression) { if (expression == null) { return null; } if (expression instanceof JetDotQualifiedExpression) { JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression; FqName parentFqn = getFQName(dotQualifiedExpression.getReceiverExpression()); Name child = getName(dotQualifiedExpression.getSelectorExpression()); return parentFqn != null && child != null ? parentFqn.child(child) : null; } else if (expression instanceof JetSimpleNameExpression) { JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression; return FqName.topLevel(simpleNameExpression.getReferencedNameAsName()); } else { throw new IllegalArgumentException( "Can't construct fqn for: " + expression.getClass().toString()); } }
public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PackageViewDescriptorImpl that = (PackageViewDescriptorImpl) o; if (!fqName.equals(that.fqName)) return false; if (!module.equals(that.module)) return false; return true; }
@Nullable public static FqName getFQName(@NotNull JetNamedDeclaration namedDeclaration) { Name name = namedDeclaration.getNameAsName(); if (name == null) { return null; } PsiElement parent = namedDeclaration.getParent(); if (parent instanceof JetClassBody) { // One nesting to JetClassBody doesn't affect to qualified name parent = parent.getParent(); } FqName firstPart = null; if (parent instanceof JetFile) { firstPart = getFQName((JetFile) parent); } else if (parent instanceof JetNamedFunction || parent instanceof JetClass) { firstPart = getFQName((JetNamedDeclaration) parent); } else if (namedDeclaration instanceof JetParameter) { JetClass constructorClass = getClassIfParameterIsProperty((JetParameter) namedDeclaration); if (constructorClass != null) { firstPart = getFQName(constructorClass); } } else if (parent instanceof JetObjectDeclaration) { if (parent.getParent() instanceof JetClassObject) { JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(parent, JetClassOrObject.class); if (classOrObject != null) { firstPart = getFQName(classOrObject); } } else { firstPart = getFQName((JetNamedDeclaration) parent); } } if (firstPart == null) { return null; } return firstPart.child(name); }