mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
parent
6788642ea9
commit
c1b3deedff
|
@ -34,6 +34,7 @@ public final class Flags {
|
||||||
public static final int TRANSIENT = 4096;
|
public static final int TRANSIENT = 4096;
|
||||||
public static final int VARARGS = 8192;
|
public static final int VARARGS = 8192;
|
||||||
public static final int VOLATILE = 16384;
|
public static final int VOLATILE = 16384;
|
||||||
|
public static final int INHERITED_ANNOTATION = 32768;
|
||||||
|
|
||||||
public static final int PACKAGE_PRIVATE = 0;
|
public static final int PACKAGE_PRIVATE = 0;
|
||||||
public static final int PRIVATE = 1;
|
public static final int PRIVATE = 1;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -58,6 +59,7 @@ public class TClass<T> extends TObject implements TAnnotatedElement, TType {
|
||||||
String canonicalName;
|
String canonicalName;
|
||||||
private PlatformClass platformClass;
|
private PlatformClass platformClass;
|
||||||
private TAnnotation[] annotationsCache;
|
private TAnnotation[] annotationsCache;
|
||||||
|
private TAnnotation[] declaredAnnotationsCache;
|
||||||
private Map<TClass<?>, TAnnotation> annotationsByType;
|
private Map<TClass<?>, TAnnotation> annotationsByType;
|
||||||
private TField[] declaredFields;
|
private TField[] declaredFields;
|
||||||
private TField[] fields;
|
private TField[] fields;
|
||||||
|
@ -744,14 +746,33 @@ public class TClass<T> extends TObject implements TAnnotatedElement, TType {
|
||||||
@Override
|
@Override
|
||||||
public TAnnotation[] getAnnotations() {
|
public TAnnotation[] getAnnotations() {
|
||||||
if (annotationsCache == null) {
|
if (annotationsCache == null) {
|
||||||
annotationsCache = (TAnnotation[]) Platform.getAnnotations(getPlatformClass());
|
TClass<?> cls = this;
|
||||||
|
var initial = true;
|
||||||
|
var map = new LinkedHashMap<Class<?>, TAnnotation>();
|
||||||
|
while (cls != null) {
|
||||||
|
for (var annot : cls.getDeclaredAnnotations()) {
|
||||||
|
var platformClass = ((TClass<?>) (Object) annot.annotationType()).platformClass;
|
||||||
|
if (initial || (platformClass.getMetadata().getFlags() & Flags.INHERITED_ANNOTATION) != 0) {
|
||||||
|
map.putIfAbsent(annot.annotationType(), annot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cls = cls.getSuperclass();
|
||||||
|
initial = false;
|
||||||
|
}
|
||||||
|
annotationsCache = map.values().toArray(new TAnnotation[0]);
|
||||||
}
|
}
|
||||||
return annotationsCache.clone();
|
return annotationsCache.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TAnnotation[] getDeclaredAnnotations() {
|
public TAnnotation[] getDeclaredAnnotations() {
|
||||||
return getAnnotations();
|
if (declaredAnnotationsCache == null) {
|
||||||
|
declaredAnnotationsCache = (TAnnotation[]) Platform.getAnnotations(getPlatformClass());
|
||||||
|
if (declaredAnnotationsCache == null) {
|
||||||
|
declaredAnnotationsCache = new TAnnotation[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return declaredAnnotationsCache.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureAnnotationsByType() {
|
private void ensureAnnotationsByType() {
|
||||||
|
|
|
@ -17,6 +17,8 @@ package org.teavm.backend.javascript.rendering;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.ObjectIntHashMap;
|
import com.carrotsearch.hppc.ObjectIntHashMap;
|
||||||
import com.carrotsearch.hppc.ObjectIntMap;
|
import com.carrotsearch.hppc.ObjectIntMap;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -517,7 +519,16 @@ public class Renderer implements RenderingManager {
|
||||||
}
|
}
|
||||||
writer.append("],").ws();
|
writer.append("],").ws();
|
||||||
|
|
||||||
writer.append(ElementModifier.pack(cls.readModifiers())).append(',').ws();
|
var flags = ElementModifier.pack(cls.readModifiers());
|
||||||
|
if (cls.hasModifier(ElementModifier.ANNOTATION)) {
|
||||||
|
var retention = cls.getAnnotations().get(Retention.class.getName());
|
||||||
|
if (retention != null && retention.getValue("value").getEnumValue().getFieldName().equals("RUNTIME")) {
|
||||||
|
if (cls.getAnnotations().get(Inherited.class.getName()) != null) {
|
||||||
|
flags |= 32768;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.append(flags).append(',').ws();
|
||||||
writer.append(cls.getLevel().ordinal()).append(',').ws();
|
writer.append(cls.getLevel().ordinal()).append(',').ws();
|
||||||
|
|
||||||
if (!requiredMetadata.enclosingClass() && !requiredMetadata.declaringClass()
|
if (!requiredMetadata.enclosingClass() && !requiredMetadata.declaringClass()
|
||||||
|
|
|
@ -20,11 +20,12 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Inherited;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.teavm.junit.SkipPlatform;
|
import org.teavm.junit.SkipPlatform;
|
||||||
|
@ -182,9 +183,8 @@ public class ClassTest {
|
||||||
@Test
|
@Test
|
||||||
@SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI})
|
@SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI})
|
||||||
public void annotationsExposed() {
|
public void annotationsExposed() {
|
||||||
Annotation[] annotations = A.class.getAnnotations();
|
var annotations = A.class.getAnnotations();
|
||||||
assertEquals(1, annotations.length);
|
assertTrue(Stream.of(annotations).anyMatch(a -> a instanceof TestAnnot));
|
||||||
assertTrue(TestAnnot.class.isAssignableFrom(annotations[0].getClass()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -225,6 +225,23 @@ public class ClassTest {
|
||||||
Set.of(ClassWithInterfaces.class.getInterfaces()));
|
Set.of(ClassWithInterfaces.class.getInterfaces()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SkipPlatform({TestPlatform.C, TestPlatform.WEBASSEMBLY, TestPlatform.WASI})
|
||||||
|
public void inheritedAnnotation() {
|
||||||
|
assertTrue(A.class.isAnnotationPresent(InheritedAnnot.class));
|
||||||
|
assertTrue(A.class.isAnnotationPresent(TestAnnot.class));
|
||||||
|
assertTrue(ASub.class.isAnnotationPresent(InheritedAnnot.class));
|
||||||
|
assertFalse(ASub.class.isAnnotationPresent(TestAnnot.class));
|
||||||
|
assertTrue(TestInterface1.class.isAnnotationPresent(InheritedAnnot.class));
|
||||||
|
assertFalse(ClassWithInterfaces.class.isAnnotationPresent(InheritedAnnot.class));
|
||||||
|
|
||||||
|
var annotationSet = Set.of(ASub.class.getAnnotations());
|
||||||
|
assertTrue(annotationSet.stream().anyMatch(a -> a instanceof InheritedAnnot));
|
||||||
|
assertFalse(annotationSet.stream().anyMatch(a -> a instanceof TestAnnot));
|
||||||
|
|
||||||
|
assertEquals(0, ASub.class.getDeclaredAnnotations().length);
|
||||||
|
}
|
||||||
|
|
||||||
private static class SuperclassWithoutInterfaces {
|
private static class SuperclassWithoutInterfaces {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +249,7 @@ public class ClassTest {
|
||||||
implements TestInterface1, TestInterface2 {
|
implements TestInterface1, TestInterface2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InheritedAnnot
|
||||||
private interface TestInterface1 {
|
private interface TestInterface1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,9 +257,13 @@ public class ClassTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestAnnot
|
@TestAnnot
|
||||||
|
@InheritedAnnot
|
||||||
private static class A {
|
private static class A {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ASub extends A {
|
||||||
|
}
|
||||||
|
|
||||||
@AnnotWithDefaultField
|
@AnnotWithDefaultField
|
||||||
private static class B {
|
private static class B {
|
||||||
}
|
}
|
||||||
|
@ -265,6 +287,11 @@ public class ClassTest {
|
||||||
int x() default 2;
|
int x() default 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Inherited
|
||||||
|
@interface InheritedAnnot {
|
||||||
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@interface AnnotWithVariousFields {
|
@interface AnnotWithVariousFields {
|
||||||
boolean a();
|
boolean a();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user