mirror of
https://github.com/konsoletyper/teavm.git
synced 2025-01-06 10:15:18 +08:00
Add tests for annotation field types
This commit is contained in:
parent
8daba1f09f
commit
dbd2c3f6bc
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.annotation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public enum TElementType {
|
||||
ANNOTATION_TYPE,
|
||||
CONSTRUCTOR,
|
||||
FIELD,
|
||||
LOCAL_VARIABLE,
|
||||
METHOD,
|
||||
PACKAGE,
|
||||
PARAMETER,
|
||||
TYPE
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
public @interface TRetention {
|
||||
TRetentionPolicy value();
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.annotation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public enum TRetentionPolicy {
|
||||
CLASS,
|
||||
RUNTIME,
|
||||
SOURCE
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2015 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
public @interface TTarget {
|
||||
TElementType[] value();
|
||||
}
|
@ -128,6 +128,7 @@ public class AnnotationClassTransformer implements ClassHolderTransformer {
|
||||
return array;
|
||||
}
|
||||
case AnnotationValue.ENUM:
|
||||
pe.initClass(value.getEnumValue().getClassName());
|
||||
return pe.getField(value.getEnumValue(), type);
|
||||
case AnnotationValue.CLASS:
|
||||
return pe.constant(value.getJavaClass());
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.teavm.callgraph;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.teavm.model.InstructionLocation;
|
||||
|
||||
/**
|
||||
@ -46,4 +47,23 @@ public class DefaultClassAccessSite implements ClassAccessSite {
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(location, callee, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof DefaultClassAccessSite)) {
|
||||
return false;
|
||||
}
|
||||
DefaultClassAccessSite other = (DefaultClassAccessSite)obj;
|
||||
return Objects.equals(location, other.location) &&
|
||||
Objects.equals(callee, other.callee) &&
|
||||
Objects.equals(className, other.className);
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ public class DependencyChecker implements DependencyInfo {
|
||||
|
||||
private Set<String> classesAddedByRoot = new HashSet<>();
|
||||
|
||||
public ClassDependency linkClass(String className, CallLocation callLocation) {
|
||||
public ClassDependency linkClass(final String className, final CallLocation callLocation) {
|
||||
ClassDependency dep = classCache.map(className);
|
||||
boolean added = true;
|
||||
if (callLocation != null && callLocation.getMethod() != null) {
|
||||
@ -215,9 +215,14 @@ public class DependencyChecker implements DependencyInfo {
|
||||
added = classesAddedByRoot.add(className);
|
||||
}
|
||||
if (!dep.isMissing() && added) {
|
||||
for (DependencyListener listener : listeners) {
|
||||
listener.classAchieved(agent, className, callLocation);
|
||||
}
|
||||
tasks.add(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (DependencyListener listener : listeners) {
|
||||
listener.classAchieved(agent, className, callLocation);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return dep;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import org.teavm.model.instructions.DoubleConstantInstruction;
|
||||
import org.teavm.model.instructions.ExitInstruction;
|
||||
import org.teavm.model.instructions.FloatConstantInstruction;
|
||||
import org.teavm.model.instructions.GetFieldInstruction;
|
||||
import org.teavm.model.instructions.InitClassInstruction;
|
||||
import org.teavm.model.instructions.IntegerConstantInstruction;
|
||||
import org.teavm.model.instructions.InvocationType;
|
||||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
@ -203,6 +204,12 @@ public final class ProgramEmitter {
|
||||
return constructArray(ValueType.parse(type), size);
|
||||
}
|
||||
|
||||
public void initClass(String className) {
|
||||
InitClassInstruction insn = new InitClassInstruction();
|
||||
insn.setClassName(className);
|
||||
addInstruction(insn);
|
||||
}
|
||||
|
||||
public ProgramEmitter jump(BasicBlock block) {
|
||||
JumpInstruction insn = new JumpInstruction();
|
||||
insn.setTarget(block);
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.teavm.parsing;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@ -197,7 +198,8 @@ public final class Parser {
|
||||
private static AnnotationValue parseAnnotationValue(Object value) {
|
||||
if (value instanceof String[]) {
|
||||
String[] enumInfo = (String[])value;
|
||||
return new AnnotationValue(new FieldReference(enumInfo[0], enumInfo[1]));
|
||||
ValueType.Object object = (ValueType.Object)ValueType.parse(enumInfo[0]);
|
||||
return new AnnotationValue(new FieldReference(object.getClassName(), enumInfo[1]));
|
||||
} else if (value instanceof Type) {
|
||||
Type cls = (Type)value;
|
||||
return new AnnotationValue(ValueType.parse(cls.getDescriptor()));
|
||||
@ -210,7 +212,8 @@ public final class Parser {
|
||||
return new AnnotationValue(resultList);
|
||||
} else if (value instanceof AnnotationNode) {
|
||||
AnnotationNode annotNode = (AnnotationNode)value;
|
||||
AnnotationHolder annotation = new AnnotationHolder(annotNode.desc.replace('.', '/'));
|
||||
ValueType.Object object = (ValueType.Object)ValueType.parse(annotNode.desc);
|
||||
AnnotationHolder annotation = new AnnotationHolder(object.getClassName());
|
||||
parseAnnotationValues(annotation, annotNode.values);
|
||||
return new AnnotationValue(annotation);
|
||||
} else if (value instanceof String) {
|
||||
@ -229,6 +232,14 @@ public final class Parser {
|
||||
return new AnnotationValue((Float)value);
|
||||
} else if (value instanceof Double) {
|
||||
return new AnnotationValue((Double)value);
|
||||
} else if (value.getClass().isArray()) {
|
||||
List<AnnotationValue> resultList = new ArrayList<>();
|
||||
int size = Array.getLength(value);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
Object item = Array.get(value, i);
|
||||
resultList.add(parseAnnotationValue(item));
|
||||
}
|
||||
return new AnnotationValue(resultList);
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@ -127,6 +128,26 @@ public class ClassTest {
|
||||
assertEquals(3, annot.x());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotationFieldTypesSupported() {
|
||||
AnnotWithVariousFields annot = D.class.getAnnotation(AnnotWithVariousFields.class);
|
||||
assertEquals(true, annot.a());
|
||||
assertEquals((byte)2, annot.b());
|
||||
assertEquals((short)3, annot.c());
|
||||
assertEquals(4, annot.d());
|
||||
assertEquals(5L, annot.e());
|
||||
assertEquals(6.5, annot.f(), 0.01);
|
||||
assertEquals(7.2, annot.g(), 0.01);
|
||||
assertArrayEquals(new int[] { 2, 3 }, annot.h());
|
||||
assertEquals(RetentionPolicy.CLASS, annot.i());
|
||||
assertEquals(Retention.class, annot.j().annotationType());
|
||||
assertEquals(1, annot.k().length);
|
||||
assertEquals(RetentionPolicy.RUNTIME, annot.k()[0].value());
|
||||
assertEquals("foo", annot.l());
|
||||
assertArrayEquals(new String[] { "bar" }, annot.m());
|
||||
assertEquals(Integer.class, annot.n());
|
||||
}
|
||||
|
||||
@TestAnnot
|
||||
private static class A {
|
||||
}
|
||||
@ -139,6 +160,12 @@ public class ClassTest {
|
||||
private static class C {
|
||||
}
|
||||
|
||||
@AnnotWithVariousFields(a = true, b = 2, c = 3, d = 4, e = 5, f = 6.5f, g = 7.2, h = { 2, 3 },
|
||||
i = RetentionPolicy.CLASS, j = @Retention(RetentionPolicy.SOURCE),
|
||||
k = { @Retention(RetentionPolicy.RUNTIME) }, l = "foo", m = "bar", n = Integer.class)
|
||||
private static class D {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnot {
|
||||
}
|
||||
@ -147,4 +174,35 @@ public class ClassTest {
|
||||
static @interface AnnotWithDefaultField {
|
||||
int x() default 2;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface AnnotWithVariousFields {
|
||||
boolean a();
|
||||
|
||||
byte b();
|
||||
|
||||
short c();
|
||||
|
||||
int d();
|
||||
|
||||
long e();
|
||||
|
||||
float f();
|
||||
|
||||
double g();
|
||||
|
||||
int[] h();
|
||||
|
||||
RetentionPolicy i();
|
||||
|
||||
Retention j();
|
||||
|
||||
Retention[] k();
|
||||
|
||||
String l();
|
||||
|
||||
String[] m();
|
||||
|
||||
Class<?> n();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user