Decompiler: show java file with a comment when kotlin file has incompatible abi version

Introduce JetDecompilerForWrongAbiVersion
This commit is contained in:
Pavel V. Talanov
2014-03-03 21:35:02 +04:00
parent 825dacfd13
commit 0cfac5f9c7
5 changed files with 98 additions and 2 deletions
+1
View File
@@ -330,6 +330,7 @@
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetTopLevelShortObjectNameIndex"/>
<psi.classFileDecompiler implementation="org.jetbrains.jet.plugin.libraries.JetClassFileDecompiler"/>
<psi.classFileDecompiler implementation="org.jetbrains.jet.plugin.libraries.JetDecompilerForWrongAbiVersion"/>
<fileBasedIndex implementation="org.jetbrains.jet.plugin.versions.KotlinAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.jet.plugin.vfilefinder.KotlinClassFileIndex"/>
@@ -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)
}
}
@@ -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
}
@@ -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"
@@ -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)
}
}