mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Add support of annotation fields and default values
This commit is contained in:
parent
32feb24d0f
commit
8daba1f09f
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,4 +35,6 @@ public interface MethodReader extends MemberReader {
|
|||
MethodReference getReference();
|
||||
|
||||
ProgramReader getProgram();
|
||||
|
||||
AnnotationValue getAnnotationDefault();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user