Add support of annotation fields and default values

This commit is contained in:
Alexey Andreev 2015-06-19 19:42:06 +04:00
parent 32feb24d0f
commit 8daba1f09f
11 changed files with 68 additions and 13 deletions

View File

@ -237,7 +237,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement {
}
annotationsByType = new HashMap<>();
for (TAnnotation annot : getAnnotations()) {
annotationsByType.put((TClass<?>)(Object)annot.getClass(), annot);
annotationsByType.put((TClass<?>)(Object)annot.annotationType(), annot);
}
}
}

View File

@ -15,9 +15,13 @@
*/
package org.teavm.classlib.java.lang.annotation;
import org.teavm.javascript.spi.Rename;
/**
*
* @author Alexey Andreev
*/
public @interface TAnnotation {
@Rename("annotationType")
Class<?> annotationType0();
}

View File

@ -85,9 +85,11 @@ public class AnnotationClassTransformer implements ClassHolderTransformer {
List<ValueEmitter> params = new ArrayList<>();
for (MethodReader methodDecl : annotationClass.getMethods()) {
ctorSignature.add(methodDecl.getResultType());
AnnotationValue value = annotation.getValue(className);
params.add(value != null ? generateAnnotationValue(classSource, pe, methodDecl.getResultType(), value) :
pe.constantNull());
AnnotationValue value = annotation.getValue(methodDecl.getName());
if (value == null) {
value = methodDecl.getAnnotationDefault();
}
params.add(generateAnnotationValue(classSource, pe, methodDecl.getResultType(), value));
}
ctorSignature.add(ValueType.VOID);

View File

@ -122,6 +122,12 @@ public class AnnotationDependencyListener implements DependencyListener {
pe.exit();
implementor.addMethod(ctor);
MethodHolder annotTypeMethod = new MethodHolder("annotationType", ValueType.parse(Class.class));
pe = ProgramEmitter.create(annotTypeMethod);
pe.wrapNew();
pe.constant(ValueType.object(annotationType)).returnValue();
implementor.addMethod(annotTypeMethod);
return implementor;
}

View File

@ -239,12 +239,16 @@ public class DiskCachedClassHolderSource implements ClassHolderSource {
}
}
private void writeAnnotation(DataOutput output, AnnotationHolder annotation) throws IOException {
private void writeAnnotation(DataOutput output, AnnotationReader annotation) throws IOException {
output.writeInt(symbolTable.lookup(annotation.getType()));
output.writeShort(annotation.getValues().size());
for (Map.Entry<String, AnnotationValue> entry : annotation.getValues().entrySet()) {
output.writeInt(symbolTable.lookup(entry.getKey()));
writeAnnotationValue(output, entry.getValue());
int fieldCount = 0;
for (@SuppressWarnings("unused") String field : annotation.getAvailableFields()) {
++fieldCount;
}
output.writeShort(fieldCount);
for (String field : annotation.getAvailableFields()) {
output.writeInt(symbolTable.lookup(field));
writeAnnotationValue(output, annotation.getValue(field));
}
}

View File

@ -88,7 +88,7 @@ public class AnnotationValue {
this.value = value;
}
public AnnotationValue(AnnotationHolder value) {
public AnnotationValue(AnnotationReader value) {
this.type = ANNOTATION;
this.value = value;
}
@ -176,11 +176,11 @@ public class AnnotationValue {
return (FieldReference)value;
}
public AnnotationHolder getAnnotation() {
public AnnotationReader getAnnotation() {
if (type != ANNOTATION) {
throw new IllegalStateException("There is no annotation value");
}
return (AnnotationHolder)value;
return (AnnotationReader)value;
}
public byte getType() {

View File

@ -22,7 +22,8 @@ package org.teavm.model;
public class MethodHolder extends MemberHolder implements MethodReader {
private MethodDescriptor descriptor;
private ClassHolder owner;
private volatile Program program;
private Program program;
private AnnotationValue annotationDefault;
public MethodHolder(MethodDescriptor descriptor) {
super(descriptor.getName());
@ -95,4 +96,13 @@ public class MethodHolder extends MemberHolder implements MethodReader {
this.program.setMethod(this);
}
}
@Override
public AnnotationValue getAnnotationDefault() {
return annotationDefault;
}
public void setAnnotationDefault(AnnotationValue annotationDefault) {
this.annotationDefault = annotationDefault;
}
}

View File

@ -35,4 +35,6 @@ public interface MethodReader extends MemberReader {
MethodReference getReference();
ProgramReader getProgram();
AnnotationValue getAnnotationDefault();
}

View File

@ -52,6 +52,9 @@ public final class ModelUtils {
copy.setProgram(ProgramUtils.copy(method.getProgram()));
}
copyAnnotations(method.getAnnotations(), copy.getAnnotations());
if (method.getAnnotationDefault() != null) {
copy.setAnnotationDefault(copyAnnotationValue(method.getAnnotationDefault()));
}
return copy;
}

View File

@ -53,6 +53,9 @@ public final class Parser {
while (program.variableCount() <= method.parameterCount()) {
program.createVariable();
}
if (node.annotationDefault != null) {
method.setAnnotationDefault(parseAnnotationValue(node.annotationDefault));
}
return method;
}

View File

@ -119,11 +119,32 @@ public class ClassTest {
assertTrue(TestAnnot.class.isAssignableFrom(annotations[0].getClass()));
}
@Test
public void annotationFieldsExposed() {
AnnotWithDefaultField annot = B.class.getAnnotation(AnnotWithDefaultField.class);
assertEquals(2, annot.x());
annot = C.class.getAnnotation(AnnotWithDefaultField.class);
assertEquals(3, annot.x());
}
@TestAnnot
private static class A {
}
@AnnotWithDefaultField
private static class B {
}
@AnnotWithDefaultField(x = 3)
private static class C {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface TestAnnot {
}
@Retention(RetentionPolicy.RUNTIME)
static @interface AnnotWithDefaultField {
int x() default 2;
}
}