Support object array annotation arguments in deserialization

This commit is contained in:
Alexander Udalov
2014-07-18 19:38:44 +04:00
parent d5681540ec
commit 540b87a1dc
12 changed files with 140 additions and 28 deletions
@@ -26,14 +26,12 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage;
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
import org.jetbrains.jet.lang.resolve.constants.ErrorValue;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -130,8 +128,7 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
@Override
public void visit(@Nullable Name name, @Nullable Object value) {
if (name != null) {
CompileTimeConstant<?> argument = ConstantsPackage.createCompileTimeConstant(value, true, false, false, null);
setArgumentValueByName(name, argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name));
setArgumentValueByName(name, createConstant(name, value));
}
}
@@ -142,9 +139,29 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
@Nullable
@Override
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitArray(@NotNull Name name) {
// TODO: support arrays
return null;
public AnnotationArrayArgumentVisitor visitArray(@NotNull final Name name) {
return new KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor() {
private final ArrayList<CompileTimeConstant<?>> elements = new ArrayList<CompileTimeConstant<?>>();
@Override
public void visit(@Nullable Object value) {
elements.add(createConstant(name, value));
}
@Override
public void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
elements.add(enumEntryValue(enumClassName, enumEntryName));
}
@Override
public void visitEnd() {
ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass);
if (parameter != null) {
elements.trimToSize();
arguments.put(parameter, new ArrayValue(elements, parameter.getType(), true, false));
}
}
};
}
@NotNull
@@ -167,6 +184,12 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements
));
}
@NotNull
private CompileTimeConstant<?> createConstant(@Nullable Name name, @Nullable Object value) {
CompileTimeConstant<?> argument = ConstantsPackage.createCompileTimeConstant(value, true, false, false, null);
return argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name);
}
private void setArgumentValueByName(@NotNull Name name, @NotNull CompileTimeConstant<?> argumentValue) {
ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass);
if (parameter != null) {
@@ -62,7 +62,15 @@ public interface KotlinJvmBinaryClass {
void visitEnum(@NotNull Name name, @NotNull JvmClassName enumClassName, @NotNull Name enumEntryName);
@Nullable
AnnotationArgumentVisitor visitArray(@NotNull Name name);
AnnotationArrayArgumentVisitor visitArray(@NotNull Name name);
void visitEnd();
}
interface AnnotationArrayArgumentVisitor {
void visit(@Nullable Object value);
void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName);
void visitEnd();
}
@@ -27,8 +27,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.AbiVersionUtil.isAbiVersionCompatible;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.*;
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArgumentVisitor;
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationVisitor;
import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.*;
import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind.*;
public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor {
@@ -113,7 +112,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Override
@Nullable
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
public AnnotationArrayArgumentVisitor visitArray(@NotNull Name name) {
if (name.asString().equals(DATA_FIELD_NAME)) {
return stringArrayVisitor();
}
@@ -125,11 +124,11 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@NotNull
private AnnotationArgumentVisitor stringArrayVisitor() {
private AnnotationArrayArgumentVisitor stringArrayVisitor() {
final List<String> strings = new ArrayList<String>(1);
return new AnnotationArgumentVisitor() {
return new AnnotationArrayArgumentVisitor() {
@Override
public void visit(@Nullable Name name, @Nullable Object value) {
public void visit(@Nullable Object value) {
if (!(value instanceof String)) {
throw new IllegalStateException("Unexpected argument value: " + value);
}
@@ -138,14 +137,8 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@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);
public void visitEnum(@NotNull JvmClassName enumClassName, @NotNull Name enumEntryName) {
unexpectedArgument(null, annotationClassName);
}
@Override
@@ -186,7 +179,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable
@Override
public AnnotationArgumentVisitor visitArray(@NotNull Name name) {
public AnnotationArrayArgumentVisitor visitArray(@NotNull Name name) {
return unexpectedArgument(name, KotlinSyntheticClass.CLASS_NAME);
}
@@ -206,7 +199,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
@Nullable
private AnnotationArgumentVisitor unexpectedArgument(@Nullable Name name, @NotNull JvmClassName annotationClassName) {
private AnnotationArrayArgumentVisitor unexpectedArgument(@Nullable Name name, @NotNull JvmClassName annotationClassName) {
if (isAbiVersionCompatible(version)) {
throw new IllegalStateException("Unexpected argument " + name + " for annotation " + annotationClassName);
}