ReadDataFromAnnotationVisitor doesn't depend on ASM anymore
This commit is contained in:
+12
-3
@@ -157,9 +157,11 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
||||
|
||||
return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() {
|
||||
@Override
|
||||
public void visit(@NotNull Name name, @Nullable Object value) {
|
||||
CompileTimeConstant<?> argument = JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(value, null);
|
||||
setArgumentValueByName(name, argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name));
|
||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||
if (name != null) {
|
||||
CompileTimeConstant<?> argument = JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(value, null);
|
||||
setArgumentValueByName(name, argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,6 +169,13 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
||||
setArgumentValueByName(name, enumEntryValue(enumClassName, enumEntryName));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitArray(@NotNull Name name) {
|
||||
// TODO: support arrays
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CompileTimeConstant<?> enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) {
|
||||
ClassDescriptor enumClass = javaClassResolver.resolveClass(enumClassName.getFqName(), IGNORE_KOTLIN_SOURCES);
|
||||
|
||||
+5
-2
@@ -51,11 +51,14 @@ public interface KotlinJvmBinaryClass {
|
||||
}
|
||||
|
||||
interface AnnotationArgumentVisitor {
|
||||
// TODO: arrays, annotations, java.lang.Class
|
||||
void visit(@NotNull Name name, @Nullable Object value);
|
||||
// TODO: annotations, java.lang.Class
|
||||
void visit(@Nullable Name name, @Nullable Object value);
|
||||
|
||||
void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName);
|
||||
|
||||
@Nullable
|
||||
AnnotationArgumentVisitor visitArray(@NotNull Name name);
|
||||
|
||||
void visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-14
@@ -18,25 +18,14 @@ package org.jetbrains.jet.lang.resolve.kotlin.header;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.ClassReader;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.jetbrains.asm4.ClassReader.*;
|
||||
|
||||
public abstract class KotlinClassFileHeader {
|
||||
@Nullable
|
||||
public static KotlinClassFileHeader readKotlinHeaderFromClassFile(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
||||
try {
|
||||
ClassReader reader = new ClassReader(kotlinClass.getFile().contentsToByteArray());
|
||||
ReadDataFromAnnotationVisitor visitor = new ReadDataFromAnnotationVisitor();
|
||||
reader.accept(visitor, SKIP_CODE | SKIP_FRAMES | SKIP_DEBUG);
|
||||
return visitor.createHeader(kotlinClass);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ReadDataFromAnnotationVisitor visitor = new ReadDataFromAnnotationVisitor();
|
||||
kotlinClass.loadClassAnnotations(visitor);
|
||||
return visitor.createHeader(kotlinClass);
|
||||
}
|
||||
|
||||
private final int version;
|
||||
|
||||
+82
-37
@@ -19,20 +19,20 @@ package org.jetbrains.jet.lang.resolve.kotlin.header;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.AnnotationVisitor;
|
||||
import org.jetbrains.asm4.ClassVisitor;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
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.Name;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
|
||||
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArgumentVisitor;
|
||||
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationVisitor;
|
||||
|
||||
/* package */ class ReadDataFromAnnotationVisitor extends ClassVisitor {
|
||||
/* package */ class ReadDataFromAnnotationVisitor implements AnnotationVisitor {
|
||||
private static final Logger LOG = Logger.getInstance(ReadDataFromAnnotationVisitor.class);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -51,9 +51,9 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static HeaderType byDescriptor(@NotNull String desc) {
|
||||
private static HeaderType byClassName(@NotNull JvmClassName className) {
|
||||
for (HeaderType headerType : HeaderType.values()) {
|
||||
if (desc.equals(headerType.annotation.getDescriptor())) {
|
||||
if (className.equals(headerType.annotation)) {
|
||||
return headerType;
|
||||
}
|
||||
}
|
||||
@@ -67,10 +67,6 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
|
||||
@Nullable
|
||||
private HeaderType foundType = null;
|
||||
|
||||
public ReadDataFromAnnotationVisitor() {
|
||||
super(Opcodes.ASM4);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KotlinClassFileHeader createHeader(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
||||
if (foundType == null) {
|
||||
@@ -102,9 +98,10 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
|
||||
return new SerializedDataHeader(version, annotationData, kind);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
HeaderType newType = HeaderType.byDescriptor(desc);
|
||||
public AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName annotationClassName) {
|
||||
HeaderType newType = HeaderType.byClassName(annotationClassName);
|
||||
if (newType == null) return null;
|
||||
|
||||
if (foundType != null) {
|
||||
@@ -115,41 +112,51 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
|
||||
foundType = newType;
|
||||
|
||||
if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) {
|
||||
return kotlinClassOrPackageVisitor(desc);
|
||||
return kotlinClassOrPackageVisitor(annotationClassName);
|
||||
}
|
||||
else if (newType == HeaderType.PACKAGE_FRAGMENT) {
|
||||
return kotlinPackageFragmentVisitor(desc);
|
||||
return kotlinPackageFragmentVisitor(annotationClassName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private AnnotationVisitor kotlinClassOrPackageVisitor(final String desc) {
|
||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||
private AnnotationArgumentVisitor kotlinClassOrPackageVisitor(@NotNull final JvmClassName annotationClassName) {
|
||||
return new AnnotationArgumentVisitor() {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
visitIntValueForSupportedAnnotation(name, value, desc);
|
||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||
visitIntValueForSupportedAnnotation(name, value, annotationClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
if (name.equals(JvmAnnotationNames.DATA_FIELD_NAME)) {
|
||||
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
|
||||
unexpectedArgument(name, annotationClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
|
||||
if (name.asString().equals(JvmAnnotationNames.DATA_FIELD_NAME)) {
|
||||
return stringArrayVisitor();
|
||||
}
|
||||
else if (isAbiVersionCompatible(version)) {
|
||||
throw new IllegalStateException("Unexpected array argument " + name + " for annotation " + desc);
|
||||
throw new IllegalStateException("Unexpected array argument " + name + " for annotation " + annotationClassName);
|
||||
}
|
||||
|
||||
return super.visitArray(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private AnnotationVisitor stringArrayVisitor() {
|
||||
private AnnotationArgumentVisitor stringArrayVisitor() {
|
||||
final List<String> strings = new ArrayList<String>(1);
|
||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||
return new AnnotationArgumentVisitor() {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||
if (!(value instanceof String)) {
|
||||
throw new IllegalStateException("Unexpected argument value: " + value);
|
||||
}
|
||||
@@ -157,31 +164,69 @@ import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCom
|
||||
strings.add((String) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
|
||||
unexpectedArgument(name, annotationClassName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
|
||||
return unexpectedArgument(name, annotationClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
annotationData = strings.toArray(new String[strings.size()]);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private AnnotationVisitor kotlinPackageFragmentVisitor(final String desc) {
|
||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
visitIntValueForSupportedAnnotation(name, value, desc);
|
||||
public void visitEnd() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void visitIntValueForSupportedAnnotation(@NotNull String name, @NotNull Object value, @NotNull String desc) {
|
||||
if (name.equals(JvmAnnotationNames.ABI_VERSION_FIELD_NAME)) {
|
||||
version = (Integer) value;
|
||||
@NotNull
|
||||
private AnnotationArgumentVisitor kotlinPackageFragmentVisitor(@NotNull final JvmClassName annotationClassName) {
|
||||
return new AnnotationArgumentVisitor() {
|
||||
@Override
|
||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||
visitIntValueForSupportedAnnotation(name, value, annotationClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
|
||||
unexpectedArgument(name, annotationClassName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
|
||||
return unexpectedArgument(name, annotationClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void visitIntValueForSupportedAnnotation(@Nullable Name name, @Nullable Object value, @NotNull JvmClassName className) {
|
||||
if (name != null && name.asString().equals(JvmAnnotationNames.ABI_VERSION_FIELD_NAME)) {
|
||||
version = value == null ? AbiVersionUtil.INVALID_VERSION : (Integer) value;
|
||||
}
|
||||
else if (isAbiVersionCompatible(version)) {
|
||||
throw new IllegalStateException("Unexpected argument " + name + " for annotation " + desc);
|
||||
else {
|
||||
unexpectedArgument(name, className);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private AnnotationArgumentVisitor unexpectedArgument(@Nullable Name name, @NotNull JvmClassName annotationClassName) {
|
||||
if (isAbiVersionCompatible(version)) {
|
||||
throw new IllegalStateException("Unexpected argument " + name + " for annotation " + annotationClassName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user