From 4fe78e4e7b5fecf1f2818a7f7757d873bf202f67 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 16 Jul 2013 17:55:56 +0400 Subject: [PATCH] Move utilities using annotations to determine whether PsiClass is kotlin class or package class to DescriptorResolverUtils Fix some of the usages PackageClassUtils uses more precise method name --- .../resolve/java/DescriptorResolverUtils.java | 33 +++++++++++++---- .../lang/resolve/java/PackageClassUtils.java | 15 ++++---- .../java/resolver/JavaNamespaceResolver.java | 36 ++++++------------- .../lang/resolve/java/scope/ScopeUtils.java | 2 +- .../jet/asJava/JavaElementFinder.java | 6 ++-- .../caches/JetFromJavaDescriptorHelper.java | 9 ++--- .../completion/DescriptorLookupConverter.java | 4 +-- .../completion/JetTypesCompletionHelper.java | 2 +- .../importOptimizer/JetImportOptimizer.java | 4 +-- .../libraries/DecompiledDataFactory.java | 7 ++-- .../plugin/libraries/JetDecompiledData.java | 2 +- 11 files changed, 61 insertions(+), 59 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java index f1d518e4fe7..15ae9c062af 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.intellij.psi.*; +import com.intellij.psi.impl.compiled.ClsClassImpl; import com.intellij.psi.util.PsiFormatUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,19 +38,39 @@ import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumClassObject; public final class DescriptorResolverUtils { + public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object"); private DescriptorResolverUtils() { } - //TODO: check that method is used properly - public static boolean isKotlinClass(@NotNull PsiClass psiClass) { - PsiModifierList modifierList = psiClass.getModifierList(); - if (modifierList == null) { + public static boolean isCompiledKotlinPackageClass(@NotNull PsiClass psiClass) { + if (!(psiClass instanceof ClsClassImpl)) { return false; } - PsiAnnotation kotlinClassAnnotation = modifierList.findAnnotation(JvmStdlibNames.KOTLIN_CLASS.getFqName().asString()); - return kotlinClassAnnotation != null; + if (!PackageClassUtils.isPackageClassFqName(new FqName(psiClass.getQualifiedName()))) { + return false; + } + return hasAnnotation(psiClass, JvmStdlibNames.KOTLIN_PACKAGE.getFqName()); + } + + public static boolean isCompiledKotlinClass(@NotNull PsiClass psiClass) { + if (!(psiClass instanceof ClsClassImpl)) { + return false; + } + return hasAnnotation(psiClass, JvmStdlibNames.KOTLIN_CLASS.getFqName()); + } + + public static boolean hasAnnotation(@NotNull PsiClass psiClass, @NotNull FqName annotationFqName) { + PsiModifierList list = psiClass.getModifierList(); + if (list != null) { + return list.findAnnotation(annotationFqName.asString()) != null; + } + return false; + } + + public static boolean isCompiledKotlinClassOrPackageClass(@NotNull PsiClass psiClass) { + return isCompiledKotlinClass(psiClass) || isCompiledKotlinPackageClass(psiClass); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java index bd7b764d03e..e5f0861bfad 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java @@ -17,15 +17,17 @@ package org.jetbrains.jet.lang.resolve.java; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClass; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; -public class PackageClassUtils { +public final class PackageClassUtils { private static final String DEFAULT_PACKAGE = "_DefaultPackage"; + private PackageClassUtils() { + } + // ex. -> _DefaultPackage, a -> APackage, a.b -> BPackage public static String getPackageClassName(@NotNull FqName packageFQN) { if (packageFQN.isRoot()) { @@ -38,15 +40,10 @@ public class PackageClassUtils { return packageFQN.child(Name.identifier(getPackageClassName(packageFQN))); } - public static boolean isPackageClass(@NotNull PsiClass psiClass) { - //TODO: read kotlin info - return psiClass.getName().endsWith("Package"); - } - - public static boolean isPackageClass(@NotNull FqName fqName) { + public static boolean isPackageClassFqName(@NotNull FqName fqName) { if (fqName.isRoot()) { return false; } - return PackageClassUtils.getPackageClassFqName(fqName.parent()).equals(fqName); + return getPackageClassFqName(fqName.parent()).equals(fqName); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java index 207164c5f42..9ff4935cdeb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java @@ -18,8 +18,10 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.intellij.psi.*; -import com.intellij.psi.impl.compiled.ClsClassImpl; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiPackage; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -164,12 +166,12 @@ public final class JavaNamespaceResolver { trace.record(JavaBindingContext.JAVA_NAMESPACE_KIND, namespaceDescriptor, JavaNamespaceKind.PROPER); if (psiClass != null) { - boolean hasKotlinPackageAnnotation = hasKotlinPackageAnnotation(psiClass); - if (isOldKotlinPackageClass(psiClass) && !hasKotlinPackageAnnotation) { + boolean isCompiledKotlinPackageClass = DescriptorResolverUtils.isCompiledKotlinPackageClass(psiClass); + if (isOldKotlinPackageClass(psiClass) && !isCompiledKotlinPackageClass) { // If psiClass has old annotations (@JetPackage) but doesn't have @KotlinPackage, report ABI version error AbiVersionUtil.checkAbiVersion(psiClass, INVALID_VERSION, trace); } - if (hasKotlinPackageAnnotation) { + if (isCompiledKotlinPackageClass) { // If psiClass has @KotlinPackage (regardless of whether it has @JetPackage or not), deserialize it to Kotlin descriptor. // Note that @KotlinPackage may still have an old ABI version, in which case null is returned by createKotlinPackageScope JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(psiClass, namespaceDescriptor); @@ -186,7 +188,7 @@ public final class JavaNamespaceResolver { if (psiClass == null) { return null; } - if (DescriptorResolverUtils.isKotlinClass(psiClass)) { + if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(psiClass)) { return null; } if (!hasStaticMembers(psiClass)) { @@ -200,25 +202,7 @@ public final class JavaNamespaceResolver { } private static boolean isOldKotlinPackageClass(@NotNull PsiClass psiClass) { - return hasAnnotation(psiClass, JvmStdlibNames.JET_PACKAGE_CLASS.getFqName()); - } - - private static boolean hasKotlinPackageAnnotation(@NotNull PsiClass psiClass) { - // TODO: merge this method with DescriptorResolverUtils#isKotlinClass - // NOTE: we need to check against ClsClassImpl because it can be a Java source, pretending to be a Kotlin class. - // In that case we can't really read the annotation from psiClass's virtual file - if (!(psiClass instanceof ClsClassImpl)) { - return false; - } - return hasAnnotation(psiClass, JvmStdlibNames.KOTLIN_PACKAGE.getFqName()); - } - - private static boolean hasAnnotation(@NotNull PsiClass psiClass, @NotNull FqName annotationFqName) { - PsiModifierList list = psiClass.getModifierList(); - if (list != null) { - return list.findAnnotation(annotationFqName.asString()) != null; - } - return false; + return DescriptorResolverUtils.hasAnnotation(psiClass, JvmStdlibNames.JET_PACKAGE_CLASS.getFqName()); } private void cache(@NotNull FqName fqName, @Nullable JetScope packageScope) { @@ -280,7 +264,7 @@ public final class JavaNamespaceResolver { PsiClass[] classes = psiPackage.getClasses(); List result = new ArrayList(classes.length); for (PsiClass psiClass : classes) { - if (DescriptorResolverUtils.isKotlinClass(psiClass)) { + if (DescriptorResolverUtils.isCompiledKotlinClass(psiClass)) { result.add(Name.identifier(psiClass.getName())); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/ScopeUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/ScopeUtils.java index 6f0c70255ef..12ad23f1c2d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/ScopeUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/ScopeUtils.java @@ -51,7 +51,7 @@ public final class ScopeUtils { } for (PsiClass psiClass : javaSemanticServices.getPsiClassFinder().findPsiClasses(psiPackage)) { - if (PackageClassUtils.isPackageClass(psiClass)) { + if (DescriptorResolverUtils.isCompiledKotlinPackageClass(psiClass)) { continue; } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java index c0c74e566f4..5409b264260 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java @@ -30,7 +30,9 @@ import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.NamespaceCodegen; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetEnumEntry; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.java.JavaPsiFacadeKotlinHacks; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -85,7 +87,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade findClassesAndObjects(qualifiedName, scope, answer); - if (PackageClassUtils.isPackageClass(qualifiedName)) { + if (PackageClassUtils.isPackageClassFqName(qualifiedName)) { findPackageClass(qualifiedName.parent(), scope, answer); } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java index 95c290d0f19..a39f485f5e1 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetFromJavaDescriptorHelper.java @@ -24,13 +24,11 @@ import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex; import com.intellij.psi.search.GlobalSearchScope; import jet.KotlinClass; import jet.KotlinPackage; -import com.intellij.psi.util.PsiTreeUtil; -import jet.runtime.typeinfo.JetPackageClass; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.*; import org.jetbrains.jet.lang.descriptors.ClassKind; -import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -95,9 +93,6 @@ public class JetFromJavaDescriptorHelper { @Nullable public static ClassKind getCompiledClassKind(@NotNull PsiClass psiClass) { - if (PackageClassUtils.isPackageClass(psiClass)) { - return null; - } ClassData classData = getClassData(psiClass); if (classData == null) return null; return DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(classData.getClassProto().getFlags())); @@ -143,7 +138,7 @@ public class JetFromJavaDescriptorHelper { FqName classFQN = new FqName(qualifiedName); - if (PackageClassUtils.isPackageClass(containingClass)) { + if (DescriptorResolverUtils.isCompiledKotlinPackageClass(containingClass)) { FqName classParentFQN = QualifiedNamesUtil.withoutLastSegment(classFQN); return QualifiedNamesUtil.combine(classParentFQN, Name.identifier(method.getName())); } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java index c1116b5c19b..69a09bc940f 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java @@ -138,14 +138,14 @@ public final class DescriptorLookupConverter { private static LookupElement createJavaLookupElementIfPossible(@NotNull PsiElement declaration, @NotNull DeclarationDescriptor descriptor) { if (declaration instanceof PsiClass) { PsiClass psiClass = (PsiClass) declaration; - if (!DescriptorResolverUtils.isKotlinClass(psiClass)) { + if (!DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(psiClass)) { return setCustomInsertHandler(new JavaPsiClassReferenceElement(psiClass)); } } if (declaration instanceof PsiMember) { PsiClass containingClass = ((PsiMember) declaration).getContainingClass(); - if (containingClass != null && !DescriptorResolverUtils.isKotlinClass(containingClass)) { + if (containingClass != null && !DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(containingClass)) { if (declaration instanceof PsiMethod) { InsertHandler handler = getInsertHandler(descriptor); assert handler != null: "Special kotlin handler is expected for function: " + declaration.getText() + " and descriptor" + DescriptorRenderer.TEXT.render(descriptor); diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java index 81df7053dbd..c6e5867491d 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java @@ -92,7 +92,7 @@ public class JetTypesCompletionHelper { return true; } - if (DescriptorResolverUtils.isKotlinClass(aClass)) { + if (DescriptorResolverUtils.isCompiledKotlinClass(aClass)) { if (JetFromJavaDescriptorHelper.getCompiledClassKind(aClass) != ClassKind.CLASS_OBJECT) { String qualifiedName = aClass.getQualifiedName(); if (qualifiedName != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java index cd3b3ba6067..5976d749118 100644 --- a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java +++ b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; @@ -283,7 +283,7 @@ public class JetImportOptimizer implements ImportOptimizer { if (memberName == null) { return null; } - if (PackageClassUtils.isPackageClass(containingClass)) { + if (DescriptorResolverUtils.isCompiledKotlinPackageClass(containingClass)) { return QualifiedNamesUtil.combine(classFQN.parent(), Name.identifier(memberName)); } else { diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java index 339ab450343..4339cf7092b 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java @@ -32,7 +32,10 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.MemberComparator; -import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; +import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRendererBuilder; @@ -77,7 +80,7 @@ public class DecompiledDataFactory { PsiClass psiClass = clsFile.getClasses()[0]; - if (PackageClassUtils.isPackageClass(psiClass)) { + if (DescriptorResolverUtils.isCompiledKotlinPackageClass(psiClass)) { NamespaceDescriptor nd = javaDescriptorResolver.resolveNamespace(new FqName(packageName), DescriptorSearchRule.INCLUDE_KOTLIN); if (nd != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompiledData.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompiledData.java index 10853bf5237..106f95665d6 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompiledData.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompiledData.java @@ -78,7 +78,7 @@ public class JetDecompiledData { } public static boolean isKotlinFile(@NotNull ClsFileImpl clsFile) { - return DescriptorResolverUtils.isKotlinClass(clsFile.getClasses()[0]); + return DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(clsFile.getClasses()[0]); } @NotNull