From d6ffd22533dbc25b3d437c81e2512d9b31d4860c Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 10 Nov 2014 18:22:03 +0300 Subject: [PATCH] More tests for decompiling classes with wrong abi version --- .../wrong/ClassWithInnerLambda$other$1.class | Bin 0 -> 951 bytes .../bin/wrong/ClassWithInnerLambda.class | Bin 0 -> 1780 bytes .../bin/wrong/TraitWithDefault$$TImpl.class | Bin 0 -> 605 bytes .../bin/wrong/TraitWithDefault.class | Bin 0 -> 693 bytes .../src/ClassWithInnerLambda.kt | 8 ++ .../src/TraitWithDefault.kt | 5 + .../AbstractInternalCompiledClassesTest.kt | 99 ++++++++++++++++++ .../decompiler/InternalCompiledClassesTest.kt | 75 +------------ .../DecompiledTextForWrongAbiVersionTest.kt | 37 +++++-- 9 files changed, 143 insertions(+), 81 deletions(-) create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda$other$1.class create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda.class create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault$$TImpl.class create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/bin/wrong/TraitWithDefault.class create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/src/ClassWithInnerLambda.kt create mode 100644 compiler/testData/cli/jvm/wrongAbiVersionLib/src/TraitWithDefault.kt create mode 100644 idea/tests/org/jetbrains/jet/plugin/decompiler/AbstractInternalCompiledClassesTest.kt 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 0000000000000000000000000000000000000000..896ff63760d50fe7e094a0503e628645a04543e7 GIT binary patch literal 951 zcma)4ZEq4m5Pp_-D77u3wAI>LPX*Lo^(##iLP|nPkEBpcKbhsaDGSG*xm#-dSH2`R z(ZnC%k5Xq(Xrj^7{jf7TJM+vlFWvh#Yx}kNbMCYIrvt;* zb(m=+7?x*VS3qf`7)pPmyffAe)p_RMs2)c2yKfa0rKKB1*BEkqAp0T+sfhRwIt+=i zRA&tKf1_B36hKggy3=t^k2)vaSIrZr(Q9=ahLltn{#Y;+%a!(sUvS&w)bGw+bHcDCC!YYy0Lm4ty?d!)$ zNmF~0;P>;mYw{+s!I0T=X}V-IJT?sUoh)hh8P@*|nZ^T#WV9xEJj4p|X!vJTY@zMD z-0Sl|@_{FM=3-cCOC_A?WFUf>CEJzfitA}WzqzhI4P4Qbk?VnSJwKG{{7C4bPvclS zo+>RTqAx>9XmzE0&CTkC*d?AxFwmZ2)exuMPM}UrT_($8dKF1Bl9}o!-28yGcccR= zrtLG2C-gQR>^)sElr>lC5Z{$7jEs25j*~hev;v1x;)Ix3p zfD5M~!f>fYnohWeAkXC*2wJuW7HJ^N)%w^zKWvk|D>fpjYUf4ULWqStAjH{$%0}01 zg^uSwuyW@pZ%7C;HP1gXPk7k$nd1f~b6qcFLLo5gURdw81?pUlBuu~ShE9i@;dd{% z;~skEV;(kGyUU+2pLIB0SvcU*Cjzoz&=IDt3rf`ueX`}Wf;gloF0EtUIvrqCgT7sa z`(*b@sI3c>T>*1sN2)c{>A!J1Bk`vE0T{)Zk4$N>u(VtOyVompS_dNnj>v%?Fi6>szL zL3)02iC6Nums{Vicw705Ufq8rw;9Tkt}rypk|G-!TM~T5t_r@Q zle{EjMy^g9WmIFuIw^iBSJa$NYCG{!BWF}l!Q%5W(PLJ@K$PXNQL?jRE3s5hZaa=@ zOXv^X%jjjB?5XOqAyr~2#a=YNKsEmK`L->~2NKiub-|a_W%5f-DTIemcvovtrAB@H zgtboD5s!l@5*NjK!}mIyQRoq@i*?$|#Gu*!uVpn@grx*LfR8jtz=%rOFH+Jf-T`${ zvgWl|yTN>iHQRhoEC}N@$K~~Ir^)?3Mcs9dTo!hH;;#R<^Gk*E!g)$V##*~(5|pk; z&^X)ab$iu4a{`A9+ixZVwMd`a=4dr2sJ72(?9lds{u!jJSV z!3wQ6dvwUa?MRE}7u+GhPw7M^>5ai^ByB;dPaC8CA-x(6JQ$~UA|S0bqQnJ7uyvRm z__sW_!sE#vwZ*n literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8e4640ad252ee3b4a9d160973787c34b352b7a10 GIT binary patch literal 605 zcma)3O-~y!5Pg#b0-<~)DJ@X-Qsod3!V=dUDnx~}ux$~n(qrWf4sqhOBd<3o|Ea&A zhyDP56zwdas;#JmCC|(ozj-sZZ|}bU0C0#M!rL3~?6pX|)ZvQ`qYr8*3lln>B+90y z4kB!fd-mDn{NEHY;QLrbmOrK!WTB^Oo=d`Ds6{O zoT|{5rcme7%S;93dxV&eHgvQ+uU%)5(+*XZk9Gv)Ua99ipv3_Kj)zH#XaKTs#S)Y$&J z;twL4sG!FG3lNsEh&tn!jP@B5`%3LwX|c)n#X|-StTKAVd+|O~!)uP4Wx*0tmvd&U b$%iw`PTz&869pRX}mkFbHJV%+`(Ab6zd literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ac6e941f3b76a6181fd9e3a0639acbb46fdbc6d9 GIT binary patch literal 693 zcmaiy+iuf95Qb;G&cP)qIp9)5K{Be+1SG5im5_oeIYvdMftFCEsw#vw$tK;zu`7Gs za?KkdZV(qd01pLB3{?d}uopW!v;X{Sf4g75ef|Of58yV!%6S}x6Xzi2QXNWl@>Gm@ z8mIywLS@R&xD#;N-y2NDkg5!!{-^f-Od%AX3zxngl6|= z>cnCkkd-q%n>#X8A`W@r>}D!|ej2o?e;h@bi;tkI6G`2x-M@b(sqG8n-wiL%Ce0Eb z$i9dZ8HMaS4e}jv#Sz|bny%e&j$_MZstX7}>4vfXy; z0?hx2m%xOTCAbFHOHc&E01Yf6p^|gamx&w%!VSYnaYa;< zJW`iVj|wZ+!h}{D#XQhMf}50?6c@v&X`f*ABi#6~$aFdYuFyh*wQSD8EsAv#FH`NR M4;82$113=W0aog+5dZ)H literal 0 HcmV?d00001 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) {