From 7fda4ef43808aaf5eabf2292bf69fb903b9ef130 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 31 Mar 2015 18:52:08 +0300 Subject: [PATCH] Don't show local/anonymous classes in libraries in Project view --- .../kotlin/idea/decompiler/DecompiledUtils.kt | 22 ++++++++++--- .../AbstractInternalCompiledClassesTest.kt | 32 ++++++++++++------- .../decompiler/InternalCompiledClassesTest.kt | 8 ++++- 3 files changed, 45 insertions(+), 17 deletions(-) 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 9289af87b70..ebb59f989a9 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 @@ -16,13 +16,17 @@ package org.jetbrains.kotlin.idea.decompiler +import com.intellij.ide.highlighter.JavaClassFileType import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.ClassFileViewProvider +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader -import com.intellij.psi.ClassFileViewProvider -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass -import com.intellij.ide.highlighter.JavaClassFileType +/** + * Checks if this file is a compiled Kotlin class file (not necessarily ABI-compatible with the current plugin) + */ public fun isKotlinCompiledFile(file: VirtualFile): Boolean { if (file.getExtension() != JavaClassFileType.INSTANCE!!.getDefaultExtension()) { return false @@ -34,6 +38,9 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean { header.syntheticClassKind != KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL } +/** + * Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin + */ public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean { if (!isKotlinCompiledFile(file)) return false @@ -41,6 +48,10 @@ public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean { return header != null && header.isCompatibleAbiVersion } +/** + * Checks if this file is a compiled "internal" Kotlin class, i.e. a Kotlin class (not necessarily ABI-compatible with the current plugin) + * which should NOT be decompiled (and, as a result, shown under the library in the Project view, be searchable via Find class, etc.) + */ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { if (!isKotlinCompiledFile(file)) { return false @@ -49,6 +60,7 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { if (ClassFileViewProvider.isInnerClass(file)) { return true } - val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader() - return header?.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS + val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader() ?: return false + return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS || + (header.kind == KotlinClassHeader.Kind.CLASS && header.classKind != null && header.classKind != KotlinClass.Kind.CLASS) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt index c401fdb7b50..aa021f90a18 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/AbstractInternalCompiledClassesTest.kt @@ -16,26 +16,33 @@ package org.jetbrains.kotlin.idea.decompiler - -import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.load.java.JvmAbi -import com.intellij.psi.PsiManager -import org.junit.Assert -import com.intellij.psi.impl.compiled.ClsFileImpl import com.intellij.psi.PsiCompiledFile import com.intellij.psi.PsiJavaFile -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.* -import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache +import com.intellij.psi.PsiManager +import com.intellij.psi.impl.compiled.ClsFileImpl +import org.jetbrains.kotlin.idea.JetLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.TRAIT_IMPL +import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache +import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader +import org.junit.Assert public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() { - private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = { + private fun isFileWithHeader(predicate: (KotlinClassHeader) -> Boolean) : VirtualFile.() -> Boolean = { val header = KotlinBinaryClassCache.getKotlinBinaryClass(this)?.getClassHeader() - header?.syntheticClassKind == kind + header != null && predicate(header) } + private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = + isFileWithHeader { it.syntheticClassKind == kind } + + private fun isClassOfKind(kind: KotlinClass.Kind) : VirtualFile.() -> Boolean = + isFileWithHeader { it.classKind == kind } + protected fun doTestTraitImplClassIsVisibleAsJavaClass() { val project = getProject() doTest("trait impl", isSyntheticClassOfKind(TRAIT_IMPL)) { @@ -54,6 +61,9 @@ public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightF } } + protected fun doTestNoPsiFilesAreBuiltForLocalClass(kind: KotlinClass.Kind): Unit = + doTestNoPsiFilesAreBuiltFor(kind.toString(), isClassOfKind(kind)) + protected fun doTestNoPsiFilesAreBuiltForSyntheticClass(kind: KotlinSyntheticClass.Kind): Unit = doTestNoPsiFilesAreBuiltFor(kind.toString(), isSyntheticClassOfKind(kind)) diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/InternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/InternalCompiledClassesTest.kt index 562c3c7b56d..db8fddd36ce 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/InternalCompiledClassesTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/InternalCompiledClassesTest.kt @@ -16,10 +16,12 @@ package org.jetbrains.kotlin.idea.decompiler +import com.intellij.psi.ClassFileViewProvider import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.kotlin.idea.JdkAndMockLibraryProjectDescriptor import org.jetbrains.kotlin.idea.PluginTestCaseBase -import com.intellij.psi.ClassFileViewProvider +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.ANONYMOUS_OBJECT +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.LOCAL_CLASS import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.* public class InternalCompiledClassesTest : AbstractInternalCompiledClassesTest() { @@ -37,6 +39,10 @@ public class InternalCompiledClassesTest : AbstractInternalCompiledClassesTest() fun testAnonymousFunctionIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(ANONYMOUS_FUNCTION) + fun testLocalClassIsInvisible() = doTestNoPsiFilesAreBuiltForLocalClass(LOCAL_CLASS) + + fun testAnonymousObjectIsInvisible() = doTestNoPsiFilesAreBuiltForLocalClass(ANONYMOUS_OBJECT) + fun testInnerClassIsInvisible() = doTestNoPsiFilesAreBuiltFor("inner or nested class") { ClassFileViewProvider.isInnerClass(this) }