8295059: test/langtools/tools/javap 12 test classes use com.sun.tools.classfile library
Reviewed-by: asotona
This commit is contained in:
parent
3671d83c87
commit
97b688340e
@ -24,11 +24,18 @@
|
|||||||
/*
|
/*
|
||||||
* @test 6716452
|
* @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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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.*;");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user