diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt index da627c96963..fb4dd548cfb 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt @@ -20,30 +20,13 @@ import com.intellij.openapi.fileTypes.StdFileTypes import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader -import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind import com.intellij.psi.ClassFileViewProvider import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass - -//TODO: this should be done via generic mechanism (special header kind) -//TODO: should also check for local classes and functions -public fun isAnonymousFunction(file: VirtualFile): Boolean { - val name = file.getNameWithoutExtension() - val index = name.lastIndexOf('$', name.length()) - if (index > 0 && index < name.length() - 1) { - val nameAfterBucks = name.substring(index + 1, name.size) - return nameAfterBucks.isNotEmpty() && nameAfterBucks[0].isDigit() - } - return false -} - public fun isKotlinCompiledFile(file: VirtualFile): Boolean { - if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) { + if (file.getExtension() != StdFileTypes.CLASS.getDefaultExtension()) { return false } - if (isAnonymousFunction(file)) { - return true - } if (isKotlinCompiledFileWithIncompatibleAbiVersion(file)) { return false } @@ -52,7 +35,7 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean { } public fun isKotlinCompiledFileWithIncompatibleAbiVersion(file: VirtualFile): Boolean { - if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) { + if (file.getExtension() != StdFileTypes.CLASS.getDefaultExtension()) { return false } val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() @@ -66,9 +49,6 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { if (ClassFileViewProvider.isInnerClass(file)) { return true } - if (isAnonymousFunction(file)) { - return true - } val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() return header?.getKind() == KotlinClassHeader.Kind.SYNTHETIC_CLASS } diff --git a/idea/testData/libraries/internalClasses/InternalClasses.kt b/idea/testData/libraries/internalClasses/InternalClasses.kt index 9836ed66a7d..1b36f173e22 100644 --- a/idea/testData/libraries/internalClasses/InternalClasses.kt +++ b/idea/testData/libraries/internalClasses/InternalClasses.kt @@ -12,12 +12,27 @@ trait TT : T { fun f() { var i = 0 - val myLocalFun = { + val myAnonymousFunction = { ++i } + fun myLocalFunction() { + i++ + } + class MyLocalClass { } + + val myAnonymousObject = object { + } + + + val lambda = { } + val samWrapper = Thread(lambda) + + val samLambda = Thread { } + + val callableReference = Any::toString } class A { diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/InternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/jet/plugin/libraries/InternalCompiledClassesTest.kt index 7a31c753325..03e557ee89d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/InternalCompiledClassesTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/InternalCompiledClassesTest.kt @@ -30,19 +30,32 @@ import com.intellij.psi.impl.compiled.ClsFileImpl import com.intellij.psi.PsiCompiledFile import com.intellij.psi.PsiClass import com.intellij.psi.PsiJavaFile +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader +import org.jetbrains.jet.storage.LockBasedStorageManager +import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass +import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.* +import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache +import com.intellij.openapi.fileTypes.StdFileTypes -//TODO: test for local functions and classes public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() { private val TEST_DATA_PATH = PluginTestCaseBase.getTestDataPathBase() + "/libraries/internalClasses" - fun testPackagePartIsInvisible() = doTestNoPsiFilesAreBuiltFor("package part") { - getNameWithoutExtension().contains(PackageClassUtils.PACKAGE_CLASS_NAME_SUFFIX + "-") - } + fun testPackagePartIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(PACKAGE_PART) - fun testAnonymousFunctionIsInvisible() = doTestNoPsiFilesAreBuiltFor("anonymous function") { - isAnonymousFunction(this) - } + fun testSamWrapperIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(SAM_WRAPPER) + + fun testSamLambdaIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(SAM_LAMBDA) + + fun testCallableReferenceWrapperIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(CALLABLE_REFERENCE_WRAPPER) + + fun testLocalFunctionIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(LOCAL_FUNCTION) + + fun testAnonymousFunctionIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(ANONYMOUS_FUNCTION) + + fun testLocalClassIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(LOCAL_CLASS) + + fun testAnonymousObjectIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(ANONYMOUS_OBJECT) fun testInnerClassIsInvisible() = doTestNoPsiFilesAreBuiltFor("inner or nested class") { ClassFileViewProvider.isInnerClass(this) @@ -50,7 +63,7 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() fun testTraitImplClassIsVisibleAsJavaClass() { val project = getProject()!! - doTest("trait impl", { getNameWithoutExtension().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX) }) { + doTest("trait impl", isSyntheticClassOfKind(TRAIT_IMPL)) { val psiFile = PsiManager.getInstance(project).findFile(this) Assert.assertTrue("Should not be kotlin file", psiFile !is JetClsFile) @@ -70,6 +83,14 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() return JdkAndMockLibraryProjectDescriptor(TEST_DATA_PATH, withSources = false) } + private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = { + val header = KotlinBinaryClassCache.getKotlinBinaryClass(this).getClassHeader() + header?.getSyntheticClassKind() == kind + } + + private fun doTestNoPsiFilesAreBuiltForSyntheticClass(kind: KotlinSyntheticClass.Kind) = + doTestNoPsiFilesAreBuiltFor(kind.toString(), isSyntheticClassOfKind(kind)) + private fun doTestNoPsiFilesAreBuiltFor(fileKind: String, acceptFile: VirtualFile.() -> Boolean) { val project = getProject()!! doTest(fileKind, acceptFile) {