@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; }
/** * Get names that could have jet descriptor equivalents. It could be inaccurate and return more * results than necessary. */ static Collection<String> getPossiblePackageDeclarationsNames( Project project, GlobalSearchScope scope) { Collection<String> result = new ArrayList<String>(); for (PsiClass packageClass : getClassesForKotlinPackages(project, scope)) { for (PsiMethod psiMethod : packageClass.getMethods()) { if (psiMethod.getModifierList().hasModifierProperty(PsiModifier.STATIC)) { result.add(psiMethod.getName()); } } } return result; }
@Nullable static FqName getJetTopLevelDeclarationFQN(@NotNull PsiMethod method) { PsiClass containingClass = method.getContainingClass(); if (containingClass != null) { String qualifiedName = containingClass.getQualifiedName(); assert qualifiedName != null; FqName classFQN = new FqName(qualifiedName); if (JavaResolverPsiUtils.isCompiledKotlinPackageClass(containingClass)) { FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN); return QualifiedNamesUtil.combine(classParentFQN, Name.identifier(method.getName())); } } return null; }
static Collection<PsiClass> getCompiledClassesForTopLevelObjects( Project project, GlobalSearchScope scope) { Set<PsiClass> jetObjectClasses = Sets.newHashSet(); Collection<PsiClass> classesByAnnotation = getClassesByAnnotation(KotlinClass.class.getSimpleName(), project, scope); for (PsiClass psiClass : classesByAnnotation) { ClassKind kind = getCompiledClassKind(psiClass); if (kind == null) { continue; } if (psiClass.getContainingClass() == null && kind == ClassKind.OBJECT) { jetObjectClasses.add(psiClass); } } return jetObjectClasses; }
@Nullable private static String[] getAnnotationDataForKotlinClass(@NotNull PsiClass psiClass) { VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass); if (virtualFile != null) { KotlinJvmBinaryClass kotlinClass = VirtualFileFinder.SERVICE .getInstance(psiClass.getProject()) .createKotlinClass(virtualFile); KotlinClassHeader header = kotlinClass.getClassHeader(); if (header != null) { return header.getAnnotationData(); } } return null; }
// TODO: common utility // TODO: doesn't work for inner classes and stuff @Nullable private static VirtualFile getVirtualFileForPsiClass(@NotNull PsiClass psiClass) { PsiFile psiFile = psiClass.getContainingFile(); return psiFile == null ? null : psiFile.getVirtualFile(); }