From e812c4e67f792837c159122a6fc881501fe73100 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 13 Feb 2015 21:44:48 +0300 Subject: [PATCH] Introduce KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL --- .../kotlin/codegen/TraitImplBodyCodegen.java | 4 +- .../KotlinSyntheticClassAnnotationTest.java | 40 +++++++++---------- .../kotlin/load/java/JvmAnnotationNames.java | 1 + .../jvm/internal/KotlinSyntheticClass.java | 2 +- .../kotlin/idea/decompiler/DecompiledUtils.kt | 4 +- .../internalClasses/InternalClasses.kt | 3 ++ .../AbstractInternalCompiledClassesTest.kt | 6 +-- 7 files changed, 31 insertions(+), 29 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/TraitImplBodyCodegen.java index fc118cccb65..48bd6ac8610 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/TraitImplBodyCodegen.java @@ -54,10 +54,8 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen { @Override protected void generateKotlinAnnotation() { - // We write LOCAL_CLASS to local trait-impl, because we don't want PSI classes to be constructed for such files - // (currently PSI for synthetic class is built only if this class is a trait-impl, see DecompiledUtils.kt) writeKotlinSyntheticClassAnnotation(v, DescriptorUtils.isTopLevelOrInnerClass(descriptor) ? KotlinSyntheticClass.Kind.TRAIT_IMPL - : KotlinSyntheticClass.Kind.LOCAL_CLASS); + : KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL); } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java b/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java index 334aa7220a5..03d8376524b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/KotlinSyntheticClassAnnotationTest.java @@ -45,92 +45,90 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase { public void testPackagePart() { doTest("fun foo() = 42", "$", - PACKAGE_PART, false); + PACKAGE_PART); } public void testTraitImpl() { doTest("trait A { fun foo() = 42 }", JvmAbi.TRAIT_IMPL_SUFFIX, - TRAIT_IMPL, true); + TRAIT_IMPL); } public void testSamWrapper() { doTest("val f = {}\nval foo = Thread(f)", "$sam", - SAM_WRAPPER, false); + SAM_WRAPPER); } public void testSamLambda() { doTest("val foo = Thread { }", "$1", - SAM_LAMBDA, true); + SAM_LAMBDA); } public void testCallableReferenceWrapper() { doTest("val f = String::get", "$1", - CALLABLE_REFERENCE_WRAPPER, true); + CALLABLE_REFERENCE_WRAPPER); } public void testLocalFunction() { doTest("fun foo() { fun bar() {} }", "$1", - LOCAL_FUNCTION, true); + LOCAL_FUNCTION); } public void testAnonymousFunction() { doTest("val f = {}", "$1", - ANONYMOUS_FUNCTION, true); + ANONYMOUS_FUNCTION); } public void testLocalClass() { doTest("fun foo() { class Local }", "Local", - LOCAL_CLASS, true); + LOCAL_CLASS); } public void testLocalTraitImpl() { doTest("fun foo() { trait Local { fun bar() = 42 } }", - "Local$$TImpl", - LOCAL_CLASS, true); + "Local$$TImpl.class", + LOCAL_TRAIT_IMPL); } public void testLocalTraitInterface() { doTest("fun foo() { trait Local { fun bar() = 42 } }", - "Local", - LOCAL_CLASS, true); + "Local.class", + LOCAL_CLASS); } public void testInnerClassOfLocalClass() { doTest("fun foo() { class Local { inner class Inner } }", "Inner", - LOCAL_CLASS, true); + LOCAL_CLASS); } public void testAnonymousObject() { doTest("val o = object {}", "$1", - ANONYMOUS_OBJECT, true); + ANONYMOUS_OBJECT); } private void doTest( @NotNull String code, - @NotNull final String classNamePart, - @NotNull KotlinSyntheticClass.Kind expectedKind, - final boolean endWithNotContains + @NotNull final String classFilePart, + @NotNull KotlinSyntheticClass.Kind expectedKind ) { loadText("package " + PACKAGE_NAME + "\n\n" + code); List output = generateClassesInFile().asList(); Collection files = Collections2.filter(output, new Predicate() { @Override public boolean apply(OutputFile file) { - String path = file.getRelativePath(); - return endWithNotContains ? path.endsWith(classNamePart + ".class") : path.contains(classNamePart); + return file.getRelativePath().contains(classFilePart); } }); - assertFalse("No files with \"" + classNamePart + "\" in the name are found: " + output, files.isEmpty()); - assertTrue("Exactly one file with \"" + classNamePart + "\" in the name should be found: " + files, files.size() == 1); + assertFalse("No files with \"" + classFilePart + "\" in the name are found: " + output, files.isEmpty()); + assertTrue("Exactly one file with \"" + classFilePart + "\" in the name should be found: " + files, files.size() == 1); String path = files.iterator().next().getRelativePath(); String fqName = path.substring(0, path.length() - ".class".length()).replace('/', '.'); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index fdd7d999cf9..f22e6aefcd9 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -59,6 +59,7 @@ public final class JvmAnnotationNames { public enum Kind { PACKAGE_PART, TRAIT_IMPL, + LOCAL_TRAIT_IMPL, SAM_WRAPPER, SAM_LAMBDA, CALLABLE_REFERENCE_WRAPPER, diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/KotlinSyntheticClass.java b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinSyntheticClass.java index 7cf4669d776..ff8a0eabbae 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/KotlinSyntheticClass.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinSyntheticClass.java @@ -26,10 +26,10 @@ public @interface KotlinSyntheticClass { Kind kind(); // Inner classes of local classes have kind LOCAL_CLASS - // Local trait-impl also has kind LOCAL_CLASS public static enum Kind { PACKAGE_PART, TRAIT_IMPL, + LOCAL_TRAIT_IMPL, SAM_WRAPPER, SAM_LAMBDA, CALLABLE_REFERENCE_WRAPPER, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt index 4ec5cd1407b..9289af87b70 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt @@ -29,7 +29,9 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean { } val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader() - return header != null && header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL + return header != null && + header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL && + header.syntheticClassKind != KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL } public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean { diff --git a/idea/testData/decompiler/internalClasses/InternalClasses.kt b/idea/testData/decompiler/internalClasses/InternalClasses.kt index 1b36f173e22..0c904821719 100644 --- a/idea/testData/decompiler/internalClasses/InternalClasses.kt +++ b/idea/testData/decompiler/internalClasses/InternalClasses.kt @@ -23,6 +23,9 @@ fun f() { class MyLocalClass { } + trait MyLocalTrait { + } + val myAnonymousObject = object { } diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt index 55d14772ccd..c401fdb7b50 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt @@ -37,7 +37,7 @@ public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightF } protected fun doTestTraitImplClassIsVisibleAsJavaClass() { - val project = getProject()!! + val project = getProject() doTest("trait impl", isSyntheticClassOfKind(TRAIT_IMPL)) { val psiFile = PsiManager.getInstance(project).findFile(this)!! Assert.assertTrue("Should not be kotlin file", @@ -50,7 +50,7 @@ public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightF decompiledPsiFile is PsiJavaFile) val classes = (decompiledPsiFile as PsiJavaFile).getClasses() Assert.assertTrue("Should have some decompiled text", - classes.size == 1 && classes[0].getName()!!.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) + classes.size() == 1 && classes[0].getName()!!.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) } } @@ -58,7 +58,7 @@ public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightF doTestNoPsiFilesAreBuiltFor(kind.toString(), isSyntheticClassOfKind(kind)) protected fun doTestNoPsiFilesAreBuiltFor(fileKind: String, acceptFile: VirtualFile.() -> Boolean) { - val project = getProject()!! + val project = getProject() doTest(fileKind, acceptFile) { val psiFile = PsiManager.getInstance(project).findFile(this) Assert.assertNull("PSI files for $fileKind classes should not be build, is was build for: ${this.getPresentableName()}",