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 * @test 6716452
* @summary need a method to get an index of an attribute * @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 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 class T6716452 {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -38,49 +45,44 @@ public class T6716452 {
public void run() throws Exception { public void run() throws Exception {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassModel cm = Classfile.of().parse(classFile.toPath());
ClassFile cf = ClassFile.read(classFile); for (MethodModel mm: cm.methods()) {
for (Method m: cf.methods) { test(mm);
test(cf, m);
} }
if (errors > 0) if (errors > 0)
throw new Exception(errors + " errors found"); throw new Exception(errors + " errors found");
} }
void test(ClassFile cf, Method m) { void test(MethodModel mm) {
test(cf, m, Attribute.Code, Code_attribute.class); test(mm, Attributes.CODE, CodeAttribute.class);
test(cf, m, Attribute.Exceptions, Exceptions_attribute.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 // encoded in the method's name
void test(ClassFile cf, Method m, String name, Class<?> c) { <T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr, Class<?> c) {
int index = m.attributes.getIndex(cf.constant_pool, name); Attribute<T> attr_instance = mm.findAttribute(attr).orElse(null);
try { int index = mm.attributes().indexOf(attr_instance);
String m_name = m.getName(cf.constant_pool); String mm_name = mm.methodName().stringValue();
System.err.println("Method " + m_name + " name:" + name + " index:" + index + " class: " + c); System.err.println("Method " + mm_name + " name:" + attr.name() + " index:" + index + " class: " + c);
boolean expect = (m_name.equals("<init>") && name.equals("Code")) boolean expect = (mm_name.equals("<init>") && attr.name().equals("Code"))
|| (m_name.indexOf(name) != -1); || (mm_name.contains(attr.name()));
boolean found = (index != -1); boolean found = (index != -1);
if (expect) { if (expect) {
if (found) { if (found) {
Attribute attr = m.attributes.get(index); if (!c.isAssignableFrom(mm.attributes().get(index).getClass())) {
if (!c.isAssignableFrom(attr.getClass())) { error(mm + ": unexpected attribute found,"
error(m + ": unexpected attribute found," + " expected " + c.getName()
+ " expected " + c.getName() + " found " + mm.attributes().get(index).attributeName());
+ " found " + attr.getClass().getName());
}
} else {
error(m + ": expected attribute " + name + " not found");
} }
} else { } else {
if (found) { error(mm + ": expected attribute " + attr.name() + " not found");
error(m + ": unexpected attribute " + name); }
} } else {
if (found) {
error(mm + ": unexpected attribute " + attr.name());
} }
} catch (ConstantPoolException e) {
error(m + ": " + e);
} }
} }

View File

@ -29,12 +29,17 @@
* @modules * @modules
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile
* jdk.jdeps/com.sun.tools.javap * 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 * @build toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox toolbox.TestRunner
* @run main TestClassNameWarning * @run main TestClassNameWarning
*/ */
import java.lang.constant.ClassDesc;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -43,9 +48,8 @@ import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; 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.JavacTask;
import toolbox.JavapTask; import toolbox.JavapTask;
import toolbox.Task; import toolbox.Task;
@ -140,7 +144,7 @@ public class TestClassNameWarning extends TestRunner {
byte[] replaceBytes = "module-info".getBytes("UTF-8"); byte[] replaceBytes = "module-info".getBytes("UTF-8");
for (int i = 0; i < bytes.length - searchBytes.length; i++) { for (int i = 0; i < bytes.length - searchBytes.length; i++) {
if (Arrays.equals(bytes, i, i + searchBytes.length, if (Arrays.equals(bytes, i, i + searchBytes.length,
searchBytes, 0, searchBytes.length)) { searchBytes, 0, searchBytes.length)) {
System.arraycopy(replaceBytes, 0, bytes, i, replaceBytes.length); System.arraycopy(replaceBytes, 0, bytes, i, replaceBytes.length);
} }
} }
@ -172,14 +176,15 @@ public class TestClassNameWarning extends TestRunner {
.files(tb.findJavaFiles(src)) .files(tb.findJavaFiles(src))
.run() .run()
.writeAll(); .writeAll();
ClassModel cm = Classfile.of().parse(classes.resolve("A.class"));
ClassFile cf = ClassFile.read(classes.resolve("A.class")); Classfile.of().buildTo(
ClassFile cf2 = new ClassFile( classes.resolve("Z.class"),
cf.magic, cf.minor_version, cf.major_version, cf.constant_pool, ClassDesc.of("0"), cb -> {
cf.access_flags, for (ClassElement ce : cm) {
0, // this_class, cb.with(ce);
cf.super_class, cf.interfaces, cf.fields, cf.methods, cf.attributes); }
new ClassWriter().write(cf2, Files.newOutputStream(classes.resolve("Z.class"))); }
);
List<String> log = new JavapTask(tb) List<String> log = new JavapTask(tb)
.classpath(classes.toString()) .classpath(classes.toString())
@ -238,4 +243,3 @@ public class TestClassNameWarning extends TestRunner {
} }
} }
} }

View File

@ -24,21 +24,23 @@
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.lang.constant.*;
import java.nio.file.Paths;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Type.ArrayType; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.Type.ClassSigType; import jdk.internal.classfile.constantpool.*;
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;
/* /*
* @test * @test
* @bug 6888367 * @bug 6888367
* @summary classfile library parses signature attributes incorrectly * @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 { public void run() throws Exception {
ClassFile cf = getClassFile("Test"); ClassModel cm = getClassFile("Test");
testFields(cf); testFields(cm);
testMethods(cf); testMethods(cm);
testInnerClasses(cf); // recursive testInnerClasses(cm); // recursive
if (errors > 0) if (errors > 0)
throw new Exception(errors + " errors found"); throw new Exception(errors + " errors found");
} }
void testFields(ClassFile cf) throws Exception { void testFields(ClassModel cm) throws Exception {
String cn = cf.getName(); String cn = cm.thisClass().name().stringValue();
ConstantPool cp = cf.constant_pool; for (FieldModel fm: cm.fields()) {
for (Field f: cf.fields) { test("field " + cn + "." + fm.fieldName(), fm.fieldTypeSymbol(), fm);
test("field " + cn + "." + f.getName(cp), f.descriptor, f.attributes, cp);
} }
} }
void testMethods(ClassFile cf) throws Exception { void testMethods(ClassModel cm) throws Exception {
String cn = cf.getName(); String cn = cm.thisClass().name().stringValue();
ConstantPool cp = cf.constant_pool; for (MethodModel mm: cm.methods()) {
for (Method m: cf.methods) { test("method " + cn + "." + mm.methodName(), mm.methodTypeSymbol(), mm);
test("method " + cn + "." + m.getName(cp), m.descriptor, m.attributes, cp);
} }
} }
void testInnerClasses(ClassFile cf) throws Exception { void testInnerClasses(ClassModel cm) throws Exception {
ConstantPool cp = cf.constant_pool; InnerClassesAttribute ic =
InnerClasses_attribute ic = cm.findAttribute(Attributes.INNER_CLASSES).orElse(null);
(InnerClasses_attribute) cf.attributes.get(Attribute.InnerClasses); assert ic != null;
for (InnerClasses_attribute.Info info: ic.classes) { for (InnerClassInfo info: ic.classes()) {
String outerClassName = cp.getClassInfo(info.outer_class_info_index).getName(); ClassEntry outerClass = info.outerClass().orElse(null);
if (!outerClassName.equals(cf.getName())) { if (outerClass == null || !outerClass.name().equalsString(cm.getClass().getName())) {
continue; continue;
} }
String innerClassName = cp.getClassInfo(info.inner_class_info_index).getName(); String innerClassName = info.innerClass().asInternalName();
ClassFile icf = getClassFile(innerClassName); ClassModel icm = getClassFile(innerClassName);
test("class " + innerClassName, null, icf.attributes, icf.constant_pool); test("class " + innerClassName, null, icm);
testInnerClasses(icf); testInnerClasses(icm);
} }
} }
void test(String name, Descriptor desc, Attributes attrs, ConstantPool cp) void test(String name, ConstantDesc desc, AttributedElement m) {
throws Exception { AnnotValues d = getDescValue(m);
AnnotValues d = getDescValue(attrs, cp); AnnotValues s = getSigValue(m);
AnnotValues s = getSigValue(attrs, cp);
if (d == null && s == null) // not a test field or method if no @Desc or @Sig given if (d == null && s == null) // not a test field or method if no @Desc or @Sig given
return; return;
System.err.println(name); System.err.println(name);
SignatureAttribute sa = m.findAttribute(Attributes.SIGNATURE).orElse(null);
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);
if (sa != null) if (sa != null)
System.err.println(" signature: " + sa.getSignature(cp)); System.err.println(" signature: " + sa.signature());
if (s != null || sa != null) { switch (desc) {
if (s != null && sa != null) { case ClassDesc cDesc -> {
checkEqual(s.raw, sa.getSignature(cp)); System.err.println(" descriptor: " + cDesc.descriptorString());
Type st = new Signature(sa.signature_index).getType(cp); checkEqual(d.raw, cDesc.descriptorString());
checkEqual(s.type, tp.print(st)); Signature dt = Signature.of(cDesc);
} else if (s != null) checkEqual(d.type, tp.print(dt));
error("@Sig annotation found but not Signature attribute"); if (s != null || sa != null) {
else if (s != null && sa != null) {
error("Signature attribute found but no @Sig annotation"); 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(); System.err.println();
} }
ClassFile getClassFile(String name) throws IOException, ConstantPoolException { ClassModel getClassFile(String name) throws IOException, URISyntaxException {
URL url = getClass().getResource(name + ".class"); URL rsc = getClass().getResource(name + ".class");
InputStream in = url.openStream(); assert rsc != null;
try { return Classfile.of().parse(Paths.get(rsc.toURI()));
return ClassFile.read(in);
} finally {
in.close();
}
} }
AnnotValues getDescValue(Attributes attrs, ConstantPool cp) throws Exception { AnnotValues getDescValue(AttributedElement m) {
return getAnnotValues(Desc.class.getName(), attrs, cp); return getAnnotValues(Desc.class.getName(), m);
} }
AnnotValues getSigValue(Attributes attrs, ConstantPool cp) throws Exception { AnnotValues getSigValue(AttributedElement m) {
return getAnnotValues(Sig.class.getName(), attrs, cp); return getAnnotValues(Sig.class.getName(), m);
} }
static class AnnotValues { static class AnnotValues {
@ -165,20 +176,14 @@ public class T6888367 {
final String type; final String type;
} }
AnnotValues getAnnotValues(String annotName, Attributes attrs, ConstantPool cp) AnnotValues getAnnotValues(String annotName, AttributedElement m) {
throws Exception { RuntimeInvisibleAnnotationsAttribute annots = m.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null);
RuntimeInvisibleAnnotations_attribute annots =
(RuntimeInvisibleAnnotations_attribute)attrs.get(Attribute.RuntimeInvisibleAnnotations);
if (annots != null) { if (annots != null) {
for (Annotation a: annots.annotations) { for (Annotation a: annots.annotations()) {
if (cp.getUTF8Value(a.type_index).equals("L" + annotName + ";")) { if (a.classSymbol().descriptorString().equals("L" + annotName + ";")) {
Annotation.Primitive_element_value pv0 = String pv0 = ((AnnotationValue.OfString) a.elements().get(0).value()).stringValue();
(Annotation.Primitive_element_value) a.element_value_pairs[0].value; String pv1 = ((AnnotationValue.OfString) a.elements().get(1).value()).stringValue();
Annotation.Primitive_element_value pv1 = return new AnnotValues(pv0, 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));
} }
} }
} }
@ -187,7 +192,7 @@ public class T6888367 {
} }
void checkEqual(String expect, String found) { 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("expected: " + expect);
System.err.println(" found: " + found); System.err.println(" found: " + found);
error("unexpected values found"); error("unexpected values found");
@ -203,96 +208,128 @@ public class T6888367 {
TypePrinter tp = new TypePrinter(); TypePrinter tp = new TypePrinter();
class TypePrinter implements Type.Visitor<String,Void> { class TypePrinter {
String print(Type t) { <T> String print(T t) {
return t == null ? null : t.accept(this, null); 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) if (ts == null)
return null; return null;
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(pre); sb.append(pre);
String sep = ""; String sep = "";
for (Type t: ts) { for (T t: ts) {
sb.append(sep); 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 = ","; sep = ",";
} }
sb.append(post); sb.append(post);
return sb.toString(); return sb.toString();
} }
public String visitSimpleType(SimpleType type, Void p) { public String visitSimpleType(Signature.BaseTypeSig type) {
return "S{" + type.name + "}"; return "S{" + type.baseType() + "}";
} }
public String visitArrayType(ArrayType type, Void p) { public String visitArrayType(Signature.ArrayTypeSig type) {
return "A{" + print(type.elemType) + "}"; return "A{" + print(type.componentSignature()) + "}";
} }
public String visitMethodType(MethodType type, Void p) { public String visitMethodType(MethodSignature type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("M{"); sb.append("M{");
if (type.typeParamTypes != null) if (!type.typeParameters().isEmpty())
sb.append(print("<", type.typeParamTypes, ">")); sb.append(print("<", type.typeParameters(), ">"));
sb.append(print(type.returnType)); sb.append(print(type.result()));
sb.append(print("(", type.paramTypes, ")")); sb.append(print("(", type.arguments(), ")"));
if (type.throwsTypes != null) if (!type.throwableSignatures().isEmpty())
sb.append(print("", type.throwsTypes, "")); sb.append(print("", type.throwableSignatures(), ""));
sb.append("}"); sb.append("}");
return sb.toString(); return sb.toString();
} }
public String visitClassSigType(ClassSigType type, Void p) { public String visitClassSigType(ClassSignature type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("CS{"); sb.append("CS{");
if (type.typeParamTypes != null) if (!type.typeParameters().isEmpty())
sb.append(print("<", type.typeParamTypes, ">")); sb.append(print("<", type.typeParameters(), ">"));
sb.append(print(type.superclassType)); sb.append(print(type.superclassSignature()));
if (type.superinterfaceTypes != null) if (!type.superinterfaceSignatures().isEmpty())
sb.append(print("i(", type.superinterfaceTypes, ")")); sb.append(print("i(", type.superinterfaceSignatures(), ")"));
sb.append("}"); sb.append("}");
return sb.toString(); return sb.toString();
} }
public String visitClassType(ClassType type, Void p) { public String visitClassType(Signature.ClassTypeSig type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("C{"); sb.append("C{");
if (type.outerType != null) { if (type.outerType().isPresent()) {
sb.append(print(type.outerType)); sb.append(print(type.outerType().get()));
sb.append("."); sb.append(".");
} }
sb.append(type.name); sb.append(type.className());
if (type.typeArgs != null) if (!type.typeArgs().isEmpty())
sb.append(print("<", type.typeArgs, ">")); sb.append(print("<", type.typeArgs(), ">"));
sb.append("}"); sb.append("}");
return sb.toString(); return sb.toString();
} }
public String visitTypeParamType(TypeParamType type, Void p) { public String visitTypeParamType(Signature.TypeParam type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("TA{"); sb.append("TA{");
sb.append(type.name); sb.append(type.identifier());
if (type.classBound != null) { if (type.classBound().isPresent()) {
sb.append(":c"); sb.append(":c");
sb.append(print(type.classBound)); sb.append(print(type.classBound().get()));
} }
if (type.interfaceBounds != null) if (!type.interfaceBounds().isEmpty())
sb.append(print(":i", type.interfaceBounds, "")); sb.append(print(":i", type.interfaceBounds(), ""));
sb.append("}"); sb.append("}");
return sb.toString(); return sb.toString();
} }
public String visitWildcardType(WildcardType type, Void p) { public String visitWildcardType(Signature.TypeArg type) {
switch (type.kind) { switch (type.wildcardIndicator()) {
case UNBOUNDED: case UNBOUNDED -> {
return "W{?}"; return "W{?}";
case EXTENDS: }
return "W{e," + print(type.boundType) + "}"; case EXTENDS -> {
case SUPER: return "W{e," + print(type.boundType().get()) + "}";
return "W{s," + print(type.boundType) + "}"; }
default: case SUPER -> {
throw new AssertionError(); 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 { class Test {
// fields // fields
@Desc(d="Z", t="S{boolean}") @Desc(d="Z", t="S{Z}")
boolean z; boolean z;
@Desc(d="B", t="S{byte}") @Desc(d="B", t="S{B}")
byte b; byte b;
@Desc(d="C", t="S{char}") @Desc(d="C", t="S{C}")
char c; char c;
@Desc(d="D", t="S{double}") @Desc(d="D", t="S{D}")
double d; double d;
@Desc(d="F", t="S{float}") @Desc(d="F", t="S{F}")
float f; float f;
@Desc(d="I", t="S{int}") @Desc(d="I", t="S{I}")
int i; int i;
@Desc(d="J", t="S{long}") @Desc(d="J", t="S{J}")
long l; long l;
@Desc(d="S", t="S{short}") @Desc(d="S", t="S{S}")
short s; short s;
@Desc(d="LClss;", t="C{Clss}") @Desc(d="LClss;", t="C{Clss}")
@ -347,7 +384,7 @@ class Test {
@Desc(d="LIntf;", t="C{Intf}") @Desc(d="LIntf;", t="C{Intf}")
Intf intf; Intf intf;
@Desc(d="[I", t="A{S{int}}") @Desc(d="[I", t="A{S{I}}")
int[] ai; int[] ai;
@Desc(d="[LClss;", t="A{C{Clss}}") @Desc(d="[LClss;", t="A{C{Clss}}")
@ -359,16 +396,16 @@ class Test {
// methods, return types // methods, return types
@Desc(d="()V", t="M{S{void}()}") @Desc(d="()V", t="M{S{V}()}")
void mv0() { } void mv0() { }
@Desc(d="()I", t="M{S{int}()}") @Desc(d="()I", t="M{S{I}()}")
int mi0() { return 0; } int mi0() { return 0; }
@Desc(d="()LClss;", t="M{C{Clss}()}") @Desc(d="()LClss;", t="M{C{Clss}()}")
Clss mclss0() { return null; } Clss mclss0() { return null; }
@Desc(d="()[I", t="M{A{S{int}}()}") @Desc(d="()[I", t="M{A{S{I}}()}")
int[] mai0() { return null; } int[] mai0() { return null; }
@Desc(d="()[LClss;", t="M{A{C{Clss}}()}") @Desc(d="()[LClss;", t="M{A{C{Clss}}()}")
@ -405,57 +442,57 @@ class Test {
// methods, arg types // 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) { } 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) { } 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) { } 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) { } void maClss1(Clss[] arg) { }
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") @Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
@Sig(s="(LGenClss<LClss;>;)V", t="M{S{void}(C{GenClss<C{Clss}>})}") @Sig(s="(LGenClss<LClss;>;)V", t="M{S{V}(C{GenClss<C{Clss}>})}")
void mgenClss1(GenClss<Clss> arg) { } void mgenClss1(GenClss<Clss> arg) { }
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") @Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
@Sig(s="(LGenClss<*>;)V", t="M{S{void}(C{GenClss<W{?}>})}") @Sig(s="(LGenClss<*>;)V", t="M{S{V}(C{GenClss<W{?}>})}")
void mgenClssW1(GenClss<?> arg) { } void mgenClssW1(GenClss<?> arg) { }
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") @Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
@Sig(s="(LGenClss<+LClss;>;)V", t="M{S{void}(C{GenClss<W{e,C{Clss}}>})}") @Sig(s="(LGenClss<+LClss;>;)V", t="M{S{V}(C{GenClss<W{e,C{Clss}}>})}")
void mgenClssWExtClss1(GenClss<? extends Clss> arg) { } void mgenClssWExtClss1(GenClss<? extends Clss> arg) { }
@Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}") @Desc(d="(LGenClss;)V", t="M{S{V}(C{GenClss})}")
@Sig(s="(LGenClss<-LClss;>;)V", t="M{S{void}(C{GenClss<W{s,C{Clss}}>})}") @Sig(s="(LGenClss<-LClss;>;)V", t="M{S{V}(C{GenClss<W{s,C{Clss}}>})}")
void mgenClssWSupClss1(GenClss<? super Clss> arg) { } 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", @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) { } <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", @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) { } <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", @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) { } <T> void mgenClssWSupT1(GenClss<? super T> arg) { }
// methods, throws // methods, throws
@Desc(d="()V", t="M{S{void}()}") @Desc(d="()V", t="M{S{V}()}")
void m_E() throws Exception { } 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;", @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 { } <T extends Throwable> void m_T() throws T { }
// inner classes // inner classes

View File

@ -24,15 +24,20 @@
/* /*
* @test * @test
* @bug 6887895 * @bug 6887895
* @summary CONSTANT_Class_info getBaseName does not handle arrays of primitives correctly * @summary test getting constantpool elements' basename through asInternalName() API
* @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 java.io.*;
import java.net.*; import java.net.*;
import java.nio.file.Paths;
import java.util.*; import java.util.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.*; import jdk.internal.classfile.constantpool.*;
public class T6887895 { public class T6887895 {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -42,23 +47,22 @@ public class T6887895 {
void run() throws Exception { void run() throws Exception {
Set<String> found = new TreeSet<String>(); Set<String> found = new TreeSet<String>();
ClassFile cf = getClassFile("T6887895$Test.class"); ClassModel cm = getClassFile("T6887895$Test.class");
for (CPInfo cpInfo: cf.constant_pool.entries()) { ConstantPool cp = cm.constantPool();
if (cpInfo instanceof CONSTANT_Class_info) { for (int i = 1; i < cp.entryCount(); ++i) {
CONSTANT_Class_info info = (CONSTANT_Class_info) cpInfo; if (cp.entryByIndex(i) instanceof ClassEntry ce) {
String name = info.getName(); String name = ce.asInternalName();
String baseName = info.getBaseName(); System.out.println("found: " + name);
System.out.println("found: " + name + " " + baseName); if (ce.asSymbol().isClassOrInterface())
if (baseName != null) found.add(name);
found.add(baseName);
} }
} }
String[] expectNames = { String[] expectNames = {
"java/lang/Object", "java/lang/Object",
"java/lang/String", "java/lang/String",
"T6887895", "T6887895",
"T6887895$Test" "T6887895$Test"
}; };
Set<String> expect = new TreeSet<String>(Arrays.asList(expectNames)); Set<String> expect = new TreeSet<String>(Arrays.asList(expectNames));
@ -69,14 +73,9 @@ public class T6887895 {
} }
} }
ClassFile getClassFile(String name) throws IOException, ConstantPoolException { ClassModel getClassFile(String name) throws IOException, URISyntaxException {
URL url = getClass().getResource(name); URL rsc = getClass().getResource(name);
InputStream in = url.openStream(); return Classfile.of().parse(Paths.get(rsc.toURI()));
try {
return ClassFile.read(in);
} finally {
in.close();
}
} }
class Test { class Test {

View File

@ -22,13 +22,19 @@
*/ */
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.Attributes;
import jdk.internal.classfile.attribute.*;
/* /*
* @test JSR175Annotations * @test JSR175Annotations
* @bug 6843077 * @bug 6843077
* @summary test that only type annotations are recorded as such in classfile * @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 { public class JSR175Annotations {
@ -40,12 +46,12 @@ public class JSR175Annotations {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
for (Field f : cf.fields) { for (MethodModel mm: cm.methods()) {
test(cf, f); test(mm);
} }
for (Method m: cf.methods) { for (FieldModel fm: cm.fields()) {
test(cf, m); test(fm);
} }
countAnnotations(); countAnnotations();
@ -55,45 +61,26 @@ public class JSR175Annotations {
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf, Method m) { void test(AttributedElement m) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
} }
void test(ClassFile cf, Field m) { // test the result of AttributedElement.findAttribute according to expectations
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); <T extends jdk.internal.classfile.Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
} if (attr_instance != null) {
switch (attr_instance) {
// test the result of Attributes.getIndex according to expectations case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
// encoded in the method's name all += tAttr.annotations().size();
void test(ClassFile cf, Method m, String name, boolean visible) { visibles += tAttr.annotations().size();
int index = m.attributes.getIndex(cf.constant_pool, name); }
if (index != -1) { case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
Attribute attr = m.attributes.get(index); all += tAttr.annotations().size();
assert attr instanceof RuntimeTypeAnnotations_attribute; invisibles += tAttr.annotations().size();
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; }
all += tAttr.annotations.length; default -> throw new AssertionError();
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;
} }
} }

View File

@ -22,17 +22,21 @@
*/ */
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
/* /*
* @test NewArray * @test NewArray
* @bug 6843077 * @bug 6843077
* @summary Test type annotations on local array are in method's code attribute. * @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 class NewArray {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new NewArray().run(); new NewArray().run();
} }
@ -41,51 +45,48 @@ public class NewArray {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(); countAnnotations();
if (errors > 0) if (errors > 0)
throw new Exception(errors + " errors found"); throw new Exception(errors + " errors found");
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf, Method m) { void test(MethodModel mm) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); test(mm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
} }
// test the result of Attributes.getIndex according to expectations // test the result of Attributes.getIndex according to expectations
// encoded in the method's name // encoded in the method's name
void test(ClassFile cf, Method m, String name, boolean visible) { <T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
Attribute attr = null; Attribute<T> attr_instance;
Code_attribute cAttr = null; CodeAttribute cAttr;
RuntimeTypeAnnotations_attribute tAttr = null;
int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code); cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
if(index!= -1) { if (cAttr != null) {
attr = m.attributes.get(index); attr_instance = cAttr.findAttribute(attr_name).orElse(null);
assert attr instanceof Code_attribute; if (attr_instance != null) {
cAttr = (Code_attribute)attr; switch (attr_instance) {
index = cAttr.attributes.getIndex(cf.constant_pool, name); case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
if(index!= -1) { all += tAttr.annotations().size();
attr = cAttr.attributes.get(index); visibles += tAttr.annotations().size();
assert attr instanceof RuntimeTypeAnnotations_attribute; }
tAttr = (RuntimeTypeAnnotations_attribute)attr; case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
all += tAttr.annotations.length; all += tAttr.annotations().size();
if (visible) invisibles += tAttr.annotations().size();
visibles += tAttr.annotations.length; }
else default -> throw new AssertionError();
invisibles += tAttr.annotations.length; }
} }
} }
} }
File writeTestFile() throws IOException { 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))); PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("import java.lang.annotation.*;"); out.println("import java.lang.annotation.*;");
out.println("import java.util.*;"); out.println("import java.util.*;");
@ -133,7 +134,6 @@ public class NewArray {
} }
} }
int errors; int errors;
int all; int all;
int visibles; int visibles;

View File

@ -23,14 +23,18 @@
import java.io.*; import java.io.*;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import jdk.internal.classfile.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.attribute.*;
/* /*
* @test Presence * @test Presence
* @bug 6843077 * @bug 6843077
* @summary test that all type annotations are present in the classfile * @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 { public class Presence {
@ -42,13 +46,13 @@ public class Presence {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
test(cf); test(cm);
for (Field f : cf.fields) { for (FieldModel fm : cm.fields()) {
test(cf, f); test(fm);
} }
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(); countAnnotations();
@ -58,91 +62,50 @@ public class Presence {
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf) { void test(AttributedElement m) {
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
} }
void test(ClassFile cf, Method m) { // test the result of AttributedElement.findAttribute according to expectations
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); <T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); Object attr_instance = m.findAttribute(attr_name).orElse(null);
} if (attr_instance != null) {
switch (attr_instance) {
void test(ClassFile cf, Field m) { case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); all += tAttr.annotations().size();
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); visibles += tAttr.annotations().size();
} }
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
// test the result of Attributes.getIndex according to expectations all += tAttr.annotations().size();
// encoded in the method's name invisibles += tAttr.annotations().size();
void test(ClassFile cf, String name, boolean visible) { }
int index = cf.attributes.getIndex(cf.constant_pool, name); default -> throw new AssertionError();
if (index != -1) { }
Attribute attr = cf.attributes.get(index); }
assert attr instanceof RuntimeTypeAnnotations_attribute; if (m instanceof MethodModel) {
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; attr_instance = m.findAttribute(Attributes.CODE).orElse(null);
all += tAttr.annotations.length; if(attr_instance!= null) {
if (visible) CodeAttribute cAttr = (CodeAttribute)attr_instance;
visibles += tAttr.annotations.length; attr_instance = cAttr.findAttribute(attr_name).orElse(null);
else if(attr_instance!= null) {
invisibles += tAttr.annotations.length; 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 writeTestFile() throws IOException {
File f = new File("TestPresence.java"); File f = new File("TestPresence.java");

View File

@ -22,13 +22,18 @@
*/ */
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
/* /*
* @test PresenceInner * @test PresenceInner
* @bug 6843077 * @bug 6843077
* @summary test that annotations in inner types count only once * @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 { public class PresenceInner {
@ -40,13 +45,13 @@ public class PresenceInner {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
test(cf); test(cm);
for (Field f : cf.fields) { for (FieldModel fm : cm.fields()) {
test(cf, f); test(fm);
} }
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
// counts are zero when vising outer class // counts are zero when vising outer class
@ -54,13 +59,13 @@ public class PresenceInner {
// visit inner class // visit inner class
File innerFile = new File("Test$1Inner.class"); File innerFile = new File("Test$1Inner.class");
ClassFile icf = ClassFile.read(innerFile); ClassModel icm = Classfile.of().parse(innerFile.toPath());
test(icf); test(icm);
for (Field f : icf.fields) { for (FieldModel fm : icm.fields()) {
test(cf, f); test(fm);
} }
for (Method m: icf.methods) { for (MethodModel mm: icm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(1); countAnnotations(1);
@ -69,66 +74,26 @@ public class PresenceInner {
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf) { void test(AttributedElement m) {
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
} }
void test(ClassFile cf, Method m) { // test the result of AttributedElement.findAttribute according to expectations
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); <T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
} if (attr_instance != null) {
switch (attr_instance) {
void test(ClassFile cf, Field m) { case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); all += tAttr.annotations().size();
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); visibles += tAttr.annotations().size();
} }
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
// test the result of Attributes.getIndex according to expectations all += tAttr.annotations().size();
// encoded in the method's name invisibles += tAttr.annotations().size();
void test(ClassFile cf, String name, boolean visible) { }
int index = cf.attributes.getIndex(cf.constant_pool, name); default -> throw new AssertionError();
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;
} }
} }

View File

@ -21,15 +21,20 @@
* questions. * questions.
*/ */
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*;
/* /*
* @test * @test
* @bug 6843077 * @bug 6843077
* @summary test that typecasts annotation are emitted if only the cast * @summary test that typecasts annotation are emitted if only the cast
* expression is optimized away * 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 { public class TypeCasts {
@ -41,9 +46,9 @@ public class TypeCasts {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(); countAnnotations();
@ -53,34 +58,34 @@ public class TypeCasts {
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf, Method m) { void test(MethodModel mm) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); 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 // encoded in the method's name
void test(ClassFile cf, Method m, String name, boolean visible) { <T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
Attribute attr = null; Attribute<T> attr;
Code_attribute cAttr = null; CodeAttribute cAttr;
int index = m.attributes.getIndex(cf.constant_pool, Attribute.Code); cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
if(index!= -1) { if (cAttr != null) {
attr = m.attributes.get(index); attr = cAttr.findAttribute(attr_name).orElse(null);
assert attr instanceof Code_attribute; if (attr != null) {
cAttr = (Code_attribute)attr; switch (attr) {
index = cAttr.attributes.getIndex(cf.constant_pool, name); case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
if(index!= -1) { all += tAttr.annotations().size();
attr = cAttr.attributes.get(index); visibles += tAttr.annotations().size();
assert attr instanceof RuntimeTypeAnnotations_attribute; }
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
all += tAttr.annotations.length; all += tAttr.annotations().size();
if (visible) invisibles += tAttr.annotations().size();
visibles += tAttr.annotations.length; }
else default -> throw new AssertionError();
invisibles += tAttr.annotations.length; }
} }
} }
} }

View File

@ -22,13 +22,19 @@
*/ */
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.Attributes;
import jdk.internal.classfile.attribute.*;
/* /*
* @test Visibility * @test Visibility
* @bug 6843077 * @bug 6843077
* @summary test that type annotations are recorded in the classfile * @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 { public class Visibility {
@ -40,9 +46,9 @@ public class Visibility {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(); countAnnotations();
@ -52,24 +58,27 @@ public class Visibility {
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(ClassFile cf, Method m) { void test(MethodModel mm) {
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); test(mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); 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 // encoded in the method's name
void test(ClassFile cf, Method m, String name, boolean visible) { <T extends Attribute<T>> void test(MethodModel mm, AttributeMapper<T> attr_name) {
int index = m.attributes.getIndex(cf.constant_pool, name); Attribute<T> attr_instance = mm.findAttribute(attr_name).orElse(null);
if (index != -1) { if (attr_instance != null) {
Attribute attr = m.attributes.get(index); switch (attr_instance) {
assert attr instanceof RuntimeTypeAnnotations_attribute; case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; all += tAttr.annotations().size();
all += tAttr.annotations.length; invisibles += tAttr.annotations().size();
if (visible) }
visibles += tAttr.annotations.length; case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
else all += tAttr.annotations().size();
invisibles += tAttr.annotations.length; visibles += tAttr.annotations().size();
}
default -> throw new AssertionError();
}
} }
} }
@ -109,7 +118,7 @@ public class Visibility {
} }
File compileTestFile(File f) { 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) if (rc != 0)
throw new Error("compilation failed. rc=" + rc); throw new Error("compilation failed. rc=" + rc);
String path = f.getPath(); String path = f.getPath();

View File

@ -22,13 +22,18 @@
*/ */
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
/* /*
* @test Wildcards * @test Wildcards
* @bug 6843077 * @bug 6843077
* @summary test that annotations target wildcards get emitted to classfile * @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 class Wildcards {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -39,13 +44,13 @@ public class Wildcards {
File javaFile = writeTestFile(); File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile); File classFile = compileTestFile(javaFile);
ClassFile cf = ClassFile.read(classFile); ClassModel cm = Classfile.of().parse(classFile.toPath());
test(cf); test(cm);
for (Field f : cf.fields) { for (FieldModel fm : cm.fields()) {
test(cf, f); test(fm);
} }
for (Method m: cf.methods) { for (MethodModel mm: cm.methods()) {
test(cf, m); test(mm);
} }
countAnnotations(); countAnnotations();
@ -54,72 +59,28 @@ public class Wildcards {
throw new Exception(errors + " errors found"); throw new Exception(errors + " errors found");
System.out.println("PASSED"); System.out.println("PASSED");
} }
void test(AttributedElement m) {
void test(ClassFile cf) { test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false);
} }
<T extends Attribute<T>> void test(AttributedElement m, AttributeMapper<T> attr_name) {
void test(ClassFile cf, Method m) { Attribute<T> attr_instance = m.findAttribute(attr_name).orElse(null);
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); if (attr_instance != null) {
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); switch (attr_instance) {
} case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
all += tAttr.annotations().size();
void test(ClassFile cf, Field m) { visibles += tAttr.annotations().size();
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); }
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
} all += tAttr.annotations().size();
invisibles += tAttr.annotations().size();
// test the result of Attributes.getIndex according to expectations }
// encoded in the method's name default -> throw new AssertionError();
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;
}
}
File writeTestFile() throws IOException { 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))); PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("import java.lang.annotation.*;"); out.println("import java.lang.annotation.*;");
out.println("import java.util.*;"); out.println("import java.util.*;");