diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda$other$1.class b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda$other$1.class new file mode 100644 index 00000000000..896ff63760d Binary files /dev/null and b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda$other$1.class differ diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda.class b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda.class new file mode 100644 index 00000000000..7ac96fb92a3 Binary files /dev/null and b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda.class differ diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault$$TImpl.class b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault$$TImpl.class new file mode 100644 index 00000000000..8e4640ad252 Binary files /dev/null and b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault$$TImpl.class differ diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault.class b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault.class new file mode 100644 index 00000000000..ac6e941f3b7 Binary files /dev/null and b/compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault.class differ diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/src/ClassWithInnerLambda.kt b/compiler/testData/cli/jvm/wrongAbiVersionLib/src/ClassWithInnerLambda.kt new file mode 100644 index 00000000000..fca1d1ddc4a --- /dev/null +++ b/compiler/testData/cli/jvm/wrongAbiVersionLib/src/ClassWithInnerLambda.kt @@ -0,0 +1,8 @@ +package wrong + +class ClassWithInnerLambda { + fun test(a: () -> Unit) = a + fun other() { + test({}) + } +} \ No newline at end of file diff --git a/compiler/testData/cli/jvm/wrongAbiVersionLib/src/TraitWithDefault.kt b/compiler/testData/cli/jvm/wrongAbiVersionLib/src/TraitWithDefault.kt new file mode 100644 index 00000000000..df593504f3d --- /dev/null +++ b/compiler/testData/cli/jvm/wrongAbiVersionLib/src/TraitWithDefault.kt @@ -0,0 +1,5 @@ +package wrong + +trait TraitWithDefault { + fun foo() = 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/decompiler/AbstractInternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/jet/plugin/decompiler/AbstractInternalCompiledClassesTest.kt new file mode 100644 index 00000000000..848289fe753 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/decompiler/AbstractInternalCompiledClassesTest.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2010-2014 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.jet.plugin.decompiler + + +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase +import com.intellij.testFramework.LightProjectDescriptor +import org.jetbrains.jet.plugin.JdkAndMockLibraryProjectDescriptor +import org.jetbrains.jet.plugin.PluginTestCaseBase +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.jet.lang.resolve.java.JvmAbi +import com.intellij.psi.PsiManager +import org.junit.Assert +import com.intellij.psi.ClassFileViewProvider +import com.intellij.psi.impl.compiled.ClsFileImpl +import com.intellij.psi.PsiCompiledFile +import com.intellij.psi.PsiJavaFile +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 org.jetbrains.jet.plugin.decompiler.navigation.NavigateToDecompiledLibraryTest + +public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() { + private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = { + val header = KotlinBinaryClassCache.getKotlinBinaryClass(this)?.getClassHeader() + header?.syntheticClassKind == kind + } + + protected fun doTestTraitImplClassIsVisibleAsJavaClass() { + val project = getProject()!! + doTest("trait impl", isSyntheticClassOfKind(TRAIT_IMPL)) { + val psiFile = PsiManager.getInstance(project).findFile(this)!! + Assert.assertTrue("Should not be kotlin file", + psiFile !is JetClsFile) + Assert.assertTrue("Should be java file, was ${psiFile.javaClass.getSimpleName()}", + psiFile is ClsFileImpl) + + val decompiledPsiFile = (psiFile as PsiCompiledFile).getDecompiledPsiFile()!! + Assert.assertTrue("Should be java decompiled file, was ${decompiledPsiFile.javaClass.getSimpleName()}", + 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)) + } + } + + protected fun doTestNoPsiFilesAreBuiltForSyntheticClass(kind: KotlinSyntheticClass.Kind): Unit = + doTestNoPsiFilesAreBuiltFor(kind.toString(), isSyntheticClassOfKind(kind)) + + protected fun doTestNoPsiFilesAreBuiltFor(fileKind: String, acceptFile: VirtualFile.() -> Boolean) { + 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()}", + psiFile) + + } + } + + protected fun doTest(fileKind: String, acceptFile: VirtualFile.() -> Boolean, performTest: VirtualFile.() -> Unit) { + val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!)!! + var foundAtLeastOneFile = false + root.checkRecursively { + if (acceptFile()) { + foundAtLeastOneFile = true + performTest() + } + } + Assert.assertTrue("Should find at least one file of kind ($fileKind). This assertion can fail in following scenarios:\n" + + "1. Test data is bad and doesn't cover this case.\n2. ABI has changed and test no longer checks anything.", + foundAtLeastOneFile) + } + + protected fun VirtualFile.checkRecursively(body: VirtualFile.() -> Unit) { + if (!isDirectory()) { + body() + } + else { + for (file in getChildren()!!) { + file.checkRecursively(body) + } + } + } +} + diff --git a/idea/tests/org/jetbrains/jet/plugin/decompiler/InternalCompiledClassesTest.kt b/idea/tests/org/jetbrains/jet/plugin/decompiler/InternalCompiledClassesTest.kt index 47a89c4945e..64ec3f0fb8e 100644 --- a/idea/tests/org/jetbrains/jet/plugin/decompiler/InternalCompiledClassesTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/decompiler/InternalCompiledClassesTest.kt @@ -16,25 +16,13 @@ package org.jetbrains.jet.plugin.decompiler -import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.jet.plugin.JdkAndMockLibraryProjectDescriptor import org.jetbrains.jet.plugin.PluginTestCaseBase -import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.jet.lang.resolve.java.JvmAbi -import com.intellij.psi.PsiManager -import org.junit.Assert import com.intellij.psi.ClassFileViewProvider -import com.intellij.psi.impl.compiled.ClsFileImpl -import com.intellij.psi.PsiCompiledFile -import com.intellij.psi.PsiJavaFile -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 org.jetbrains.jet.plugin.decompiler.navigation.NavigateToDecompiledLibraryTest - -public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() { +public class InternalCompiledClassesTest : AbstractInternalCompiledClassesTest() { private val TEST_DATA_PATH = PluginTestCaseBase.getTestDataPathBase() + "/decompiler/internalClasses" fun testPackagePartIsInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClass(PACKAGE_PART) @@ -57,68 +45,9 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase() ClassFileViewProvider.isInnerClass(this) } - fun testTraitImplClassIsVisibleAsJavaClass() { - val project = getProject()!! - doTest("trait impl", isSyntheticClassOfKind(TRAIT_IMPL)) { - val psiFile = PsiManager.getInstance(project).findFile(this)!! - Assert.assertTrue("Should not be kotlin file", - psiFile !is JetClsFile) - Assert.assertTrue("Should be java file, was ${psiFile.javaClass.getSimpleName()}", - psiFile is ClsFileImpl) - - val decompiledPsiFile = (psiFile as PsiCompiledFile).getDecompiledPsiFile()!! - Assert.assertTrue("Should be java decompiled file, was ${decompiledPsiFile.javaClass.getSimpleName()}", - 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)) - } - } + fun testTraitImplClassIsVisibleAsJavaClass() = doTestTraitImplClassIsVisibleAsJavaClass() override fun getProjectDescriptor(): LightProjectDescriptor { return JdkAndMockLibraryProjectDescriptor(TEST_DATA_PATH, /* withSources = */ false) } - - private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = { - val header = KotlinBinaryClassCache.getKotlinBinaryClass(this)?.getClassHeader() - header?.syntheticClassKind == 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) { - val psiFile = PsiManager.getInstance(project).findFile(this) - Assert.assertNull("PSI files for $fileKind classes should not be build, is was build for: ${this.getPresentableName()}", - psiFile) - - } - } - - private fun doTest(fileKind: String, acceptFile: VirtualFile.() -> Boolean, performTest: VirtualFile.() -> Unit) { - val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!)!! - var foundAtLeastOneFile = false - root.checkRecursively { - if (acceptFile()) { - foundAtLeastOneFile = true - performTest() - } - } - Assert.assertTrue("Should find at least one file of kind ($fileKind). This assertion can fail in following scenarios:\n" + - "1. Test data is bad and doesn't cover this case.\n2. ABI has changed and test no longer checks anything.", - foundAtLeastOneFile) - } - - private fun VirtualFile.checkRecursively(body: VirtualFile.() -> Unit) { - if (!isDirectory()) { - body() - } - else { - for (file in getChildren()!!) { - file.checkRecursively(body) - } - } - } } diff --git a/idea/tests/org/jetbrains/jet/plugin/decompiler/textBuilder/DecompiledTextForWrongAbiVersionTest.kt b/idea/tests/org/jetbrains/jet/plugin/decompiler/textBuilder/DecompiledTextForWrongAbiVersionTest.kt index 6786a3cfd7e..89524836372 100644 --- a/idea/tests/org/jetbrains/jet/plugin/decompiler/textBuilder/DecompiledTextForWrongAbiVersionTest.kt +++ b/idea/tests/org/jetbrains/jet/plugin/decompiler/textBuilder/DecompiledTextForWrongAbiVersionTest.kt @@ -16,7 +16,6 @@ package org.jetbrains.jet.plugin.decompiler.textBuilder -import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase import com.intellij.testFramework.LightProjectDescriptor import org.jetbrains.jet.JetTestCaseBuilder import com.intellij.psi.PsiManager @@ -28,21 +27,43 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.impl.compiled.ClsFileImpl import org.jetbrains.jet.plugin.decompiler.navigation.NavigateToDecompiledLibraryTest import org.jetbrains.jet.lang.psi.JetFile +import com.intellij.openapi.vfs.VfsUtilCore +import org.jetbrains.jet.utils.addIfNotNull +import java.util.LinkedHashSet +import java.util.regex.Pattern +import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART +import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.ANONYMOUS_FUNCTION +import org.jetbrains.jet.plugin.decompiler.AbstractInternalCompiledClassesTest -public class DecompiledTextForWrongAbiVersionTest : JetLightCodeInsightFixtureTestCase() { +public class DecompiledTextForWrongAbiVersionTest : AbstractInternalCompiledClassesTest() { override fun getProjectDescriptor(): LightProjectDescriptor { return JetJdkAndLibraryProjectDescriptor(File(JetTestCaseBuilder.getTestDataPathBase() + "/cli/jvm/wrongAbiVersionLib/bin")) } - fun testClassWithWrongAbiVersion() { - val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!) - checkFileWithWrongAbiVersion(root!!.findChild("ClassWithWrongAbiVersion.class")!!) - } + fun testPackagePartIsInvisibleWrongAbiVersion() = doTestNoPsiFilesAreBuiltForSyntheticClass(PACKAGE_PART) - fun testPackageFacadeWithWrongAbiVersion() { + fun testTraitImplClassIsVisibleAsJavaClassWrongAbiVersion() = doTestTraitImplClassIsVisibleAsJavaClass() + + fun testAnonymousFunctionIsInvisibleWrongAbiVersion() = doTestNoPsiFilesAreBuiltForSyntheticClass(ANONYMOUS_FUNCTION) + + fun testClassWithWrongAbiVersion() = doTest("ClassWithWrongAbiVersion\\.class") + + fun testPackageFacadeWithWrongAbiVersion() = doTest("WrongPackage\\.class") + + fun doTest(namePattern: String) { val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!) - checkFileWithWrongAbiVersion(root!!.findChild("wrong")!!.findChild("WrongPackage.class")!!) + + val pattern = Pattern.compile(namePattern) + val files = LinkedHashSet() + VfsUtilCore.iterateChildrenRecursively( + root, + { virtualFile -> virtualFile.isDirectory() || pattern.matcher(virtualFile.getName()).matches() }, + { virtualFile -> if (!virtualFile.isDirectory()) files.addIfNotNull(virtualFile); true }) + + Assert.assertTrue("Only file should matches the pattern '$namePattern', but found: $files", files.size == 1) + + checkFileWithWrongAbiVersion(files.single()) } private fun checkFileWithWrongAbiVersion(file: VirtualFile) {