8295059: test/langtools/tools/javap 12 test classes use com.sun.tools.classfile library

Reviewed-by: asotona
This commit is contained in:
Qing Xiao 2023-07-31 15:03:05 +00:00 committed by Adam Sotona
parent 3671d83c87
commit 97b688340e
11 changed files with 520 additions and 588 deletions

View File

@ -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);
}
}

View File

@ -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 {
}
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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();

View File

@ -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.*;");