From 0cfac5f9c73aeea4fc6366420d5cf1b2443a1fb0 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 3 Mar 2014 21:35:02 +0400 Subject: [PATCH] Decompiler: show java file with a comment when kotlin file has incompatible abi version Introduce JetDecompilerForWrongAbiVersion --- idea/src/META-INF/plugin.xml | 1 + .../plugin/libraries/DecompiledTextFactory.kt | 1 - .../jet/plugin/libraries/DecompiledUtils.kt | 13 ++++- .../JetDecompilerForWrongAbiVersion.kt | 29 ++++++++++ .../DecompiledTextForWrongAbiVersionTest.kt | 56 +++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/libraries/JetDecompilerForWrongAbiVersion.kt create mode 100644 idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextForWrongAbiVersionTest.kt diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index ec1f920c6f3..98867f22613 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -330,6 +330,7 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledTextFactory.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledTextFactory.kt index 9caca5b69db..fe3a80a7625 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledTextFactory.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledTextFactory.kt @@ -48,7 +48,6 @@ public fun buildDecompiledText( buildDecompiledText(packageFqName, listOf(resolver.resolveClass(classFqName)).filterNotNull()) } else { - // TODO: support other header kinds: for trait-impl show the trait, for package fragment - the whole package throw UnsupportedOperationException("Unknown header kind: " + kind) } } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt index 426f7538cf8..8380f6fa673 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt @@ -43,10 +43,21 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean { if (isAnonymousFunction(file)) { return true } + if (isKotlinCompiledFileWithIncompatibleAbiVersion(file)) { + return false + } val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() return header != null && header.getKind() != KotlinClassHeader.Kind.TRAIT_IMPL } +public fun isKotlinCompiledFileWithIncompatibleAbiVersion(file: VirtualFile): Boolean { + if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) { + return false + } + val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() + return header?.getKind() == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION +} + public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { if (!isKotlinCompiledFile(file)) { return false @@ -58,5 +69,5 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { return true } val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() - return header != null && header.getKind() == KotlinClassHeader.Kind.PACKAGE_PART + return header?.getKind() == KotlinClassHeader.Kind.PACKAGE_PART } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompilerForWrongAbiVersion.kt b/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompilerForWrongAbiVersion.kt new file mode 100644 index 00000000000..d66366784b4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetDecompilerForWrongAbiVersion.kt @@ -0,0 +1,29 @@ +/* + * 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.libraries + +import com.intellij.psi.compiled.ClassFileDecompilers +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.impl.compiled.ClsFileImpl + +public class JetDecompilerForWrongAbiVersion : ClassFileDecompilers.Light() { + override fun accepts(file: VirtualFile) = isKotlinCompiledFileWithIncompatibleAbiVersion(file) + + override fun getText(file: VirtualFile) = "$INCOMPATIBLE_ABI_VERSION_COMMENT\n${ClsFileImpl.decompile(file)}" +} + +val INCOMPATIBLE_ABI_VERSION_COMMENT = " // This Kotlin file has an incompatible ABI version and is displayed as Java class" \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextForWrongAbiVersionTest.kt b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextForWrongAbiVersionTest.kt new file mode 100644 index 00000000000..4eeabb0cd71 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/DecompiledTextForWrongAbiVersionTest.kt @@ -0,0 +1,56 @@ +/* + * 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.libraries + +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase +import com.intellij.testFramework.LightProjectDescriptor +import org.jetbrains.jet.JetTestCaseBuilder +import com.intellij.psi.PsiManager +import junit.framework.Assert +import com.intellij.psi.PsiCompiledFile +import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor +import java.io.File +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiJavaFile +import com.intellij.psi.impl.compiled.ClsFileImpl + +public class DecompiledTextForWrongAbiVersionTest : JetLightCodeInsightFixtureTestCase() { + + override fun getProjectDescriptor(): LightProjectDescriptor { + return JetJdkAndLibraryProjectDescriptor(File(JetTestCaseBuilder.getTestDataPathBase() + "/cli/jvm/wrongAbiVersionLib")) + } + + fun testClassWithWrongAbiVersion() { + val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!) + checkFileWithWrongAbiVersion(root!!.findChild("ClassWithWrongAbiVersion.class")!!) + } + + fun testPackageFacadeWithWrongAbiVersion() { + val root = NavigateToDecompiledLibraryTest.findTestLibraryRoot(myModule!!) + checkFileWithWrongAbiVersion(root!!.findChild("wrong")!!.findChild("WrongPackage.class")!!) + } + + private fun checkFileWithWrongAbiVersion(file: VirtualFile) { + val psiFile = PsiManager.getInstance(getProject()!!).findFile(file) + Assert.assertTrue(psiFile is ClsFileImpl) + val decompiledPsiFile = (psiFile as PsiCompiledFile).getDecompiledPsiFile() + Assert.assertTrue(decompiledPsiFile is PsiJavaFile) + val decompiledText = decompiledPsiFile!!.getText()!! + Assert.assertTrue(decompiledText.contains(INCOMPATIBLE_ABI_VERSION_COMMENT)) + Assert.assertTrue((decompiledPsiFile as PsiJavaFile).getClasses().size == 1) + } +} \ No newline at end of file