Delete getFqName() method from KotlinClassFileHeader

It's not related to the header. Add getClassName() method to
KotlinJvmBinaryClass, which reads the internal name of the class
This commit is contained in:
Alexander Udalov
2013-09-25 21:18:41 +04:00
parent a5a80a9ccc
commit 8b63665b20
10 changed files with 50 additions and 53 deletions
@@ -34,6 +34,7 @@ import static org.jetbrains.asm4.Opcodes.ASM4;
public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
private final VirtualFile file; private final VirtualFile file;
private JvmClassName className;
public VirtualFileKotlinClass(@NotNull VirtualFile file) { public VirtualFileKotlinClass(@NotNull VirtualFile file) {
this.file = file; this.file = file;
@@ -45,6 +46,26 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
return file; 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 @Override
public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) { public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) {
try { try {
@@ -116,7 +116,7 @@ public final class DeserializedDescriptorResolver {
} }
if (header != null) { if (header != null) {
errorReporter.reportIncompatibleAbiVersion(header.getFqName(), kotlinClass.getFile(), header.getVersion()); errorReporter.reportIncompatibleAbiVersion(kotlinClass.getClassName().getFqName(), kotlinClass.getFile(), header.getVersion());
} }
return null; return null;
@@ -26,6 +26,9 @@ public interface KotlinJvmBinaryClass {
@NotNull @NotNull
VirtualFile getFile(); VirtualFile getFile();
@NotNull
JvmClassName getClassName();
void loadClassAnnotations(@NotNull AnnotationVisitor visitor); void loadClassAnnotations(@NotNull AnnotationVisitor visitor);
void loadMemberAnnotations(@NotNull MemberVisitor visitor); void loadMemberAnnotations(@NotNull MemberVisitor visitor);
@@ -16,11 +16,8 @@
package org.jetbrains.jet.lang.resolve.kotlin.header; 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 { public class IncompatibleAnnotationHeader extends KotlinClassFileHeader {
protected IncompatibleAnnotationHeader(int version, @NotNull FqName fqName) { protected IncompatibleAnnotationHeader(int version) {
super(version, fqName); super(version);
} }
} }
@@ -20,7 +20,6 @@ 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;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass; import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.io.IOException; import java.io.IOException;
@@ -41,22 +40,12 @@ public abstract class KotlinClassFileHeader {
} }
private final int version; private final int version;
private final FqName fqName;
protected KotlinClassFileHeader(int version, @NotNull FqName fqName) { protected KotlinClassFileHeader(int version) {
this.version = version; this.version = version;
this.fqName = fqName;
} }
public int getVersion() { public int getVersion() {
return version; return version;
} }
/**
* @return FQ name for class header or package class FQ name for package header (e.g. <code>test.TestPackage</code>)
*/
@NotNull
public FqName getFqName() {
return fqName;
}
} }
@@ -16,12 +16,8 @@
package org.jetbrains.jet.lang.resolve.kotlin.header; 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 { public class PackageFragmentClassFileHeader extends KotlinClassFileHeader {
protected PackageFragmentClassFileHeader(int version, @NotNull FqName fqName) { protected PackageFragmentClassFileHeader(int version) {
super(version, fqName); super(version);
} }
} }
@@ -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.JvmAnnotationNames;
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.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -67,8 +66,6 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
private String[] annotationData = null; private String[] annotationData = null;
@Nullable @Nullable
private HeaderType foundType = null; private HeaderType foundType = null;
@Nullable
private FqName fqName = null;
public ReadDataFromAnnotationVisitor() { public ReadDataFromAnnotationVisitor() {
super(Opcodes.ASM4); super(Opcodes.ASM4);
@@ -80,39 +77,29 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
return null; return null;
} }
if (fqName == null) {
LOG.error("Class doesn't have a name in the bytecode: " + kotlinClass);
return null;
}
if (!AbiVersionUtil.isAbiVersionCompatible(version)) { if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
return new IncompatibleAnnotationHeader(version, fqName); return new IncompatibleAnnotationHeader(version);
} }
switch (foundType) { switch (foundType) {
case CLASS: case CLASS:
return serializedDataHeader(SerializedDataHeader.Kind.CLASS, fqName); return serializedDataHeader(SerializedDataHeader.Kind.CLASS, kotlinClass);
case PACKAGE: case PACKAGE:
return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE, fqName); return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE, kotlinClass);
case PACKAGE_FRAGMENT: case PACKAGE_FRAGMENT:
return new PackageFragmentClassFileHeader(version, fqName); return new PackageFragmentClassFileHeader(version);
default: default:
throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType); throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType);
} }
} }
@Nullable @Nullable
private SerializedDataHeader serializedDataHeader(@NotNull SerializedDataHeader.Kind kind, @NotNull FqName fqName) { private SerializedDataHeader serializedDataHeader(@NotNull SerializedDataHeader.Kind kind, @NotNull KotlinJvmBinaryClass kotlinClass) {
if (annotationData == null) { 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 null;
} }
return new SerializedDataHeader(version, annotationData, kind, fqName); return new SerializedDataHeader(version, annotationData, kind);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
fqName = JvmClassName.byInternalName(name).getFqName();
} }
@Override @Override
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.kotlin.header; package org.jetbrains.jet.lang.resolve.kotlin.header;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.name.FqName;
public class SerializedDataHeader extends KotlinClassFileHeader { public class SerializedDataHeader extends KotlinClassFileHeader {
public enum Kind { public enum Kind {
@@ -28,8 +27,8 @@ public class SerializedDataHeader extends KotlinClassFileHeader {
private final String[] data; private final String[] data;
private final Kind kind; private final Kind kind;
protected SerializedDataHeader(int version, @NotNull String[] annotationData, @NotNull Kind kind, @NotNull FqName fqName) { protected SerializedDataHeader(int version, @NotNull String[] annotationData, @NotNull Kind kind) {
super(version, fqName); super(version);
this.data = annotationData; this.data = annotationData;
this.kind = kind; this.kind = kind;
} }
@@ -52,6 +52,8 @@ public final class DecompiledDataFactory {
@NotNull @NotNull
private final SerializedDataHeader classFileHeader; private final SerializedDataHeader classFileHeader;
@NotNull @NotNull
private final FqName classFqName;
@NotNull
private final VirtualFile classFile; private final VirtualFile classFile;
@NotNull @NotNull
private final Project project; private final Project project;
@@ -63,7 +65,10 @@ public final class DecompiledDataFactory {
new InjectorForJavaDescriptorResolver(project, new BindingTraceContext()); new InjectorForJavaDescriptorResolver(project, new BindingTraceContext());
this.javaDescriptorResolver = injector.getJavaDescriptorResolver(); 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; assert header instanceof SerializedDataHeader : "Decompiled data factory shouldn't be called on an unsupported file: " + classFile;
this.classFileHeader = (SerializedDataHeader) header; this.classFileHeader = (SerializedDataHeader) header;
} }
@@ -74,7 +79,7 @@ public final class DecompiledDataFactory {
} }
private JetDecompiledData build() { private JetDecompiledData build() {
FqName packageFqName = classFileHeader.getFqName().parent(); FqName packageFqName = classFqName.parent();
appendDecompiledTextAndPackageName(packageFqName); appendDecompiledTextAndPackageName(packageFqName);
SerializedDataHeader.Kind kind = classFileHeader.getKind(); SerializedDataHeader.Kind kind = classFileHeader.getKind();
if (kind == SerializedDataHeader.Kind.PACKAGE) { if (kind == SerializedDataHeader.Kind.PACKAGE) {
@@ -91,7 +96,7 @@ public final class DecompiledDataFactory {
} }
} }
else if (kind == SerializedDataHeader.Kind.CLASS) { 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) { if (cd != null) {
appendDescriptor(cd, ""); appendDescriptor(cd, "");
} }
@@ -75,10 +75,10 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension<FqName> {
@Override @Override
public Map<FqName, Void> map(FileContent inputData) { public Map<FqName, Void> map(FileContent inputData) {
try { try {
KotlinClassFileHeader header = VirtualFileKotlinClass kotlinClass = new VirtualFileKotlinClass(inputData.getFile());
KotlinClassFileHeader.readKotlinHeaderFromClassFile(new VirtualFileKotlinClass(inputData.getFile())); KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(kotlinClass);
if (header != null && !(header instanceof IncompatibleAnnotationHeader)) { if (header != null && !(header instanceof IncompatibleAnnotationHeader)) {
return Collections.singletonMap(header.getFqName(), null); return Collections.singletonMap(kotlinClass.getClassName().getFqName(), null);
} }
} }
catch (Throwable e) { catch (Throwable e) {