KotlinJvmBinaryClass now has a getClassHeader() method
This commit is contained in:
@@ -19,8 +19,8 @@ package org.jetbrains.jet.cli.jvm.compiler;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.*;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClassFinder;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
public class CliVirtualFileFinder extends VirtualFileKotlinClassFinder implements VirtualFileFinder {
|
||||
@@ -70,7 +70,7 @@ public class CliVirtualFileFinder extends VirtualFileKotlinClassFinder implement
|
||||
return null;
|
||||
}
|
||||
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
|
||||
if (KotlinClassHeader.read(createKotlinClass(vFile)) != null) {
|
||||
if (createKotlinClass(vFile).getClassHeader() != null) {
|
||||
return vFile;
|
||||
}
|
||||
}
|
||||
|
||||
+47
-16
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
||||
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import jet.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.ClassReader;
|
||||
@@ -24,7 +26,11 @@ import org.jetbrains.asm4.ClassVisitor;
|
||||
import org.jetbrains.asm4.FieldVisitor;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
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.ExceptionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -34,10 +40,27 @@ import static org.jetbrains.asm4.Opcodes.ASM4;
|
||||
|
||||
public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
||||
private final VirtualFile file;
|
||||
private JvmClassName className;
|
||||
private final NotNullLazyValue<JvmClassName> className;
|
||||
private final NullableLazyValue<KotlinClassHeader> classHeader;
|
||||
|
||||
public VirtualFileKotlinClass(@NotNull VirtualFile file) {
|
||||
public VirtualFileKotlinClass(@NotNull StorageManager storageManager, @NotNull VirtualFile file) {
|
||||
this.file = file;
|
||||
this.className = storageManager.createLazyValue(
|
||||
new Function0<JvmClassName>() {
|
||||
@Override
|
||||
public JvmClassName invoke() {
|
||||
return computeClassName();
|
||||
}
|
||||
}
|
||||
);
|
||||
this.classHeader = storageManager.createNullableLazyValue(
|
||||
new Function0<KotlinClassHeader>() {
|
||||
@Override
|
||||
public KotlinClassHeader invoke() {
|
||||
return KotlinClassHeader.read(VirtualFileKotlinClass.this);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -45,24 +68,32 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
||||
return file;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JvmClassName computeClassName() {
|
||||
final Ref<JvmClassName> classNameRef = Ref.create();
|
||||
try {
|
||||
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 (IOException e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
}
|
||||
return classNameRef.get();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JvmClassName getClassName() {
|
||||
if (className == null) {
|
||||
try {
|
||||
new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM4) {
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
className = JvmClassName.byInternalName(name);
|
||||
}
|
||||
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
return className.invoke();
|
||||
}
|
||||
|
||||
return className;
|
||||
@Override
|
||||
public KotlinClassHeader getClassHeader() {
|
||||
return classHeader.invoke();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ import com.intellij.util.containers.SLRUCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
||||
|
||||
public abstract class VirtualFileKotlinClassFinder implements VirtualFileFinder {
|
||||
|
||||
@@ -29,7 +30,8 @@ public abstract class VirtualFileKotlinClassFinder implements VirtualFileFinder
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinJvmBinaryClass createValue(VirtualFile virtualFile) {
|
||||
return new VirtualFileKotlinClass(virtualFile);
|
||||
// Operations under this lock are not supposed to involve other locks
|
||||
return new VirtualFileKotlinClass(new LockBasedStorageManager(), virtualFile);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ public final class DeserializedDescriptorResolver {
|
||||
|
||||
@Nullable
|
||||
private String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass, @NotNull SerializedDataHeader.Kind expectedKind) {
|
||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
||||
if (header instanceof SerializedDataHeader) {
|
||||
SerializedDataHeader serializedDataHeader = (SerializedDataHeader) header;
|
||||
if (serializedDataHeader.getKind() != expectedKind) return null;
|
||||
|
||||
+4
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.kotlin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public interface KotlinJvmBinaryClass {
|
||||
@@ -29,6 +30,9 @@ public interface KotlinJvmBinaryClass {
|
||||
|
||||
void loadMemberAnnotations(@NotNull MemberVisitor visitor);
|
||||
|
||||
@Nullable
|
||||
KotlinClassHeader getClassHeader();
|
||||
|
||||
interface MemberVisitor {
|
||||
// TODO: abstract signatures for methods and fields instead of ASM 'desc' strings?
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
@@ -120,7 +119,7 @@ public class JetFromJavaDescriptorHelper {
|
||||
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
||||
if (virtualFile != null) {
|
||||
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(psiClass.getProject()).createKotlinClass(virtualFile);
|
||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
||||
if (header instanceof SerializedDataHeader) {
|
||||
return ((SerializedDataHeader) header).getAnnotationData();
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public final class DecompiledDataFactory {
|
||||
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(project).createKotlinClass(classFile);
|
||||
this.classFqName = kotlinClass.getClassName().getFqNameForClassNameWithoutDollars();
|
||||
|
||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
||||
assert header instanceof SerializedDataHeader : "Decompiled data factory shouldn't be called on an unsupported file: " + classFile;
|
||||
this.classFileHeader = (SerializedDataHeader) header;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
||||
|
||||
public final class DecompiledUtils {
|
||||
@@ -33,7 +32,7 @@ public final class DecompiledUtils {
|
||||
}
|
||||
//TODO: check index
|
||||
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(project).createKotlinClass(file);
|
||||
return KotlinClassHeader.read(kotlinClass) instanceof SerializedDataHeader;
|
||||
return kotlinClass.getClassHeader() instanceof SerializedDataHeader;
|
||||
}
|
||||
|
||||
private DecompiledUtils() {
|
||||
|
||||
+3
-3
@@ -27,8 +27,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.header.PackageFragmentClassHeader;
|
||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
||||
|
||||
/**
|
||||
* This class is needed to build an empty PSI stub for compiled package fragment classes. This results in these classes not showing up
|
||||
@@ -46,8 +46,8 @@ public class EmptyPackageFragmentClsStubBuilderFactory extends ClsStubBuilderFac
|
||||
public boolean canBeProcessed(VirtualFile file, byte[] bytes) {
|
||||
if (file.getName().contains(PackageClassUtils.PACKAGE_CLASS_NAME_SUFFIX + "-") &&
|
||||
StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) {
|
||||
KotlinJvmBinaryClass kotlinClass = new VirtualFileKotlinClass(file);
|
||||
return KotlinClassHeader.read(kotlinClass) instanceof PackageFragmentClassHeader;
|
||||
KotlinJvmBinaryClass kotlinClass = new VirtualFileKotlinClass(LockBasedStorageManager.NO_LOCKS, file);
|
||||
return kotlinClass.getClassHeader() instanceof PackageFragmentClassHeader;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension<FqName> {
|
||||
try {
|
||||
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(inputData.getProject())
|
||||
.createKotlinClass(inputData.getFile());
|
||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||
KotlinClassHeader header = kotlinClass.getClassHeader();
|
||||
if (header != null && !(header instanceof IncompatibleAnnotationHeader)) {
|
||||
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user