8295059: test/langtools/tools/javap 12 test classes use com.sun.tools.classfile library
Reviewed-by: asotona
This commit is contained in:
parent
3671d83c87
commit
97b688340e
@ -24,11 +24,18 @@
|
||||
/*
|
||||
* @test 6716452
|
||||
* @summary need a method to get an index of an attribute
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
public class T6716452 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -38,49 +45,44 @@ public class T6716452 {
|
||||
public void run() throws Exception {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.Code, Code_attribute.class);
|
||||
test(cf, m, Attribute.Exceptions, Exceptions_attribute.class);
|
||||
void test(MethodModel mm) {
|
||||
test(mm, Attributes.CODE, CodeAttribute.class);
|
||||
test(mm, Attributes.EXCEPTIONS, ExceptionsAttribute.class);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// test the result of MethodModel.findAttribute, MethodModel.attributes().indexOf() according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, Class<?> c) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
try {
|
||||
String m_name = m.getName(cf.constant_pool);
|
||||
System.err.println("Method " + m_name + " name:" + name + " index:" + index + " class: " + c);
|
||||
boolean expect = (m_name.equals("<init>") && name.equals("Code"))
|
||||
|| (m_name.indexOf(name) != -1);
|
||||
boolean found = (index != -1);
|
||||
if (expect) {
|
||||
if (found) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
if (!c.isAssignableFrom(attr.getClass())) {
|
||||
error(m + ": unexpected attribute found,"
|
||||
+ " expected " + c.getName()
|
||||
+ " found " + attr.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
error(m + ": expected attribute " + name + " not found");
|
||||
<T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr, Class<?> c) {
|
||||
Attribute<T> attr_instance = mm.findAttribute(attr).orElse(null);
|
||||
int index = mm.attributes().indexOf(attr_instance);
|
||||
String mm_name = mm.methodName().stringValue();
|
||||
System.err.println("Method " + mm_name + " name:" + attr.name() + " index:" + index + " class: " + c);
|
||||
boolean expect = (mm_name.equals("<init>") && attr.name().equals("Code"))
|
||||
|| (mm_name.contains(attr.name()));
|
||||
boolean found = (index != -1);
|
||||
if (expect) {
|
||||
if (found) {
|
||||
if (!c.isAssignableFrom(mm.attributes().get(index).getClass())) {
|
||||
error(mm + ": unexpected attribute found,"
|
||||
+ " expected " + c.getName()
|
||||
+ " found " + mm.attributes().get(index).attributeName());
|
||||
}
|
||||
} else {
|
||||
if (found) {
|
||||
error(m + ": unexpected attribute " + name);
|
||||
}
|
||||
error(mm + ": expected attribute " + attr.name() + " not found");
|
||||
}
|
||||
} else {
|
||||
if (found) {
|
||||
error(mm + ": unexpected attribute " + attr.name());
|
||||
}
|
||||
} catch (ConstantPoolException e) {
|
||||
error(m + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,17 @@
|
||||
* @modules
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* jdk.jdeps/com.sun.tools.javap
|
||||
* java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
* @build toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox toolbox.TestRunner
|
||||
* @run main TestClassNameWarning
|
||||
*/
|
||||
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -43,9 +48,8 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ClassWriter;
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import toolbox.JavacTask;
|
||||
import toolbox.JavapTask;
|
||||
import toolbox.Task;
|
||||
@ -140,7 +144,7 @@ public class TestClassNameWarning extends TestRunner {
|
||||
byte[] replaceBytes = "module-info".getBytes("UTF-8");
|
||||
for (int i = 0; i < bytes.length - searchBytes.length; i++) {
|
||||
if (Arrays.equals(bytes, i, i + searchBytes.length,
|
||||
searchBytes, 0, searchBytes.length)) {
|
||||
searchBytes, 0, searchBytes.length)) {
|
||||
System.arraycopy(replaceBytes, 0, bytes, i, replaceBytes.length);
|
||||
}
|
||||
}
|
||||
@ -172,14 +176,15 @@ public class TestClassNameWarning extends TestRunner {
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run()
|
||||
.writeAll();
|
||||
|
||||
ClassFile cf = ClassFile.read(classes.resolve("A.class"));
|
||||
ClassFile cf2 = new ClassFile(
|
||||
cf.magic, cf.minor_version, cf.major_version, cf.constant_pool,
|
||||
cf.access_flags,
|
||||
0, // this_class,
|
||||
cf.super_class, cf.interfaces, cf.fields, cf.methods, cf.attributes);
|
||||
new ClassWriter().write(cf2, Files.newOutputStream(classes.resolve("Z.class")));
|
||||
ClassModel cm = Classfile.of().parse(classes.resolve("A.class"));
|
||||
Classfile.of().buildTo(
|
||||
classes.resolve("Z.class"),
|
||||
ClassDesc.of("0"), cb -> {
|
||||
for (ClassElement ce : cm) {
|
||||
cb.with(ce);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
List<String> log = new JavapTask(tb)
|
||||
.classpath(classes.toString())
|
||||
@ -238,4 +243,3 @@ public class TestClassNameWarning extends TestRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,21 +24,23 @@
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.lang.constant.*;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.Type.ArrayType;
|
||||
import com.sun.tools.classfile.Type.ClassSigType;
|
||||
import com.sun.tools.classfile.Type.ClassType;
|
||||
import com.sun.tools.classfile.Type.MethodType;
|
||||
import com.sun.tools.classfile.Type.SimpleType;
|
||||
import com.sun.tools.classfile.Type.TypeParamType;
|
||||
import com.sun.tools.classfile.Type.WildcardType;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6888367
|
||||
* @summary classfile library parses signature attributes incorrectly
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -61,99 +63,108 @@ public class T6888367 {
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
ClassFile cf = getClassFile("Test");
|
||||
ClassModel cm = getClassFile("Test");
|
||||
|
||||
testFields(cf);
|
||||
testMethods(cf);
|
||||
testInnerClasses(cf); // recursive
|
||||
testFields(cm);
|
||||
testMethods(cm);
|
||||
testInnerClasses(cm); // recursive
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void testFields(ClassFile cf) throws Exception {
|
||||
String cn = cf.getName();
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
for (Field f: cf.fields) {
|
||||
test("field " + cn + "." + f.getName(cp), f.descriptor, f.attributes, cp);
|
||||
void testFields(ClassModel cm) throws Exception {
|
||||
String cn = cm.thisClass().name().stringValue();
|
||||
for (FieldModel fm: cm.fields()) {
|
||||
test("field " + cn + "." + fm.fieldName(), fm.fieldTypeSymbol(), fm);
|
||||
}
|
||||
}
|
||||
|
||||
void testMethods(ClassFile cf) throws Exception {
|
||||
String cn = cf.getName();
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
for (Method m: cf.methods) {
|
||||
test("method " + cn + "." + m.getName(cp), m.descriptor, m.attributes, cp);
|
||||
void testMethods(ClassModel cm) throws Exception {
|
||||
String cn = cm.thisClass().name().stringValue();
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test("method " + cn + "." + mm.methodName(), mm.methodTypeSymbol(), mm);
|
||||
}
|
||||
}
|
||||
|
||||
void testInnerClasses(ClassFile cf) throws Exception {
|
||||
ConstantPool cp = cf.constant_pool;
|
||||
InnerClasses_attribute ic =
|
||||
(InnerClasses_attribute) cf.attributes.get(Attribute.InnerClasses);
|
||||
for (InnerClasses_attribute.Info info: ic.classes) {
|
||||
String outerClassName = cp.getClassInfo(info.outer_class_info_index).getName();
|
||||
if (!outerClassName.equals(cf.getName())) {
|
||||
void testInnerClasses(ClassModel cm) throws Exception {
|
||||
InnerClassesAttribute ic =
|
||||
cm.findAttribute(Attributes.INNER_CLASSES).orElse(null);
|
||||
assert ic != null;
|
||||
for (InnerClassInfo info: ic.classes()) {
|
||||
ClassEntry outerClass = info.outerClass().orElse(null);
|
||||
if (outerClass == null || !outerClass.name().equalsString(cm.getClass().getName())) {
|
||||
continue;
|
||||
}
|
||||
String innerClassName = cp.getClassInfo(info.inner_class_info_index).getName();
|
||||
ClassFile icf = getClassFile(innerClassName);
|
||||
test("class " + innerClassName, null, icf.attributes, icf.constant_pool);
|
||||
testInnerClasses(icf);
|
||||
String innerClassName = info.innerClass().asInternalName();
|
||||
ClassModel icm = getClassFile(innerClassName);
|
||||
test("class " + innerClassName, null, icm);
|
||||
testInnerClasses(icm);
|
||||
}
|
||||
}
|
||||
|
||||
void test(String name, Descriptor desc, Attributes attrs, ConstantPool cp)
|
||||
throws Exception {
|
||||
AnnotValues d = getDescValue(attrs, cp);
|
||||
AnnotValues s = getSigValue(attrs, cp);
|
||||
void test(String name, ConstantDesc desc, AttributedElement m) {
|
||||
AnnotValues d = getDescValue(m);
|
||||
AnnotValues s = getSigValue(m);
|
||||
if (d == null && s == null) // not a test field or method if no @Desc or @Sig given
|
||||
return;
|
||||
|
||||
System.err.println(name);
|
||||
|
||||
if (desc != null) {
|
||||
System.err.println(" descriptor: " + desc.getValue(cp));
|
||||
checkEqual(d.raw, desc.getValue(cp));
|
||||
Type dt = new Signature(desc.index).getType(cp);
|
||||
checkEqual(d.type, tp.print(dt));
|
||||
}
|
||||
|
||||
Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature);
|
||||
SignatureAttribute sa = m.findAttribute(Attributes.SIGNATURE).orElse(null);
|
||||
if (sa != null)
|
||||
System.err.println(" signature: " + sa.getSignature(cp));
|
||||
System.err.println(" signature: " + sa.signature());
|
||||
|
||||
if (s != null || sa != null) {
|
||||
if (s != null && sa != null) {
|
||||
checkEqual(s.raw, sa.getSignature(cp));
|
||||
Type st = new Signature(sa.signature_index).getType(cp);
|
||||
checkEqual(s.type, tp.print(st));
|
||||
} else if (s != null)
|
||||
error("@Sig annotation found but not Signature attribute");
|
||||
else
|
||||
error("Signature attribute found but no @Sig annotation");
|
||||
switch (desc) {
|
||||
case ClassDesc cDesc -> {
|
||||
System.err.println(" descriptor: " + cDesc.descriptorString());
|
||||
checkEqual(d.raw, cDesc.descriptorString());
|
||||
Signature dt = Signature.of(cDesc);
|
||||
checkEqual(d.type, tp.print(dt));
|
||||
if (s != null || sa != null) {
|
||||
if (s != null && sa != null) {
|
||||
checkEqual(s.raw, sa.signature().stringValue());
|
||||
Signature st = Signature.parseFrom(sa.signature().stringValue());
|
||||
checkEqual(s.type, tp.print(st));
|
||||
} else if (s != null)
|
||||
error("@Sig annotation found but not Signature attribute");
|
||||
else
|
||||
error("Signature attribute found but no @Sig annotation");
|
||||
}
|
||||
}
|
||||
case MethodTypeDesc mDesc -> {
|
||||
System.err.println(" descriptor: " + mDesc.descriptorString());
|
||||
checkEqual(d.raw, mDesc.descriptorString());
|
||||
MethodSignature mdt = MethodSignature.of(mDesc);
|
||||
checkEqual(d.type, tp.print(mdt));
|
||||
if (s != null || sa != null) {
|
||||
if (s != null && sa != null) {
|
||||
checkEqual(s.raw, sa.signature().stringValue());
|
||||
MethodSignature mst = MethodSignature.parseFrom(sa.signature().stringValue());
|
||||
checkEqual(s.type, tp.print(mst));
|
||||
} else if (s != null)
|
||||
error("@Sig annotation found but not Signature attribute");
|
||||
else
|
||||
error("Signature attribute found but no @Sig annotation");
|
||||
}
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
|
||||
System.err.println();
|
||||
}
|
||||
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
URL url = getClass().getResource(name + ".class");
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
ClassModel getClassFile(String name) throws IOException, URISyntaxException {
|
||||
URL rsc = getClass().getResource(name + ".class");
|
||||
assert rsc != null;
|
||||
return Classfile.of().parse(Paths.get(rsc.toURI()));
|
||||
}
|
||||
|
||||
AnnotValues getDescValue(Attributes attrs, ConstantPool cp) throws Exception {
|
||||
return getAnnotValues(Desc.class.getName(), attrs, cp);
|
||||
AnnotValues getDescValue(AttributedElement m) {
|
||||
return getAnnotValues(Desc.class.getName(), m);
|
||||
}
|
||||
|
||||
AnnotValues getSigValue(Attributes attrs, ConstantPool cp) throws Exception {
|
||||
return getAnnotValues(Sig.class.getName(), attrs, cp);
|
||||
AnnotValues getSigValue(AttributedElement m) {
|
||||
return getAnnotValues(Sig.class.getName(), m);
|
||||
}
|
||||
|
||||
static class AnnotValues {
|
||||
@ -165,20 +176,14 @@ public class T6888367 {
|
||||
final String type;
|
||||
}
|
||||
|
||||
AnnotValues getAnnotValues(String annotName, Attributes attrs, ConstantPool cp)
|
||||
throws Exception {
|
||||
RuntimeInvisibleAnnotations_attribute annots =
|
||||
(RuntimeInvisibleAnnotations_attribute)attrs.get(Attribute.RuntimeInvisibleAnnotations);
|
||||
AnnotValues getAnnotValues(String annotName, AttributedElement m) {
|
||||
RuntimeInvisibleAnnotationsAttribute annots = m.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null);
|
||||
if (annots != null) {
|
||||
for (Annotation a: annots.annotations) {
|
||||
if (cp.getUTF8Value(a.type_index).equals("L" + annotName + ";")) {
|
||||
Annotation.Primitive_element_value pv0 =
|
||||
(Annotation.Primitive_element_value) a.element_value_pairs[0].value;
|
||||
Annotation.Primitive_element_value pv1 =
|
||||
(Annotation.Primitive_element_value) a.element_value_pairs[1].value;
|
||||
return new AnnotValues(
|
||||
cp.getUTF8Value(pv0.const_value_index),
|
||||
cp.getUTF8Value(pv1.const_value_index));
|
||||
for (Annotation a: annots.annotations()) {
|
||||
if (a.classSymbol().descriptorString().equals("L" + annotName + ";")) {
|
||||
String pv0 = ((AnnotationValue.OfString) a.elements().get(0).value()).stringValue();
|
||||
String pv1 = ((AnnotationValue.OfString) a.elements().get(1).value()).stringValue();
|
||||
return new AnnotValues(pv0, pv1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,7 +192,7 @@ public class T6888367 {
|
||||
}
|
||||
|
||||
void checkEqual(String expect, String found) {
|
||||
if (!(expect == null ? found == null : expect.equals(found))) {
|
||||
if (!(Objects.equals(expect, found))) {
|
||||
System.err.println("expected: " + expect);
|
||||
System.err.println(" found: " + found);
|
||||
error("unexpected values found");
|
||||
@ -203,96 +208,128 @@ public class T6888367 {
|
||||
|
||||
TypePrinter tp = new TypePrinter();
|
||||
|
||||
class TypePrinter implements Type.Visitor<String,Void> {
|
||||
String print(Type t) {
|
||||
return t == null ? null : t.accept(this, null);
|
||||
class TypePrinter {
|
||||
<T> String print(T t) {
|
||||
switch (t) {
|
||||
case Signature.BaseTypeSig type -> {
|
||||
return visitSimpleType(type);
|
||||
}
|
||||
case Signature.ArrayTypeSig type -> {
|
||||
return visitArrayType(type);
|
||||
}
|
||||
case Signature.ClassTypeSig type -> {
|
||||
return visitClassType(type);
|
||||
}
|
||||
case ClassSignature type -> {
|
||||
return visitClassSigType(type);
|
||||
}
|
||||
case MethodSignature type -> {
|
||||
return visitMethodType(type);
|
||||
}
|
||||
case Signature.TypeVarSig type -> {
|
||||
return "S{" + type.identifier() + "}"; //Consider the TypeVarSig as Simple Type
|
||||
}
|
||||
default -> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
String print(String pre, List<? extends Type> ts, String post) {
|
||||
<T> String print(String pre, List<T> ts, String post) {
|
||||
if (ts == null)
|
||||
return null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(pre);
|
||||
String sep = "";
|
||||
for (Type t: ts) {
|
||||
for (T t: ts) {
|
||||
sb.append(sep);
|
||||
sb.append(print(t));
|
||||
switch (t) {
|
||||
case Signature sig -> sb.append(print(sig));
|
||||
case Signature.TypeParam pSig -> sb.append(visitTypeParamType(pSig));
|
||||
case Signature.TypeArg aSig -> sb.append(visitWildcardType(aSig));
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
sep = ",";
|
||||
}
|
||||
sb.append(post);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitSimpleType(SimpleType type, Void p) {
|
||||
return "S{" + type.name + "}";
|
||||
public String visitSimpleType(Signature.BaseTypeSig type) {
|
||||
return "S{" + type.baseType() + "}";
|
||||
}
|
||||
|
||||
public String visitArrayType(ArrayType type, Void p) {
|
||||
return "A{" + print(type.elemType) + "}";
|
||||
public String visitArrayType(Signature.ArrayTypeSig type) {
|
||||
return "A{" + print(type.componentSignature()) + "}";
|
||||
}
|
||||
|
||||
public String visitMethodType(MethodType type, Void p) {
|
||||
public String visitMethodType(MethodSignature type) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("M{");
|
||||
if (type.typeParamTypes != null)
|
||||
sb.append(print("<", type.typeParamTypes, ">"));
|
||||
sb.append(print(type.returnType));
|
||||
sb.append(print("(", type.paramTypes, ")"));
|
||||
if (type.throwsTypes != null)
|
||||
sb.append(print("", type.throwsTypes, ""));
|
||||
if (!type.typeParameters().isEmpty())
|
||||
sb.append(print("<", type.typeParameters(), ">"));
|
||||
sb.append(print(type.result()));
|
||||
sb.append(print("(", type.arguments(), ")"));
|
||||
if (!type.throwableSignatures().isEmpty())
|
||||
sb.append(print("", type.throwableSignatures(), ""));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitClassSigType(ClassSigType type, Void p) {
|
||||
public String visitClassSigType(ClassSignature type) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CS{");
|
||||
if (type.typeParamTypes != null)
|
||||
sb.append(print("<", type.typeParamTypes, ">"));
|
||||
sb.append(print(type.superclassType));
|
||||
if (type.superinterfaceTypes != null)
|
||||
sb.append(print("i(", type.superinterfaceTypes, ")"));
|
||||
if (!type.typeParameters().isEmpty())
|
||||
sb.append(print("<", type.typeParameters(), ">"));
|
||||
sb.append(print(type.superclassSignature()));
|
||||
if (!type.superinterfaceSignatures().isEmpty())
|
||||
sb.append(print("i(", type.superinterfaceSignatures(), ")"));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitClassType(ClassType type, Void p) {
|
||||
public String visitClassType(Signature.ClassTypeSig type) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("C{");
|
||||
if (type.outerType != null) {
|
||||
sb.append(print(type.outerType));
|
||||
if (type.outerType().isPresent()) {
|
||||
sb.append(print(type.outerType().get()));
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(type.name);
|
||||
if (type.typeArgs != null)
|
||||
sb.append(print("<", type.typeArgs, ">"));
|
||||
sb.append(type.className());
|
||||
if (!type.typeArgs().isEmpty())
|
||||
sb.append(print("<", type.typeArgs(), ">"));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitTypeParamType(TypeParamType type, Void p) {
|
||||
public String visitTypeParamType(Signature.TypeParam type) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("TA{");
|
||||
sb.append(type.name);
|
||||
if (type.classBound != null) {
|
||||
sb.append(type.identifier());
|
||||
if (type.classBound().isPresent()) {
|
||||
sb.append(":c");
|
||||
sb.append(print(type.classBound));
|
||||
sb.append(print(type.classBound().get()));
|
||||
}
|
||||
if (type.interfaceBounds != null)
|
||||
sb.append(print(":i", type.interfaceBounds, ""));
|
||||
if (!type.interfaceBounds().isEmpty())
|
||||
sb.append(print(":i", type.interfaceBounds(), ""));
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String visitWildcardType(WildcardType type, Void p) {
|
||||
switch (type.kind) {
|
||||
case UNBOUNDED:
|
||||
public String visitWildcardType(Signature.TypeArg type) {
|
||||
switch (type.wildcardIndicator()) {
|
||||
case UNBOUNDED -> {
|
||||
return "W{?}";
|
||||
case EXTENDS:
|
||||
return "W{e," + print(type.boundType) + "}";
|
||||
case SUPER:
|
||||
return "W{s," + print(type.boundType) + "}";
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
case EXTENDS -> {
|
||||
return "W{e," + print(type.boundType().get()) + "}";
|
||||
}
|
||||
case SUPER -> {
|
||||
return "W{s," + print(type.boundType().get()) + "}";
|
||||
}
|
||||
default -> {
|
||||
if (type.boundType().isPresent()) return print(type.boundType().get());
|
||||
else throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,28 +354,28 @@ class GenClss<T> { }
|
||||
class Test {
|
||||
// fields
|
||||
|
||||
@Desc(d="Z", t="S{boolean}")
|
||||
@Desc(d="Z", t="S{Z}")
|
||||
boolean z;
|
||||
|
||||
@Desc(d="B", t="S{byte}")
|
||||
@Desc(d="B", t="S{B}")
|
||||
byte b;
|
||||
|
||||
@Desc(d="C", t="S{char}")
|
||||
@Desc(d="C", t="S{C}")
|
||||
char c;
|
||||
|
||||
@Desc(d="D", t="S{double}")
|
||||
@Desc(d="D", t="S{D}")
|
||||
double d;
|
||||
|
||||
@Desc(d="F", t="S{float}")
|
||||
@Desc(d="F", t="S{F}")
|
||||
float f;
|
||||
|
||||
@Desc(d="I", t="S{int}")
|
||||
@Desc(d="I", t="S{I}")
|
||||
int i;
|
||||
|
||||
@Desc(d="J", t="S{long}")
|
||||
@Desc(d="J", t="S{J}")
|
||||
long l;
|
||||
|
||||
@Desc(d="S", t="S{short}")
|
||||
@Desc(d="S", t="S{S}")
|
||||
short s;
|
||||
|
||||
@Desc(d="LClss;", t="C{Clss}")
|
||||
@ -347,7 +384,7 @@ class Test {
|
||||
@Desc(d="LIntf;", t="C{Intf}")
|
||||
Intf intf;
|
||||
|
||||
@Desc(d="[I", t="A{S{int}}")
|
||||
@Desc(d="[I", t="A{S{I}}")
|
||||
int[] ai;
|
||||
|
||||
@Desc(d="[LClss;", t="A{C{Clss}}")
|
||||
@ -359,16 +396,16 @@ class Test {
|
||||
|
||||
// methods, return types
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
@Desc(d="()V", t="M{S{V}()}")
|
||||
void mv0() { }
|
||||
|
||||
@Desc(d="()I", t="M{S{int}()}")
|
||||
@Desc(d="()I", t="M{S{I}()}")
|
||||
int mi0() { return 0; }
|
||||
|
||||
@Desc(d="()LClss;", t="M{C{Clss}()}")
|
||||
Clss mclss0() { return null; }
|
||||
|
||||
@Desc(d="()[I", t="M{A{S{int}}()}")
|
||||
@Desc(d="()[I", t="M{A{S{I}}()}")
|
||||
int[] mai0() { return null; }
|
||||
|
||||
@Desc(d="()[LClss;", t="M{A{C{Clss}}()}")
|
||||
@ -405,57 +442,57 @@ class Test {
|
||||
|
||||
// methods, arg types
|
||||
|
||||
@Desc(d="(I)V", t="M{S{void}(S{int})}")
|
||||
@Desc(d="(I)V", t="M{S{V}(S{I})}")
|
||||
void mi1(int arg) { }
|
||||
|
||||
@Desc(d="(LClss;)V", t="M{S{void}(C{Clss})}")
|
||||
@Desc(d="(LClss;)V", t="M{S{V}(C{Clss})}")
|
||||
void mclss1(Clss arg) { }
|
||||
|
||||
@Desc(d="([I)V", t="M{S{void}(A{S{int}})}")
|
||||
@Desc(d="([I)V", t="M{S{V}(A{S{I}})}")
|
||||
void mai1(int[] arg) { }
|
||||
|
||||
@Desc(d="([LClss;)V", t="M{S{void}(A{C{Clss}})}")
|
||||
@Desc(d="([LClss;)V", t="M{S{V}(A{C{Clss}})}")
|
||||
void maClss1(Clss[] arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<LClss;>;)V", t="M{S{void}(C{GenClss<C{Clss}>})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<LClss;>;)V", t="M{S{V}(C{GenClss<C{Clss}>})}")
|
||||
void mgenClss1(GenClss<Clss> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<*>;)V", t="M{S{void}(C{GenClss<W{?}>})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<*>;)V", t="M{S{V}(C{GenClss<W{?}>})}")
|
||||
void mgenClssW1(GenClss<?> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<+LClss;>;)V", t="M{S{void}(C{GenClss<W{e,C{Clss}}>})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<+LClss;>;)V", t="M{S{V}(C{GenClss<W{e,C{Clss}}>})}")
|
||||
void mgenClssWExtClss1(GenClss<? extends Clss> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<-LClss;>;)V", t="M{S{void}(C{GenClss<W{s,C{Clss}}>})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="(LGenClss<-LClss;>;)V", t="M{S{V}(C{GenClss<W{s,C{Clss}}>})}")
|
||||
void mgenClssWSupClss1(GenClss<? super Clss> arg) { }
|
||||
|
||||
@Desc(d="(Ljava/lang/Object;)V", t="M{S{void}(C{java/lang/Object})}")
|
||||
@Desc(d="(Ljava/lang/Object;)V", t="M{S{V}(C{java/lang/Object})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(TT;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(S{T})}")
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{V}(S{T})}")
|
||||
<T> void mt1(T arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(LGenClss<+TT;>;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{e,S{T}}>})}")
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{V}(C{GenClss<W{e,S{T}}>})}")
|
||||
<T> void mgenClssWExtT1(GenClss<? extends T> arg) { }
|
||||
|
||||
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
|
||||
@Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
|
||||
@Sig(s="<T:Ljava/lang/Object;>(LGenClss<-TT;>;)V",
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{s,S{T}}>})}")
|
||||
t="M{<TA{T:cC{java/lang/Object}}>S{V}(C{GenClss<W{s,S{T}}>})}")
|
||||
<T> void mgenClssWSupT1(GenClss<? super T> arg) { }
|
||||
|
||||
// methods, throws
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
@Desc(d="()V", t="M{S{V}()}")
|
||||
void m_E() throws Exception { }
|
||||
|
||||
@Desc(d="()V", t="M{S{void}()}")
|
||||
@Desc(d="()V", t="M{S{V}()}")
|
||||
@Sig(s="<T:Ljava/lang/Throwable;>()V^TT;",
|
||||
t="M{<TA{T:cC{java/lang/Throwable}}>S{void}()S{T}}")
|
||||
t="M{<TA{T:cC{java/lang/Throwable}}>S{V}()S{T}}")
|
||||
<T extends Throwable> void m_T() throws T { }
|
||||
|
||||
// inner classes
|
||||
|
@ -24,15 +24,20 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 6887895
|
||||
* @summary CONSTANT_Class_info getBaseName does not handle arrays of primitives correctly
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @summary test getting constantpool elements' basename through asInternalName() API
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.ConstantPool.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
|
||||
public class T6887895 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -42,23 +47,22 @@ public class T6887895 {
|
||||
void run() throws Exception {
|
||||
Set<String> found = new TreeSet<String>();
|
||||
|
||||
ClassFile cf = getClassFile("T6887895$Test.class");
|
||||
for (CPInfo cpInfo: cf.constant_pool.entries()) {
|
||||
if (cpInfo instanceof CONSTANT_Class_info) {
|
||||
CONSTANT_Class_info info = (CONSTANT_Class_info) cpInfo;
|
||||
String name = info.getName();
|
||||
String baseName = info.getBaseName();
|
||||
System.out.println("found: " + name + " " + baseName);
|
||||
if (baseName != null)
|
||||
found.add(baseName);
|
||||
ClassModel cm = getClassFile("T6887895$Test.class");
|
||||
ConstantPool cp = cm.constantPool();
|
||||
for (int i = 1; i < cp.entryCount(); ++i) {
|
||||
if (cp.entryByIndex(i) instanceof ClassEntry ce) {
|
||||
String name = ce.asInternalName();
|
||||
System.out.println("found: " + name);
|
||||
if (ce.asSymbol().isClassOrInterface())
|
||||
found.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
String[] expectNames = {
|
||||
"java/lang/Object",
|
||||
"java/lang/String",
|
||||
"T6887895",
|
||||
"T6887895$Test"
|
||||
"java/lang/Object",
|
||||
"java/lang/String",
|
||||
"T6887895",
|
||||
"T6887895$Test"
|
||||
};
|
||||
|
||||
Set<String> expect = new TreeSet<String>(Arrays.asList(expectNames));
|
||||
@ -69,14 +73,9 @@ public class T6887895 {
|
||||
}
|
||||
}
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
URL url = getClass().getResource(name);
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
ClassModel getClassFile(String name) throws IOException, URISyntaxException {
|
||||
URL rsc = getClass().getResource(name);
|
||||
return Classfile.of().parse(Paths.get(rsc.toURI()));
|
||||
}
|
||||
|
||||
class Test {
|
||||
|
@ -22,13 +22,19 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.Attributes;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test JSR175Annotations
|
||||
* @bug 6843077
|
||||
* @summary test that only type annotations are recorded as such in classfile
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class JSR175Annotations {
|
||||
@ -40,12 +46,12 @@ public class JSR175Annotations {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
for (FieldModel fm: cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -55,45 +61,26 @@ public class JSR175Annotations {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(AttributedElement m) {
|
||||
test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Field m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
// test the result of AttributedElement.findAttribute according to expectations
|
||||
<T extends jdk.internal.classfile.Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,17 +22,21 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test NewArray
|
||||
* @bug 6843077
|
||||
* @summary Test type annotations on local array are in method's code attribute.
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class NewArray {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NewArray().run();
|
||||
}
|
||||
@ -41,51 +45,48 @@ public class NewArray {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(MethodModel mm) {
|
||||
test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(mm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
RuntimeTypeAnnotations_attribute tAttr = null;
|
||||
<T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr_instance;
|
||||
CodeAttribute cAttr;
|
||||
|
||||
int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = m.attributes.get(index);
|
||||
assert attr instanceof Code_attribute;
|
||||
cAttr = (Code_attribute)attr;
|
||||
index = cAttr.attributes.getIndex(cf.constant_pool, name);
|
||||
if(index!= -1) {
|
||||
attr = cAttr.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
|
||||
if (cAttr != null) {
|
||||
attr_instance = cAttr.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("import java.lang.annotation.*;");
|
||||
out.println("import java.util.*;");
|
||||
@ -133,7 +134,6 @@ public class NewArray {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int errors;
|
||||
int all;
|
||||
int visibles;
|
||||
|
@ -23,14 +23,18 @@
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test Presence
|
||||
* @bug 6843077
|
||||
* @summary test that all type annotations are present in the classfile
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class Presence {
|
||||
@ -42,13 +46,13 @@ public class Presence {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -58,91 +62,50 @@ public class Presence {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf) {
|
||||
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(AttributedElement m) {
|
||||
test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, String name, boolean visible) {
|
||||
int index = cf.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = cf.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
// test the result of AttributedElement.findAttribute according to expectations
|
||||
<T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
|
||||
Object attr_instance = m.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
if (m instanceof MethodModel) {
|
||||
attr_instance = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
if(attr_instance!= null) {
|
||||
CodeAttribute cAttr = (CodeAttribute)attr_instance;
|
||||
attr_instance = cAttr.findAttribute(attr_name).orElse(null);
|
||||
if(attr_instance!= null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
RuntimeTypeAnnotations_attribute tAttr = null;
|
||||
|
||||
// collect annotations attributes on method
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
// collect annotations from method's code attribute
|
||||
index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = m.attributes.get(index);
|
||||
assert attr instanceof Code_attribute;
|
||||
cAttr = (Code_attribute)attr;
|
||||
index = cAttr.attributes.getIndex(cf.constant_pool, name);
|
||||
if(index!= -1) {
|
||||
attr = cAttr.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Field m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("TestPresence.java");
|
||||
|
@ -22,13 +22,18 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test PresenceInner
|
||||
* @bug 6843077
|
||||
* @summary test that annotations in inner types count only once
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class PresenceInner {
|
||||
@ -40,13 +45,13 @@ public class PresenceInner {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
// counts are zero when vising outer class
|
||||
@ -54,13 +59,13 @@ public class PresenceInner {
|
||||
|
||||
// visit inner class
|
||||
File innerFile = new File("Test$1Inner.class");
|
||||
ClassFile icf = ClassFile.read(innerFile);
|
||||
test(icf);
|
||||
for (Field f : icf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel icm = Classfile.of().parse(innerFile.toPath());
|
||||
test(icm);
|
||||
for (FieldModel fm : icm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: icf.methods) {
|
||||
test(cf, m);
|
||||
for (MethodModel mm: icm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations(1);
|
||||
@ -69,66 +74,26 @@ public class PresenceInner {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf) {
|
||||
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(AttributedElement m) {
|
||||
test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, String name, boolean visible) {
|
||||
int index = cf.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = cf.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Field m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
// test the result of AttributedElement.findAttribute according to expectations
|
||||
<T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,15 +21,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077
|
||||
* @summary test that typecasts annotation are emitted if only the cast
|
||||
* expression is optimized away
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class TypeCasts {
|
||||
@ -41,9 +46,9 @@ public class TypeCasts {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -53,34 +58,34 @@ public class TypeCasts {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(MethodModel mm) {
|
||||
test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(mm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// test the result of MethodModel.findAttribute according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
<T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr;
|
||||
CodeAttribute cAttr;
|
||||
|
||||
int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = m.attributes.get(index);
|
||||
assert attr instanceof Code_attribute;
|
||||
cAttr = (Code_attribute)attr;
|
||||
index = cAttr.attributes.getIndex(cf.constant_pool, name);
|
||||
if(index!= -1) {
|
||||
attr = cAttr.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
|
||||
if (cAttr != null) {
|
||||
attr = cAttr.findAttribute(attr_name).orElse(null);
|
||||
if (attr != null) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,13 +22,19 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.Attributes;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test Visibility
|
||||
* @bug 6843077
|
||||
* @summary test that type annotations are recorded in the classfile
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class Visibility {
|
||||
@ -40,9 +46,9 @@ public class Visibility {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -52,24 +58,27 @@ public class Visibility {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(MethodModel mm) {
|
||||
test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(mm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// test the result of mm.findAttribute according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
<T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr_instance = mm.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +118,7 @@ public class Visibility {
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] {"-g", f.getPath() });
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] {"-g", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
|
@ -22,13 +22,18 @@
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test Wildcards
|
||||
* @bug 6843077
|
||||
* @summary test that annotations target wildcards get emitted to classfile
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
public class Wildcards {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -39,13 +44,13 @@ public class Wildcards {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -54,72 +59,28 @@ public class Wildcards {
|
||||
throw new Exception(errors + " errors found");
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
void test(ClassFile cf) {
|
||||
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
void test(AttributedElement m) {
|
||||
test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, String name, boolean visible) {
|
||||
int index = cf.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = cf.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
<T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
|
||||
Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
|
||||
if (attr_instance != null) {
|
||||
switch (attr_instance) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
visibles += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
all += tAttr.annotations().size();
|
||||
invisibles += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Field m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("import java.lang.annotation.*;");
|
||||
out.println("import java.util.*;");
|
||||
|
Loading…
x
Reference in New Issue
Block a user