diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java index 0fbce52dc66..e16f9884b58 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenBinding.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -156,7 +156,6 @@ public class CodegenBinding { closure.setCaptureThis(); } - assert PsiCodegenPredictor.checkPredictedNameFromPsi(classDescriptor, asmType, fileClassesManager); trace.record(ASM_TYPE, classDescriptor, asmType); trace.record(CLOSURE, classDescriptor, closure); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/PsiCodegenPredictor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/PsiCodegenPredictor.java deleted file mode 100644 index 80e2797e0a5..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/PsiCodegenPredictor.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.codegen.binding; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.codegen.AsmUtil; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; -import org.jetbrains.kotlin.fileClasses.FileClasses; -import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; -import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.org.objectweb.asm.Type; - -import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration; - -public final class PsiCodegenPredictor { - private PsiCodegenPredictor() { - } - - public static boolean checkPredictedNameFromPsi( - @NotNull DeclarationDescriptor descriptor, - @Nullable Type nameFromDescriptors, - @NotNull JvmFileClassesProvider fileClassesManager - ) { - PsiElement element = descriptorToDeclaration(descriptor); - if (element instanceof KtDeclaration) { - String classNameFromPsi = getPredefinedJvmInternalName((KtDeclaration) element, fileClassesManager); - assert classNameFromPsi == null || Type.getObjectType(classNameFromPsi).equals(nameFromDescriptors) : - String.format("Invalid algorithm for getting qualified name from psi! Predicted: %s, actual %s\n" + - "Element: %s", classNameFromPsi, nameFromDescriptors, element.getText()); - } - - return true; - } - - /** - * @return null if no prediction can be done. - */ - @Nullable - public static String getPredefinedJvmInternalName( - @NotNull KtDeclaration declaration, - @NotNull JvmFileClassesProvider fileClassesProvider - ) { - // TODO: Method won't work for declarations inside companion objects - // TODO: Method won't give correct class name for traits implementations - - if (declaration instanceof KtPropertyAccessor) { - return getPredefinedJvmInternalName(((KtPropertyAccessor) declaration).getProperty(), fileClassesProvider); - } - KtDeclaration parentDeclaration = KtStubbedPsiUtil.getContainingDeclaration(declaration); - - String parentInternalName; - if (parentDeclaration != null) { - parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesProvider); - if (parentInternalName == null) { - return null; - } - } - else { - KtFile containingFile = declaration.getContainingKtFile(); - - if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) { - Name name = ((KtNamedDeclaration) declaration).getNameAsName(); - return name == null ? null : FileClasses.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString(); - } - - parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(containingFile.getPackageFqName()); - } - - if (!PsiTreeUtil.instanceOf(declaration, KtClass.class, KtObjectDeclaration.class, KtNamedFunction.class, KtProperty.class) || - isEnumEntryWithoutBody(declaration)) { - // Other subclasses are not valid for class name prediction. - // For example JetFunctionLiteral - return null; - } - - Name name = ((KtNamedDeclaration) declaration).getNameAsName(); - if (name == null) { - return null; - } - - if (declaration instanceof KtNamedFunction) { - if (!(parentDeclaration instanceof KtClass || parentDeclaration instanceof KtObjectDeclaration)) { - // Can't generate predefined name for internal functions - return null; - } - } - - // NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not - // PackageClassName$propertyName$ClassName - if (declaration instanceof KtProperty) { - return parentInternalName + "$" + name.asString(); - } - - if (parentInternalName.isEmpty()) { - return name.asString(); - } - - return parentInternalName + (parentDeclaration == null ? "/" : "$") + name.asString(); - } - - private static boolean isEnumEntryWithoutBody(KtDeclaration declaration) { - if (!(declaration instanceof KtEnumEntry)) { - return false; - } - KtClassBody body = ((KtEnumEntry) declaration).getBody(); - return body == null || body.getDeclarations().size() == 0; - } -} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt index 556ed6eb0b7..e102455f39d 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt @@ -35,9 +35,7 @@ import com.intellij.util.IncorrectOperationException import com.intellij.util.containers.ContainerUtil import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.name.FqName @@ -49,7 +47,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.jvm.JvmClassName import java.util.* import javax.swing.Icon @@ -435,18 +432,28 @@ open class KtLightClassForExplicitDeclaration( classOrObject) } + if (isEnumEntryWithoutBody(classOrObject)) { + return null + } + val fqName = predictFqName(classOrObject) ?: return null return KtLightClassForExplicitDeclaration({ fqName }, classOrObject) } + private fun isEnumEntryWithoutBody(classOrObject: KtClassOrObject): Boolean { + if (classOrObject !is KtEnumEntry) { + return false + } + return classOrObject.getBody()?.declarations?.isEmpty() ?: true + } + private fun predictFqName(classOrObject: KtClassOrObject): FqName? { if (classOrObject.isLocal()) { if (classOrObject.containingFile.virtualFile == null) return null val data = getLightClassDataExactly(classOrObject) return data?.jvmQualifiedName } - val internalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject, NoResolveFileClassesProvider) - return if (internalName == null) null else JvmClassName.byInternalName(internalName).fqNameForClassNameWithoutDollars + return classOrObject.fqName } fun getLightClassData(classOrObject: KtClassOrObject): LightClassData { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.java index 340a7aefdf4..6d57bcc148e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.java @@ -40,13 +40,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.kotlin.builtins.DefaultBuiltIns; -import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor; import org.jetbrains.kotlin.config.LanguageVersion; import org.jetbrains.kotlin.context.ContextKt; import org.jetbrains.kotlin.context.MutableModuleContext; import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.ModuleDescriptorKt; -import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider; import org.jetbrains.kotlin.frontend.di.InjectionKt; import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex; import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope; @@ -62,7 +60,6 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingTraceContext; import org.jetbrains.kotlin.resolve.TargetPlatform; -import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform; import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer; import org.jetbrains.kotlin.resolve.lazy.ResolveSession; @@ -384,11 +381,10 @@ public class SourceNavigationHelper { @Nullable public static PsiClass getOriginalClass(@NotNull KtClassOrObject classOrObject) { // Copied from JavaPsiImplementationHelperImpl:getOriginalClass() - String internalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject, NoResolveFileClassesProvider.INSTANCE); - if (internalName == null) { + FqName fqName = classOrObject.getFqName(); + if (fqName == null) { return null; } - String fqName = JvmClassName.byInternalName(internalName).getFqNameForClassNameWithoutDollars().asString(); KtFile file = classOrObject.getContainingKtFile(); @@ -400,7 +396,7 @@ public class SourceNavigationHelper { if (vFile == null || !idx.isInLibrarySource(vFile)) return null; final Set orderEntries = new THashSet(idx.getOrderEntriesForFile(vFile)); - return JavaPsiFacade.getInstance(project).findClass(fqName, new GlobalSearchScope(project) { + return JavaPsiFacade.getInstance(project).findClass(fqName.asString(), new GlobalSearchScope(project) { @Override public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) { return 0;