Make single decompiler be responsible for compiled Kotlin files
IDEA caches link between a virtual file and correspondent FileViewProvider. This breaks navigation to decompiled sources for the library that has been just updated because of outdated ABI version. Also IDEA don't allow to change language for decompiled files. #KT-6016 Fixed
This commit is contained in:
+30
-17
@@ -18,30 +18,32 @@ package org.jetbrains.jet.lang.resolve.kotlin;
|
|||||||
|
|
||||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
|
import com.intellij.openapi.application.ApplicationManager;
|
||||||
import com.intellij.openapi.components.ServiceManager;
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
import com.intellij.openapi.util.Ref;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.util.containers.SLRUCache;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public final class KotlinBinaryClassCache implements Disposable {
|
public final class KotlinBinaryClassCache implements Disposable {
|
||||||
|
private static class RequestCache {
|
||||||
|
VirtualFile virtualFile;
|
||||||
|
long modificationStamp;
|
||||||
|
VirtualFileKotlinClass virtualFileKotlinClass;
|
||||||
|
|
||||||
// This cache must be small: we only query the same file a few times in a row (from different places)
|
public VirtualFileKotlinClass cache(VirtualFile file, VirtualFileKotlinClass aClass) {
|
||||||
// It's local to each thread: we don't want a single instance to synchronize access on, because VirtualFileKotlinClass.create involves
|
virtualFile = file;
|
||||||
// reading files from disk and may take some time
|
virtualFileKotlinClass = aClass;
|
||||||
private final ThreadLocal<SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>>> cache =
|
modificationStamp = file.getModificationStamp();
|
||||||
new ThreadLocal<SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>>>() {
|
|
||||||
|
return aClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ThreadLocal<RequestCache> cache =
|
||||||
|
new ThreadLocal<RequestCache>() {
|
||||||
@Override
|
@Override
|
||||||
protected SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>> initialValue() {
|
protected RequestCache initialValue() {
|
||||||
return new SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>>(2, 2) {
|
return new RequestCache();
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public Ref<VirtualFileKotlinClass> createValue(VirtualFile virtualFile) {
|
|
||||||
return Ref.create(VirtualFileKotlinClass.OBJECT$.create(virtualFile));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,7 +52,18 @@ public final class KotlinBinaryClassCache implements Disposable {
|
|||||||
if (file.getFileType() != JavaClassFileType.INSTANCE) return null;
|
if (file.getFileType() != JavaClassFileType.INSTANCE) return null;
|
||||||
|
|
||||||
KotlinBinaryClassCache service = ServiceManager.getService(KotlinBinaryClassCache.class);
|
KotlinBinaryClassCache service = ServiceManager.getService(KotlinBinaryClassCache.class);
|
||||||
return service.cache.get().get(file).get();
|
RequestCache requestCache = service.cache.get();
|
||||||
|
|
||||||
|
if (file.getModificationStamp() == requestCache.modificationStamp && file.equals(requestCache.virtualFile)) {
|
||||||
|
return requestCache.virtualFileKotlinClass;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||||
|
|
||||||
|
//noinspection deprecation
|
||||||
|
VirtualFileKotlinClass aClass = VirtualFileKotlinClass.OBJECT$.create(file);
|
||||||
|
return requestCache.cache(file, aClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils.concurrent.block
|
||||||
|
|
||||||
|
public class LockedClearableLazyValue<T: Any>(val lock: Any, val init: () -> T) {
|
||||||
|
private volatile var value: T? = null
|
||||||
|
|
||||||
|
public fun get(): T {
|
||||||
|
val _v1 = value
|
||||||
|
if (_v1 != null) {
|
||||||
|
return _v1
|
||||||
|
}
|
||||||
|
|
||||||
|
return synchronized(lock) {
|
||||||
|
val _v2 = value
|
||||||
|
// Suppress because of https://youtrack.jetbrains.com/issue/KT-6176
|
||||||
|
[suppress("UNNECESSARY_NOT_NULL_ASSERTION")]
|
||||||
|
if (_v2 != null) {
|
||||||
|
_v2!!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val _v3 = init()
|
||||||
|
this.value = _v3
|
||||||
|
_v3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun drop() {
|
||||||
|
synchronized (lock) {
|
||||||
|
value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticCla
|
|||||||
import com.intellij.ide.highlighter.JavaClassFileType
|
import com.intellij.ide.highlighter.JavaClassFileType
|
||||||
|
|
||||||
public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
|
public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
|
||||||
if (isKotlinCompiledFileWithIncompatibleAbiVersion(file)) {
|
if (file.getExtension() != JavaClassFileType.INSTANCE!!.getDefaultExtension()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,18 +32,18 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
|
|||||||
return header != null && header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL
|
return header != null && header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isKotlinCompiledFileWithIncompatibleAbiVersion(file: VirtualFile): Boolean {
|
public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
|
||||||
if (file.getExtension() != JavaClassFileType.INSTANCE!!.getDefaultExtension()) {
|
if (!isKotlinCompiledFile(file)) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
||||||
return header != null && !header.isCompatibleAbiVersion
|
return header != null && header.isCompatibleAbiVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
|
public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
|
||||||
if (!isKotlinCompiledFile(file)) {
|
if (!isKotlinCompiledFile(file)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClassFileViewProvider.isInnerClass(file)) {
|
if (ClassFileViewProvider.isInnerClass(file)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-13
@@ -24,28 +24,23 @@ import com.intellij.psi.PsiManager
|
|||||||
import com.intellij.psi.SingleRootFileViewProvider
|
import com.intellij.psi.SingleRootFileViewProvider
|
||||||
import org.jetbrains.jet.plugin.JetLanguage
|
import org.jetbrains.jet.plugin.JetLanguage
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
import org.jetbrains.jet.plugin.decompiler.textBuilder.buildDecompiledText
|
|
||||||
|
|
||||||
public class JetClassFileViewProvider(
|
public class JetClassFileViewProvider(
|
||||||
manager: PsiManager,
|
manager: PsiManager,
|
||||||
file: VirtualFile,
|
val file: VirtualFile,
|
||||||
physical: Boolean,
|
physical: Boolean,
|
||||||
val isInternal: Boolean
|
val isInternal: Boolean) : SingleRootFileViewProvider(manager, file, physical, JetLanguage.INSTANCE) {
|
||||||
) : SingleRootFileViewProvider(manager, file, physical, JetLanguage.INSTANCE) {
|
|
||||||
val decompiledText by Delegates.blockingLazy(this) {
|
val jetClsFile by Delegates.blockingLazy(this) {
|
||||||
buildDecompiledText(getVirtualFile())
|
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||||
|
if (!isInternal) JetClsFile(this) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getContents(): CharSequence {
|
override fun getContents(): CharSequence {
|
||||||
return if (isInternal) "" else decompiledText.text
|
return if (!isInternal) jetClsFile!!.getText() else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? {
|
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? = jetClsFile
|
||||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
|
||||||
if (isInternal) return null
|
|
||||||
|
|
||||||
return JetClsFile(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createCopy(copy: VirtualFile): SingleRootFileViewProvider {
|
override fun createCopy(copy: VirtualFile): SingleRootFileViewProvider {
|
||||||
return JetClassFileViewProvider(getManager(), copy, false, isInternal)
|
return JetClassFileViewProvider(getManager(), copy, false, isInternal)
|
||||||
|
|||||||
@@ -22,31 +22,53 @@ import com.intellij.psi.util.PsiTreeUtil
|
|||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration
|
import org.jetbrains.jet.lang.psi.JetDeclaration
|
||||||
import kotlin.properties.Delegates
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.jet.plugin.decompiler.textBuilder.buildDecompiledText
|
||||||
import org.jetbrains.jet.plugin.decompiler.textBuilder.descriptorToKey
|
import org.jetbrains.jet.plugin.decompiler.textBuilder.descriptorToKey
|
||||||
|
import org.jetbrains.jet.utils.concurrent.block.LockedClearableLazyValue
|
||||||
|
|
||||||
public class JetClsFile(val provider: JetClassFileViewProvider) : ClsFileImpl(provider) {
|
public class JetClsFile(val provider: JetClassFileViewProvider) : ClsFileImpl(provider) {
|
||||||
|
private val mirrorLock = Any()
|
||||||
|
|
||||||
private val decompiledFile by Delegates.blockingLazy(this) {
|
private val mirrorFile = LockedClearableLazyValue(mirrorLock) {
|
||||||
JetDummyClassFileViewProvider.createJetFile(provider.getManager(), getVirtualFile(), provider.decompiledText.text)
|
JetDummyClassFileViewProvider.createJetFile(
|
||||||
|
provider.getManager(),
|
||||||
|
getVirtualFile(),
|
||||||
|
decompiledText.get().text)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDecompiledPsiFile() = decompiledFile
|
private val decompiledText = LockedClearableLazyValue(mirrorLock) {
|
||||||
|
buildDecompiledText(getVirtualFile())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMirror(): PsiElement? = mirrorFile.get()
|
||||||
|
|
||||||
public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): JetDeclaration? {
|
public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): JetDeclaration? {
|
||||||
val key = descriptorToKey(descriptor.getOriginal())
|
val key = descriptorToKey(descriptor.getOriginal())
|
||||||
val range = provider.decompiledText.renderedDescriptorsToRange[key]
|
|
||||||
if (range == null) {
|
return synchronized(mirrorLock) {
|
||||||
return null
|
val range = decompiledText.get().renderedDescriptorsToRange[key]
|
||||||
|
if (range != null) {
|
||||||
|
PsiTreeUtil.findElementOfClassAtRange(
|
||||||
|
mirrorFile.get(), range.getStartOffset(), range.getEndOffset(), javaClass<JetDeclaration>())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onContentReload() {
|
||||||
|
super<ClsFileImpl>.onContentReload()
|
||||||
|
|
||||||
|
synchronized (mirrorLock) {
|
||||||
|
decompiledText.drop()
|
||||||
|
mirrorFile.drop()
|
||||||
}
|
}
|
||||||
return PsiTreeUtil.findElementOfClassAtRange(decompiledFile, range.getStartOffset(), range.getEndOffset(), javaClass<JetDeclaration>())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestOnly
|
TestOnly
|
||||||
fun getRenderedDescriptorsToRange(): Map<String, TextRange> {
|
fun getRenderedDescriptorsToRange(): Map<String, TextRange> {
|
||||||
return provider.decompiledText.renderedDescriptorsToRange
|
return decompiledText.get().renderedDescriptorsToRange
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTextLength() = decompiledFile.getTextLength()
|
|
||||||
override fun getText() = decompiledFile.getText()
|
|
||||||
}
|
}
|
||||||
|
|||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 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)}"
|
|
||||||
}
|
|
||||||
|
|
||||||
public val INCOMPATIBLE_ABI_VERSION_COMMENT: String = " // This Kotlin file has an incompatible ABI version and is displayed as Java class"
|
|
||||||
+27
-13
@@ -32,6 +32,19 @@ import org.jetbrains.jet.lang.types.error.MissingDependencyErrorClass
|
|||||||
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
|
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
|
||||||
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers
|
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.jet.lang.types.isFlexible
|
import org.jetbrains.jet.lang.types.isFlexible
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.header.isCompatiblePackageFacadeKind
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.header.isCompatibleClassKind
|
||||||
|
|
||||||
|
private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI"
|
||||||
|
private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI"
|
||||||
|
|
||||||
|
public val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled."
|
||||||
|
public val INCOMPATIBLE_ABI_VERSION_COMMENT: String =
|
||||||
|
"$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
|
||||||
|
"//\n" +
|
||||||
|
"// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" +
|
||||||
|
"// File ABI version is $FILE_ABI_VERSION_MARKER"
|
||||||
|
|
||||||
public fun buildDecompiledText(
|
public fun buildDecompiledText(
|
||||||
classFile: VirtualFile,
|
classFile: VirtualFile,
|
||||||
@@ -41,21 +54,22 @@ public fun buildDecompiledText(
|
|||||||
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||||
val classId = kotlinClass!!.getClassId()
|
val classId = kotlinClass!!.getClassId()
|
||||||
val classHeader = kotlinClass.getClassHeader()
|
val classHeader = kotlinClass.getClassHeader()
|
||||||
val kind = kotlinClass.getClassHeader().kind
|
|
||||||
val packageFqName = classId.getPackageFqName()
|
val packageFqName = classId.getPackageFqName()
|
||||||
|
|
||||||
if (!classHeader.isCompatibleAbiVersion) {
|
return when {
|
||||||
throw UnsupportedOperationException("Illegal operation for incompatibel header")
|
!classHeader.isCompatibleAbiVersion -> {
|
||||||
}
|
DecompiledText(
|
||||||
|
INCOMPATIBLE_ABI_VERSION_COMMENT
|
||||||
return if (kind == KotlinClassHeader.Kind.PACKAGE_FACADE) {
|
.replaceAll(CURRENT_ABI_VERSION_MARKER, JvmAbi.VERSION.toString())
|
||||||
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInPackage(packageFqName)))
|
.replaceAll(FILE_ABI_VERSION_MARKER, classHeader.version.toString()),
|
||||||
}
|
mapOf())
|
||||||
else if (kind == KotlinClassHeader.Kind.CLASS) {
|
}
|
||||||
buildDecompiledText(packageFqName, listOf(resolver.resolveTopLevelClass(classId)).filterNotNull())
|
classHeader.isCompatiblePackageFacadeKind() ->
|
||||||
}
|
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInPackage(packageFqName)))
|
||||||
else {
|
classHeader.isCompatibleClassKind() ->
|
||||||
throw UnsupportedOperationException("Unknown header kind: " + kind)
|
buildDecompiledText(packageFqName, listOf(resolver.resolveTopLevelClass(classId)).filterNotNull())
|
||||||
|
else ->
|
||||||
|
throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -37,7 +37,7 @@ import org.jetbrains.jet.lang.PlatformToKotlinClassMap
|
|||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||||
import org.jetbrains.jet.descriptors.serialization.ClassData
|
import org.jetbrains.jet.descriptors.serialization.ClassData
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.jet.plugin.decompiler.isKotlinCompiledFile
|
import org.jetbrains.jet.plugin.decompiler.isKotlinWithCompatibleAbiVersion
|
||||||
|
|
||||||
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
||||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||||
@@ -81,7 +81,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
|||||||
val segments = DeserializedResolverUtils.kotlinFqNameToJavaFqName(classId.getRelativeClassName()).pathSegments()
|
val segments = DeserializedResolverUtils.kotlinFqNameToJavaFqName(classId.getRelativeClassName()).pathSegments()
|
||||||
val targetName = segments.joinToString("$", postfix = ".class")
|
val targetName = segments.joinToString("$", postfix = ".class")
|
||||||
val virtualFile = packageDirectory.findChild(targetName)
|
val virtualFile = packageDirectory.findChild(targetName)
|
||||||
if (virtualFile != null && isKotlinCompiledFile(virtualFile)) {
|
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
|
||||||
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
|
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -397,7 +397,6 @@
|
|||||||
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetTopLevelObjectShortNameIndex"/>
|
<stubIndex implementation="org.jetbrains.jet.plugin.stubindex.JetTopLevelObjectShortNameIndex"/>
|
||||||
|
|
||||||
<psi.classFileDecompiler implementation="org.jetbrains.jet.plugin.decompiler.JetClassFileDecompiler"/>
|
<psi.classFileDecompiler implementation="org.jetbrains.jet.plugin.decompiler.JetClassFileDecompiler"/>
|
||||||
<psi.classFileDecompiler implementation="org.jetbrains.jet.plugin.decompiler.JetDecompilerForWrongAbiVersion"/>
|
|
||||||
|
|
||||||
<fileBasedIndex implementation="org.jetbrains.jet.plugin.versions.KotlinAbiVersionIndex"/>
|
<fileBasedIndex implementation="org.jetbrains.jet.plugin.versions.KotlinAbiVersionIndex"/>
|
||||||
<fileBasedIndex implementation="org.jetbrains.jet.plugin.vfilefinder.KotlinClassFileIndex"/>
|
<fileBasedIndex implementation="org.jetbrains.jet.plugin.vfilefinder.KotlinClassFileIndex"/>
|
||||||
|
|||||||
+3
-5
@@ -25,10 +25,9 @@ import com.intellij.psi.PsiCompiledFile
|
|||||||
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor
|
import org.jetbrains.jet.plugin.JetJdkAndLibraryProjectDescriptor
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaFile
|
|
||||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||||
import org.jetbrains.jet.plugin.decompiler.navigation.NavigateToDecompiledLibraryTest
|
import org.jetbrains.jet.plugin.decompiler.navigation.NavigateToDecompiledLibraryTest
|
||||||
import org.jetbrains.jet.plugin.decompiler.INCOMPATIBLE_ABI_VERSION_COMMENT
|
import org.jetbrains.jet.lang.psi.JetFile
|
||||||
|
|
||||||
public class DecompiledTextForWrongAbiVersionTest : JetLightCodeInsightFixtureTestCase() {
|
public class DecompiledTextForWrongAbiVersionTest : JetLightCodeInsightFixtureTestCase() {
|
||||||
|
|
||||||
@@ -50,9 +49,8 @@ public class DecompiledTextForWrongAbiVersionTest : JetLightCodeInsightFixtureTe
|
|||||||
val psiFile = PsiManager.getInstance(getProject()!!).findFile(file)
|
val psiFile = PsiManager.getInstance(getProject()!!).findFile(file)
|
||||||
Assert.assertTrue(psiFile is ClsFileImpl)
|
Assert.assertTrue(psiFile is ClsFileImpl)
|
||||||
val decompiledPsiFile = (psiFile as PsiCompiledFile).getDecompiledPsiFile()
|
val decompiledPsiFile = (psiFile as PsiCompiledFile).getDecompiledPsiFile()
|
||||||
Assert.assertTrue(decompiledPsiFile is PsiJavaFile)
|
Assert.assertTrue(decompiledPsiFile is JetFile)
|
||||||
val decompiledText = decompiledPsiFile!!.getText()!!
|
val decompiledText = decompiledPsiFile!!.getText()!!
|
||||||
Assert.assertTrue(decompiledText.contains(INCOMPATIBLE_ABI_VERSION_COMMENT))
|
Assert.assertTrue(decompiledText.contains(INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT))
|
||||||
Assert.assertTrue((decompiledPsiFile as PsiJavaFile).getClasses().size == 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user