diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java index 91c70499799..0de5fc752a0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java @@ -34,6 +34,7 @@ import static org.jetbrains.asm4.Opcodes.ASM4; public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { private final VirtualFile file; + private JvmClassName className; public VirtualFileKotlinClass(@NotNull VirtualFile file) { this.file = file; @@ -45,6 +46,26 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { return file; } + @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; + } + @Override public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) { try { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java index b7fe47d3de3..a3fa87a5b1e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java @@ -116,7 +116,7 @@ public final class DeserializedDescriptorResolver { } if (header != null) { - errorReporter.reportIncompatibleAbiVersion(header.getFqName(), kotlinClass.getFile(), header.getVersion()); + errorReporter.reportIncompatibleAbiVersion(kotlinClass.getClassName().getFqName(), kotlinClass.getFile(), header.getVersion()); } return null; diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java index a4ba321d8eb..61cfe10b753 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java @@ -26,6 +26,9 @@ public interface KotlinJvmBinaryClass { @NotNull VirtualFile getFile(); + @NotNull + JvmClassName getClassName(); + void loadClassAnnotations(@NotNull AnnotationVisitor visitor); void loadMemberAnnotations(@NotNull MemberVisitor visitor); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/IncompatibleAnnotationHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/IncompatibleAnnotationHeader.java index f870f4d49c0..ffbb056f742 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/IncompatibleAnnotationHeader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/IncompatibleAnnotationHeader.java @@ -16,11 +16,8 @@ package org.jetbrains.jet.lang.resolve.kotlin.header; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.name.FqName; - public class IncompatibleAnnotationHeader extends KotlinClassFileHeader { - protected IncompatibleAnnotationHeader(int version, @NotNull FqName fqName) { - super(version, fqName); + protected IncompatibleAnnotationHeader(int version) { + super(version); } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassFileHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassFileHeader.java index e0149dbd4ed..7167623cdc1 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassFileHeader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/KotlinClassFileHeader.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.ClassReader; import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass; -import org.jetbrains.jet.lang.resolve.name.FqName; import java.io.IOException; @@ -41,22 +40,12 @@ public abstract class KotlinClassFileHeader { } private final int version; - private final FqName fqName; - protected KotlinClassFileHeader(int version, @NotNull FqName fqName) { + protected KotlinClassFileHeader(int version) { this.version = version; - this.fqName = fqName; } public int getVersion() { return version; } - - /** - * @return FQ name for class header or package class FQ name for package header (e.g. test.TestPackage) - */ - @NotNull - public FqName getFqName() { - return fqName; - } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/PackageFragmentClassFileHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/PackageFragmentClassFileHeader.java index 3b5f477df7c..e379eadaec4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/PackageFragmentClassFileHeader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/PackageFragmentClassFileHeader.java @@ -16,12 +16,8 @@ package org.jetbrains.jet.lang.resolve.kotlin.header; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassFileHeader; -import org.jetbrains.jet.lang.resolve.name.FqName; - public class PackageFragmentClassFileHeader extends KotlinClassFileHeader { - protected PackageFragmentClassFileHeader(int version, @NotNull FqName fqName) { - super(version, fqName); + protected PackageFragmentClassFileHeader(int version) { + super(version); } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadDataFromAnnotationVisitor.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadDataFromAnnotationVisitor.java index cf8e7dfcf37..2f26cb25aaa 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadDataFromAnnotationVisitor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/ReadDataFromAnnotationVisitor.java @@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.resolve.java.AbiVersionUtil; import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; 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 java.util.ArrayList; import java.util.List; @@ -67,8 +66,6 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom private String[] annotationData = null; @Nullable private HeaderType foundType = null; - @Nullable - private FqName fqName = null; public ReadDataFromAnnotationVisitor() { super(Opcodes.ASM4); @@ -80,39 +77,29 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom return null; } - if (fqName == null) { - LOG.error("Class doesn't have a name in the bytecode: " + kotlinClass); - return null; - } - if (!AbiVersionUtil.isAbiVersionCompatible(version)) { - return new IncompatibleAnnotationHeader(version, fqName); + return new IncompatibleAnnotationHeader(version); } switch (foundType) { case CLASS: - return serializedDataHeader(SerializedDataHeader.Kind.CLASS, fqName); + return serializedDataHeader(SerializedDataHeader.Kind.CLASS, kotlinClass); case PACKAGE: - return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE, fqName); + return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE, kotlinClass); case PACKAGE_FRAGMENT: - return new PackageFragmentClassFileHeader(version, fqName); + return new PackageFragmentClassFileHeader(version); default: throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType); } } @Nullable - private SerializedDataHeader serializedDataHeader(@NotNull SerializedDataHeader.Kind kind, @NotNull FqName fqName) { + private SerializedDataHeader serializedDataHeader(@NotNull SerializedDataHeader.Kind kind, @NotNull KotlinJvmBinaryClass kotlinClass) { if (annotationData == null) { - LOG.error("Kotlin annotation " + foundType + " is incorrect for class: " + fqName); + LOG.error("Kotlin annotation " + foundType + " is incorrect for class: " + kotlinClass); return null; } - return new SerializedDataHeader(version, annotationData, kind, fqName); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - fqName = JvmClassName.byInternalName(name).getFqName(); + return new SerializedDataHeader(version, annotationData, kind); } @Override diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/SerializedDataHeader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/SerializedDataHeader.java index da6a62f2d59..4aa97605822 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/SerializedDataHeader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/header/SerializedDataHeader.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.resolve.kotlin.header; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.name.FqName; public class SerializedDataHeader extends KotlinClassFileHeader { public enum Kind { @@ -28,8 +27,8 @@ public class SerializedDataHeader extends KotlinClassFileHeader { private final String[] data; private final Kind kind; - protected SerializedDataHeader(int version, @NotNull String[] annotationData, @NotNull Kind kind, @NotNull FqName fqName) { - super(version, fqName); + protected SerializedDataHeader(int version, @NotNull String[] annotationData, @NotNull Kind kind) { + super(version); this.data = annotationData; this.kind = kind; } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java index 544476e03d8..9d2f2a7134f 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledDataFactory.java @@ -52,6 +52,8 @@ public final class DecompiledDataFactory { @NotNull private final SerializedDataHeader classFileHeader; @NotNull + private final FqName classFqName; + @NotNull private final VirtualFile classFile; @NotNull private final Project project; @@ -63,7 +65,10 @@ public final class DecompiledDataFactory { new InjectorForJavaDescriptorResolver(project, new BindingTraceContext()); this.javaDescriptorResolver = injector.getJavaDescriptorResolver(); - KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(new VirtualFileKotlinClass(classFile)); + VirtualFileKotlinClass kotlinClass = new VirtualFileKotlinClass(classFile); + this.classFqName = kotlinClass.getClassName().getFqName(); + + KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(kotlinClass); assert header instanceof SerializedDataHeader : "Decompiled data factory shouldn't be called on an unsupported file: " + classFile; this.classFileHeader = (SerializedDataHeader) header; } @@ -74,7 +79,7 @@ public final class DecompiledDataFactory { } private JetDecompiledData build() { - FqName packageFqName = classFileHeader.getFqName().parent(); + FqName packageFqName = classFqName.parent(); appendDecompiledTextAndPackageName(packageFqName); SerializedDataHeader.Kind kind = classFileHeader.getKind(); if (kind == SerializedDataHeader.Kind.PACKAGE) { @@ -91,7 +96,7 @@ public final class DecompiledDataFactory { } } else if (kind == SerializedDataHeader.Kind.CLASS) { - ClassDescriptor cd = javaDescriptorResolver.resolveClass(classFileHeader.getFqName(), INCLUDE_KOTLIN_SOURCES); + ClassDescriptor cd = javaDescriptorResolver.resolveClass(classFqName, INCLUDE_KOTLIN_SOURCES); if (cd != null) { appendDescriptor(cd, ""); } diff --git a/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java index f26634edfe5..849b9d48195 100644 --- a/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java +++ b/idea/src/org/jetbrains/jet/plugin/vfilefinder/KotlinClassFileIndex.java @@ -75,10 +75,10 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension { @Override public Map map(FileContent inputData) { try { - KotlinClassFileHeader header = - KotlinClassFileHeader.readKotlinHeaderFromClassFile(new VirtualFileKotlinClass(inputData.getFile())); + VirtualFileKotlinClass kotlinClass = new VirtualFileKotlinClass(inputData.getFile()); + KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(kotlinClass); if (header != null && !(header instanceof IncompatibleAnnotationHeader)) { - return Collections.singletonMap(header.getFqName(), null); + return Collections.singletonMap(kotlinClass.getClassName().getFqName(), null); } } catch (Throwable e) {