mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 00: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<>();
|
annotationsByType = new HashMap<>();
|
||||||
for (TAnnotation annot : getAnnotations()) {
|
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;
|
package org.teavm.classlib.java.lang.annotation;
|
||||||
|
|
||||||
|
import org.teavm.javascript.spi.Rename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public @interface TAnnotation {
|
public @interface TAnnotation {
|
||||||
|
@Rename("annotationType")
|
||||||
|
Class<?> annotationType0();
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,11 @@ public class AnnotationClassTransformer implements ClassHolderTransformer {
|
||||||
List<ValueEmitter> params = new ArrayList<>();
|
List<ValueEmitter> params = new ArrayList<>();
|
||||||
for (MethodReader methodDecl : annotationClass.getMethods()) {
|
for (MethodReader methodDecl : annotationClass.getMethods()) {
|
||||||
ctorSignature.add(methodDecl.getResultType());
|
ctorSignature.add(methodDecl.getResultType());
|
||||||
AnnotationValue value = annotation.getValue(className);
|
AnnotationValue value = annotation.getValue(methodDecl.getName());
|
||||||
params.add(value != null ? generateAnnotationValue(classSource, pe, methodDecl.getResultType(), value) :
|
if (value == null) {
|
||||||
pe.constantNull());
|
value = methodDecl.getAnnotationDefault();
|
||||||
|
}
|
||||||
|
params.add(generateAnnotationValue(classSource, pe, methodDecl.getResultType(), value));
|
||||||
}
|
}
|
||||||
ctorSignature.add(ValueType.VOID);
|
ctorSignature.add(ValueType.VOID);
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,12 @@ public class AnnotationDependencyListener implements DependencyListener {
|
||||||
pe.exit();
|
pe.exit();
|
||||||
implementor.addMethod(ctor);
|
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;
|
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.writeInt(symbolTable.lookup(annotation.getType()));
|
||||||
output.writeShort(annotation.getValues().size());
|
int fieldCount = 0;
|
||||||
for (Map.Entry<String, AnnotationValue> entry : annotation.getValues().entrySet()) {
|
for (@SuppressWarnings("unused") String field : annotation.getAvailableFields()) {
|
||||||
output.writeInt(symbolTable.lookup(entry.getKey()));
|
++fieldCount;
|
||||||
writeAnnotationValue(output, entry.getValue());
|
}
|
||||||
|
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;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotationValue(AnnotationHolder value) {
|
public AnnotationValue(AnnotationReader value) {
|
||||||
this.type = ANNOTATION;
|
this.type = ANNOTATION;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
@ -176,11 +176,11 @@ public class AnnotationValue {
|
||||||
return (FieldReference)value;
|
return (FieldReference)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnnotationHolder getAnnotation() {
|
public AnnotationReader getAnnotation() {
|
||||||
if (type != ANNOTATION) {
|
if (type != ANNOTATION) {
|
||||||
throw new IllegalStateException("There is no annotation value");
|
throw new IllegalStateException("There is no annotation value");
|
||||||
}
|
}
|
||||||
return (AnnotationHolder)value;
|
return (AnnotationReader)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getType() {
|
public byte getType() {
|
||||||
|
|
|
@ -22,7 +22,8 @@ package org.teavm.model;
|
||||||
public class MethodHolder extends MemberHolder implements MethodReader {
|
public class MethodHolder extends MemberHolder implements MethodReader {
|
||||||
private MethodDescriptor descriptor;
|
private MethodDescriptor descriptor;
|
||||||
private ClassHolder owner;
|
private ClassHolder owner;
|
||||||
private volatile Program program;
|
private Program program;
|
||||||
|
private AnnotationValue annotationDefault;
|
||||||
|
|
||||||
public MethodHolder(MethodDescriptor descriptor) {
|
public MethodHolder(MethodDescriptor descriptor) {
|
||||||
super(descriptor.getName());
|
super(descriptor.getName());
|
||||||
|
@ -95,4 +96,13 @@ public class MethodHolder extends MemberHolder implements MethodReader {
|
||||||
this.program.setMethod(this);
|
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();
|
MethodReference getReference();
|
||||||
|
|
||||||
ProgramReader getProgram();
|
ProgramReader getProgram();
|
||||||
|
|
||||||
|
AnnotationValue getAnnotationDefault();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ public final class ModelUtils {
|
||||||
copy.setProgram(ProgramUtils.copy(method.getProgram()));
|
copy.setProgram(ProgramUtils.copy(method.getProgram()));
|
||||||
}
|
}
|
||||||
copyAnnotations(method.getAnnotations(), copy.getAnnotations());
|
copyAnnotations(method.getAnnotations(), copy.getAnnotations());
|
||||||
|
if (method.getAnnotationDefault() != null) {
|
||||||
|
copy.setAnnotationDefault(copyAnnotationValue(method.getAnnotationDefault()));
|
||||||
|
}
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ public final class Parser {
|
||||||
while (program.variableCount() <= method.parameterCount()) {
|
while (program.variableCount() <= method.parameterCount()) {
|
||||||
program.createVariable();
|
program.createVariable();
|
||||||
}
|
}
|
||||||
|
if (node.annotationDefault != null) {
|
||||||
|
method.setAnnotationDefault(parseAnnotationValue(node.annotationDefault));
|
||||||
|
}
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,11 +119,32 @@ public class ClassTest {
|
||||||
assertTrue(TestAnnot.class.isAssignableFrom(annotations[0].getClass()));
|
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
|
@TestAnnot
|
||||||
private static class A {
|
private static class A {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AnnotWithDefaultField
|
||||||
|
private static class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
@AnnotWithDefaultField(x = 3)
|
||||||
|
private static class C {
|
||||||
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface TestAnnot {
|
static @interface TestAnnot {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
static @interface AnnotWithDefaultField {
|
||||||
|
int x() default 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user