Refactor KotlinJvmBinaryClass, VirtualFileKotlinClass, etc.
VirtualFileKotlinClass now reads its header and name on creation. This is not lazy enough and may be slower in some circumstances, but has the following advantage: if anything is wrong in the header, a VirtualFileKotlinClass instance will not be created at all, making it nearly impossible for the client code to operate on invalid data causing all kinds of exceptions
This commit is contained in:
@@ -37,23 +37,15 @@ public class CliVirtualFileFinder extends VirtualFileKotlinClassFinder implement
|
|||||||
@Override
|
@Override
|
||||||
public VirtualFile findVirtualFileWithHeader(@NotNull FqName className) {
|
public VirtualFile findVirtualFileWithHeader(@NotNull FqName className) {
|
||||||
for (VirtualFile root : classPath) {
|
for (VirtualFile root : classPath) {
|
||||||
VirtualFile fileInRoot = findKotlinFile(className, root);
|
VirtualFile fileInRoot = findFileInRoot(className.asString(), root, '.');
|
||||||
if (fileInRoot != null) {
|
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
|
||||||
|
if (fileInRoot != null && KotlinBinaryClassCache.getKotlinBinaryClass(fileInRoot) != null) {
|
||||||
return fileInRoot;
|
return fileInRoot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VirtualFile findKotlinFile(@NotNull FqName className, @NotNull VirtualFile root) {
|
|
||||||
VirtualFile vFile = findFileInRoot(className.asString(), root, '.');
|
|
||||||
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
|
|
||||||
if (vFile != null && KotlinBinaryClassCache.getKotlinBinaryClass(vFile).getClassHeader() != null) {
|
|
||||||
return vFile;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VirtualFile findVirtualFile(@NotNull String internalName) {
|
public VirtualFile findVirtualFile(@NotNull String internalName) {
|
||||||
for (VirtualFile root : classPath) {
|
for (VirtualFile root : classPath) {
|
||||||
|
|||||||
+7
-7
@@ -17,29 +17,29 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin;
|
||||||
|
|
||||||
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 com.intellij.util.containers.SLRUCache;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public final class KotlinBinaryClassCache {
|
public final class KotlinBinaryClassCache {
|
||||||
|
|
||||||
// This cache must be small: we only query the same file a few times in a row (from different places)
|
// This cache must be small: we only query the same file a few times in a row (from different places)
|
||||||
// Since it is on application level we should be careful about this cache. Consider profiling multiple projects indexing simultaneously.
|
// Since it is on application level we should be careful about this cache. Consider profiling multiple projects indexing simultaneously.
|
||||||
private final SLRUCache<VirtualFile, KotlinJvmBinaryClass> cache = new SLRUCache<VirtualFile, KotlinJvmBinaryClass>(2, 2) {
|
private final SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>> cache = new SLRUCache<VirtualFile, Ref<VirtualFileKotlinClass>>(2, 2) {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public KotlinJvmBinaryClass createValue(VirtualFile virtualFile) {
|
public Ref<VirtualFileKotlinClass> createValue(VirtualFile virtualFile) {
|
||||||
// Operations under this lock are not supposed to involve other locks
|
return Ref.create(VirtualFileKotlinClass.create(virtualFile));
|
||||||
return new VirtualFileKotlinClass(new LockBasedStorageManager(), virtualFile);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
public static KotlinJvmBinaryClass getKotlinBinaryClass(@NotNull VirtualFile file) {
|
public static KotlinJvmBinaryClass getKotlinBinaryClass(@NotNull VirtualFile file) {
|
||||||
KotlinBinaryClassCache service = ServiceManager.getService(KotlinBinaryClassCache.class);
|
KotlinBinaryClassCache service = ServiceManager.getService(KotlinBinaryClassCache.class);
|
||||||
synchronized (service.cache) {
|
synchronized (service.cache) {
|
||||||
return service.cache.get(file);
|
return service.cache.get(file).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-53
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.kotlin;
|
|||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import kotlin.Function0;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.asm4.ClassReader;
|
import org.jetbrains.asm4.ClassReader;
|
||||||
@@ -30,9 +29,6 @@ import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
|||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.storage.NotNullLazyValue;
|
|
||||||
import org.jetbrains.jet.storage.NullableLazyValue;
|
|
||||||
import org.jetbrains.jet.storage.StorageManager;
|
|
||||||
import org.jetbrains.jet.utils.UtilsPackage;
|
import org.jetbrains.jet.utils.UtilsPackage;
|
||||||
|
|
||||||
import static org.jetbrains.asm4.ClassReader.*;
|
import static org.jetbrains.asm4.ClassReader.*;
|
||||||
@@ -42,27 +38,49 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
private final static Logger LOG = Logger.getInstance(VirtualFileKotlinClass.class);
|
private final static Logger LOG = Logger.getInstance(VirtualFileKotlinClass.class);
|
||||||
|
|
||||||
private final VirtualFile file;
|
private final VirtualFile file;
|
||||||
private final NotNullLazyValue<JvmClassName> className;
|
private final JvmClassName className;
|
||||||
private final NullableLazyValue<KotlinClassHeader> classHeader;
|
private final KotlinClassHeader classHeader;
|
||||||
|
|
||||||
public VirtualFileKotlinClass(@NotNull StorageManager storageManager, @NotNull VirtualFile file) {
|
private VirtualFileKotlinClass(@NotNull VirtualFile file, @NotNull JvmClassName className, @NotNull KotlinClassHeader classHeader) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.className = storageManager.createLazyValue(
|
this.className = className;
|
||||||
new Function0<JvmClassName>() {
|
this.classHeader = classHeader;
|
||||||
@Override
|
}
|
||||||
public JvmClassName invoke() {
|
|
||||||
return computeClassName();
|
@Nullable
|
||||||
}
|
/* package */ static VirtualFileKotlinClass create(@NotNull VirtualFile file) {
|
||||||
|
try {
|
||||||
|
final ReadKotlinClassHeaderAnnotationVisitor readHeaderVisitor = new ReadKotlinClassHeaderAnnotationVisitor();
|
||||||
|
final Ref<JvmClassName> classNameRef = Ref.create();
|
||||||
|
new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM4) {
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
classNameRef.set(JvmClassName.byInternalName(name));
|
||||||
}
|
}
|
||||||
);
|
|
||||||
this.classHeader = storageManager.createNullableLazyValue(
|
@Override
|
||||||
new Function0<KotlinClassHeader>() {
|
public org.jetbrains.asm4.AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||||
@Override
|
return convertAnnotationVisitor(readHeaderVisitor, desc);
|
||||||
public KotlinClassHeader invoke() {
|
|
||||||
return ReadKotlinClassHeaderAnnotationVisitor.read(VirtualFileKotlinClass.this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
readHeaderVisitor.visitEnd();
|
||||||
|
}
|
||||||
|
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||||
|
|
||||||
|
JvmClassName className = classNameRef.get();
|
||||||
|
if (className == null) return null;
|
||||||
|
|
||||||
|
KotlinClassHeader header = readHeaderVisitor.createHeader();
|
||||||
|
if (header == null) return null;
|
||||||
|
|
||||||
|
return new VirtualFileKotlinClass(file, className, header);
|
||||||
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
|
LOG.warn(renderFileReadingErrorMessage(file), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -71,32 +89,15 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JvmClassName computeClassName() {
|
@Override
|
||||||
final Ref<JvmClassName> classNameRef = Ref.create();
|
public JvmClassName getClassName() {
|
||||||
try {
|
return className;
|
||||||
new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM4) {
|
|
||||||
@Override
|
|
||||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
|
||||||
classNameRef.set(JvmClassName.byInternalName(name));
|
|
||||||
}
|
|
||||||
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
|
||||||
}
|
|
||||||
catch (Throwable e) {
|
|
||||||
logFileReadingError(e);
|
|
||||||
throw UtilsPackage.rethrow(e);
|
|
||||||
}
|
|
||||||
return classNameRef.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
|
||||||
public JvmClassName getClassName() {
|
|
||||||
return className.invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KotlinClassHeader getClassHeader() {
|
public KotlinClassHeader getClassHeader() {
|
||||||
return classHeader.invoke();
|
return classHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,7 +116,7 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
logFileReadingError(e);
|
LOG.error(renderFileReadingErrorMessage(file), e);
|
||||||
throw UtilsPackage.rethrow(e);
|
throw UtilsPackage.rethrow(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,7 +201,7 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
logFileReadingError(e);
|
LOG.error(renderFileReadingErrorMessage(file), e);
|
||||||
throw UtilsPackage.rethrow(e);
|
throw UtilsPackage.rethrow(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,6 +212,13 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
return JvmClassName.byInternalName(desc.substring(1, desc.length() - 1));
|
return JvmClassName.byInternalName(desc.substring(1, desc.length() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String renderFileReadingErrorMessage(@NotNull VirtualFile file) {
|
||||||
|
return "Could not read file: " + file.getPath() + "\n"
|
||||||
|
+ "Size in bytes: " + file.getLength() + "\n"
|
||||||
|
+ "File type: " + file.getFileType().getName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return file.hashCode();
|
return file.hashCode();
|
||||||
@@ -225,13 +233,4 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + ": " + file.toString();
|
return getClass().getSimpleName() + ": " + file.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logFileReadingError(@NotNull Throwable e) {
|
|
||||||
LOG.error(
|
|
||||||
"Could not read file: " + file.getPath() + "\n"
|
|
||||||
+ "Size in bytes: " + file.getLength() + "\n"
|
|
||||||
+ "File type: " + file.getFileType().getName(),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -75,8 +75,8 @@ fun LazyJavaResolverContext.findClassInJava(fqName: FqName): JavaClassLookupResu
|
|||||||
}
|
}
|
||||||
|
|
||||||
val kotlinClass = kotlinClassFinder.findKotlinClass(fqName)
|
val kotlinClass = kotlinClassFinder.findKotlinClass(fqName)
|
||||||
val header = kotlinClass?.getClassHeader()
|
if (kotlinClass != null) {
|
||||||
if (kotlinClass != null && header != null) {
|
val header = kotlinClass.getClassHeader()
|
||||||
if (header.kind == KotlinClassHeader.Kind.CLASS) {
|
if (header.kind == KotlinClassHeader.Kind.CLASS) {
|
||||||
val descriptor = packageFragmentProvider.resolveKotlinBinaryClass(kotlinClass)
|
val descriptor = packageFragmentProvider.resolveKotlinBinaryClass(kotlinClass)
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
|
|||||||
-2
@@ -117,8 +117,6 @@ public final class DeserializedDescriptorResolver {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass, @NotNull KotlinClassHeader.Kind expectedKind) {
|
private String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass, @NotNull KotlinClassHeader.Kind expectedKind) {
|
||||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
KotlinClassHeader header = kotlinClass.getClassHeader();
|
||||||
if (header == null) return null;
|
|
||||||
|
|
||||||
if (header.getKind() == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
|
if (header.getKind() == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
|
||||||
errorReporter.reportIncompatibleAbiVersion(kotlinClass, header.getVersion());
|
errorReporter.reportIncompatibleAbiVersion(kotlinClass, header.getVersion());
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ public interface KotlinJvmBinaryClass {
|
|||||||
|
|
||||||
void visitMembers(@NotNull MemberVisitor visitor);
|
void visitMembers(@NotNull MemberVisitor visitor);
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
KotlinClassHeader getClassHeader();
|
KotlinClassHeader getClassHeader();
|
||||||
|
|
||||||
interface MemberVisitor {
|
interface MemberVisitor {
|
||||||
|
|||||||
-11
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
|
import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
@@ -53,16 +52,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
|||||||
private KotlinClassHeader.Kind headerKind = null;
|
private KotlinClassHeader.Kind headerKind = null;
|
||||||
private KotlinSyntheticClass.Kind syntheticClassKind = null;
|
private KotlinSyntheticClass.Kind syntheticClassKind = null;
|
||||||
|
|
||||||
private ReadKotlinClassHeaderAnnotationVisitor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static KotlinClassHeader read(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
|
||||||
ReadKotlinClassHeaderAnnotationVisitor visitor = new ReadKotlinClassHeaderAnnotationVisitor();
|
|
||||||
kotlinClass.loadClassAnnotations(visitor);
|
|
||||||
return visitor.createHeader();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public KotlinClassHeader createHeader() {
|
public KotlinClassHeader createHeader() {
|
||||||
if (headerKind == null) {
|
if (headerKind == null) {
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ import org.jetbrains.jet.lang.descriptors.ClassKind;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
|
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
|
|
||||||
@@ -113,9 +111,8 @@ public class JetFromJavaDescriptorHelper {
|
|||||||
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
||||||
if (virtualFile != null) {
|
if (virtualFile != null) {
|
||||||
KotlinJvmBinaryClass kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile);
|
KotlinJvmBinaryClass kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile);
|
||||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
if (kotlinClass != null) {
|
||||||
if (header != null) {
|
return kotlinClass.getClassHeader().getAnnotationData();
|
||||||
return header.getAnnotationData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -35,10 +35,9 @@ public fun buildDecompiledText(
|
|||||||
resolver: ResolverForDecompiler = DeserializerForDecompiler(classFile)
|
resolver: ResolverForDecompiler = DeserializerForDecompiler(classFile)
|
||||||
): DecompiledText {
|
): DecompiledText {
|
||||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||||
val classFqName = kotlinClass.getClassName().getFqNameForClassNameWithoutDollars()
|
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||||
val classFileHeader = kotlinClass.getClassHeader()
|
val classFqName = kotlinClass!!.getClassName().getFqNameForClassNameWithoutDollars()
|
||||||
assert(classFileHeader != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
val kind = kotlinClass.getClassHeader().kind
|
||||||
val kind = classFileHeader!!.kind
|
|
||||||
val packageFqName = classFqName.parent()
|
val packageFqName = classFqName.parent()
|
||||||
|
|
||||||
return if (kind == KotlinClassHeader.Kind.PACKAGE_FACADE) {
|
return if (kind == KotlinClassHeader.Kind.PACKAGE_FACADE) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
|
|||||||
if (isKotlinCompiledFileWithIncompatibleAbiVersion(file)) {
|
if (isKotlinCompiledFileWithIncompatibleAbiVersion(file)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
||||||
return header != null && header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL
|
return header != null && header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ public fun isKotlinCompiledFileWithIncompatibleAbiVersion(file: VirtualFile): Bo
|
|||||||
if (file.getExtension() != StdFileTypes.CLASS.getDefaultExtension()) {
|
if (file.getExtension() != StdFileTypes.CLASS.getDefaultExtension()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
||||||
return header?.kind == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION
|
return header?.kind == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +49,6 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
|
|||||||
if (ClassFileViewProvider.isInnerClass(file)) {
|
if (ClassFileViewProvider.isInnerClass(file)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
||||||
return header?.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS
|
return header?.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ import org.jetbrains.jet.lang.resolve.kotlin.ConstantDescriptorDeserializer
|
|||||||
|
|
||||||
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
|
||||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||||
val classFqName = kotlinClass.getClassName().getFqNameForClassNameWithoutDollars()
|
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||||
|
val classFqName = kotlinClass!!.getClassName().getFqNameForClassNameWithoutDollars()
|
||||||
val packageFqName = classFqName.parent()
|
val packageFqName = classFqName.parent()
|
||||||
return DeserializerForDecompiler(classFile.getParent()!!, packageFqName)
|
return DeserializerForDecompiler(classFile.getParent()!!, packageFqName)
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeBinaryClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor {
|
private fun deserializeBinaryClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor {
|
||||||
val data = kotlinClass.getClassHeader()?.annotationData
|
val data = kotlinClass.getClassHeader().annotationData
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
LOG.error("Annotation data missing for ${kotlinClass.getClassName()}")
|
LOG.error("Annotation data missing for ${kotlinClass.getClassName()}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension<FqName> {
|
|||||||
public Map<FqName, Void> map(FileContent inputData) {
|
public Map<FqName, Void> map(FileContent inputData) {
|
||||||
try {
|
try {
|
||||||
KotlinJvmBinaryClass kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(inputData.getFile());
|
KotlinJvmBinaryClass kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(inputData.getFile());
|
||||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
if (kotlinClass != null && kotlinClass.getClassHeader().getKind() != KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
|
||||||
if (header != null && header.getKind() != KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
|
|
||||||
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
|
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class InternalCompiledClassesTest : JetLightCodeInsightFixtureTestCase()
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = {
|
private fun isSyntheticClassOfKind(kind: KotlinSyntheticClass.Kind) : VirtualFile.() -> Boolean = {
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(this).getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(this)?.getClassHeader()
|
||||||
header?.syntheticClassKind == kind
|
header?.syntheticClassKind == kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user