mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8295058: test/langtools/tools/javac 116 test classes uses com.sun.tools.classfile library
Reviewed-by: asotona
This commit is contained in:
parent
4726960fcd
commit
380418fad0
@ -25,10 +25,11 @@ package annotations.classfile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.ConstantPool.InvalidIndex;
|
||||
import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/**
|
||||
* A class providing utilities for writing tests that inspect class
|
||||
@ -326,8 +327,8 @@ public class ClassfileInspector {
|
||||
/**
|
||||
* See if this template matches the given visibility.
|
||||
*
|
||||
* @param Whether or not the annotation is visible at runtime.
|
||||
* @return Whether or not this template matches the visibility.
|
||||
* @param visibility Whether the annotation is visible at runtime.
|
||||
* @return Whether this template matches the visibility.
|
||||
*/
|
||||
public boolean matchVisibility(boolean visibility) {
|
||||
return this.visibility == visibility;
|
||||
@ -340,9 +341,8 @@ public class ClassfileInspector {
|
||||
*
|
||||
* @param anno The annotation to attempt to match.
|
||||
*/
|
||||
public void matchAnnotation(ConstantPool cpool,
|
||||
Annotation anno) {
|
||||
if (checkMatch(cpool, anno)) {
|
||||
public void matchAnnotation(Annotation anno) {
|
||||
if (checkMatch(anno)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -351,17 +351,11 @@ public class ClassfileInspector {
|
||||
* Indicate whether an annotation matches this expected
|
||||
* annotation.
|
||||
*
|
||||
* @param ConstantPool The constant pool to use.
|
||||
* @param anno The annotation to check.
|
||||
* @return Whether the annotation matches.
|
||||
*/
|
||||
protected boolean checkMatch(ConstantPool cpool,
|
||||
Annotation anno) {
|
||||
try {
|
||||
return cpool.getUTF8Info(anno.type_index).value.equals("L" + expectedName + ";");
|
||||
} catch (InvalidIndex | UnexpectedEntry e) {
|
||||
return false;
|
||||
}
|
||||
protected boolean checkMatch(Annotation anno) {
|
||||
return anno.classSymbol().descriptorString().equals("L" + expectedName + ";");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -532,7 +526,7 @@ public class ClassfileInspector {
|
||||
protected final int parameter_index;
|
||||
protected final int type_index;
|
||||
protected final int exception_index;
|
||||
protected final TypeAnnotation.Position.TypePathEntry[] typePath;
|
||||
protected final List<TypeAnnotation.TypePathComponent> typePath;
|
||||
|
||||
/**
|
||||
* Create an {@code ExpectedTypeAnnotation} from its
|
||||
@ -561,7 +555,7 @@ public class ClassfileInspector {
|
||||
int parameter_index,
|
||||
int type_index,
|
||||
int exception_index,
|
||||
TypeAnnotation.Position.TypePathEntry... typePath) {
|
||||
List<TypeAnnotation.TypePathComponent> typePath) {
|
||||
super(expectedName, visibility, expectedCount);
|
||||
this.targetType = targetType;
|
||||
this.bound_index = bound_index;
|
||||
@ -589,19 +583,18 @@ public class ClassfileInspector {
|
||||
sb.append(", exception_index = ");
|
||||
sb.append(exception_index);
|
||||
sb.append(", type_path = [");
|
||||
for(int i = 0; i < typePath.length; i++) {
|
||||
for(int i = 0; i < typePath.size(); i++) {
|
||||
if (i != 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(typePath[i]);
|
||||
sb.append(typePath.get(i));
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void matchAnnotation(ConstantPool cpool,
|
||||
Annotation anno) {}
|
||||
public void matchAnnotation(Annotation anno) {}
|
||||
|
||||
public void matchAnnotation(TypeAnnotation anno) {
|
||||
if (checkMatch(anno)) {
|
||||
@ -610,20 +603,39 @@ public class ClassfileInspector {
|
||||
}
|
||||
|
||||
public boolean checkMatch(TypeAnnotation anno) {
|
||||
boolean matches = checkMatch(anno.constant_pool, anno.annotation);
|
||||
|
||||
matches = matches && anno.position.type == targetType;
|
||||
matches = matches && anno.position.bound_index == bound_index;
|
||||
matches = matches && anno.position.parameter_index == parameter_index;
|
||||
matches = matches && anno.position.type_index == type_index;
|
||||
matches = matches && anno.position.exception_index == exception_index;
|
||||
matches = matches && anno.position.location.size() == typePath.length;
|
||||
boolean matches = checkMatch((Annotation) anno);
|
||||
int boundIdx = Integer.MIN_VALUE, paraIdx = Integer.MIN_VALUE, tIdx = Integer.MIN_VALUE, exIdx = Integer.MIN_VALUE;
|
||||
switch (anno.targetInfo()) {
|
||||
case TypeAnnotation.TypeParameterBoundTarget binfo -> {
|
||||
boundIdx = binfo.boundIndex();
|
||||
paraIdx = binfo.typeParameterIndex();
|
||||
}
|
||||
case TypeAnnotation.FormalParameterTarget fpinfo -> {
|
||||
paraIdx = fpinfo.formalParameterIndex();
|
||||
}
|
||||
case TypeAnnotation.TypeParameterTarget pinfo -> {
|
||||
paraIdx = pinfo.typeParameterIndex();
|
||||
}
|
||||
case TypeAnnotation.TypeArgumentTarget ainfo -> {
|
||||
tIdx = ainfo.typeArgumentIndex();
|
||||
}
|
||||
case TypeAnnotation.CatchTarget cinfo -> {
|
||||
exIdx = cinfo.exceptionTableIndex();
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
matches = matches && anno.targetInfo().targetType() == targetType;
|
||||
matches = matches && boundIdx == bound_index;
|
||||
matches = matches && paraIdx == parameter_index;
|
||||
matches = matches && tIdx == type_index;
|
||||
matches = matches && exIdx == exception_index;
|
||||
matches = matches && anno.targetPath().size() == typePath.size();
|
||||
|
||||
if (matches) {
|
||||
int i = 0;
|
||||
for(TypeAnnotation.Position.TypePathEntry entry :
|
||||
anno.position.location) {
|
||||
matches = matches && typePath[i++].equals(entry);
|
||||
for(TypeAnnotation.TypePathComponent entry :
|
||||
anno.targetPath()) {
|
||||
matches = matches && typePath.get(i++).equals(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,8 +659,8 @@ public class ClassfileInspector {
|
||||
protected int parameter_index = Integer.MIN_VALUE;
|
||||
protected int type_index = Integer.MIN_VALUE;
|
||||
protected int exception_index = Integer.MIN_VALUE;
|
||||
protected TypeAnnotation.Position.TypePathEntry[] typePath =
|
||||
new TypeAnnotation.Position.TypePathEntry[0];
|
||||
protected List<TypeAnnotation.TypePathComponent> typePath =
|
||||
new ArrayList<TypeAnnotation.TypePathComponent>();
|
||||
|
||||
/**
|
||||
* Create a {@code Builder} from the mandatory parameters.
|
||||
@ -696,7 +708,7 @@ public class ClassfileInspector {
|
||||
/**
|
||||
* Provide a parameter index parameter.
|
||||
*
|
||||
* @param bound_index The parameter_index value.
|
||||
* @param parameter_index The parameter_index value.
|
||||
*/
|
||||
public Builder setParameterIndex(int parameter_index) {
|
||||
this.parameter_index = parameter_index;
|
||||
@ -728,7 +740,7 @@ public class ClassfileInspector {
|
||||
*
|
||||
* @param typePath The type path value.
|
||||
*/
|
||||
public Builder setTypePath(TypeAnnotation.Position.TypePathEntry[] typePath) {
|
||||
public Builder setTypePath(List<TypeAnnotation.TypePathComponent> typePath) {
|
||||
this.typePath = typePath;
|
||||
return this;
|
||||
}
|
||||
@ -768,7 +780,7 @@ public class ClassfileInspector {
|
||||
int parameter_index,
|
||||
int type_index,
|
||||
int exception_index,
|
||||
TypeAnnotation.Position.TypePathEntry... typePath) {
|
||||
List<TypeAnnotation.TypePathComponent> typePath) {
|
||||
super(expectedName, visibility, expectedCount, targetType, bound_index,
|
||||
parameter_index, type_index, exception_index, typePath);
|
||||
this.methodname = methodname;
|
||||
@ -792,11 +804,11 @@ public class ClassfileInspector {
|
||||
sb.append(", exception_index = ");
|
||||
sb.append(exception_index);
|
||||
sb.append(", type_path = [");
|
||||
for(int i = 0; i < typePath.length; i++) {
|
||||
for(int i = 0; i < typePath.size(); i++) {
|
||||
if (i != 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(typePath[i]);
|
||||
sb.append(typePath.get(i));
|
||||
}
|
||||
sb.append("]");
|
||||
sb.append(" on method ");
|
||||
@ -894,7 +906,7 @@ public class ClassfileInspector {
|
||||
int parameter_index,
|
||||
int type_index,
|
||||
int exception_index,
|
||||
TypeAnnotation.Position.TypePathEntry... typePath) {
|
||||
List<TypeAnnotation.TypePathComponent> typePath) {
|
||||
super(expectedName, visibility, expectedCount, targetType, bound_index,
|
||||
parameter_index, type_index, exception_index, typePath);
|
||||
this.fieldname = fieldname;
|
||||
@ -913,11 +925,11 @@ public class ClassfileInspector {
|
||||
.append(", exception_index = ").append(exception_index)
|
||||
.append(", type_path = [");
|
||||
|
||||
for(int i = 0; i < typePath.length; i++) {
|
||||
for(int i = 0; i < typePath.size(); i++) {
|
||||
if (i != 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(typePath[i]);
|
||||
sb.append(typePath.get(i));
|
||||
}
|
||||
sb.append("]")
|
||||
.append(" on field ").append(fieldname);
|
||||
@ -981,162 +993,146 @@ public class ClassfileInspector {
|
||||
}
|
||||
}
|
||||
|
||||
private void matchClassAnnotation(ClassFile classfile,
|
||||
ExpectedAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Attribute attr : classfile.attributes) {
|
||||
attr.accept(annoMatcher(classfile.constant_pool), expected);
|
||||
private void matchClassAnnotation(ClassModel classfile,
|
||||
ExpectedAnnotation expected) {
|
||||
for(Attribute<?> attr : classfile.attributes()) {
|
||||
annoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchMethodAnnotation(ClassFile classfile,
|
||||
ExpectedMethodAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Method meth : classfile.methods) {
|
||||
if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
|
||||
for(Attribute attr : meth.attributes) {
|
||||
attr.accept(annoMatcher(classfile.constant_pool), expected);
|
||||
private void matchMethodAnnotation(ClassModel classfile,
|
||||
ExpectedMethodAnnotation expected) {
|
||||
for(MethodModel meth : classfile.methods()) {
|
||||
if (expected.matchMethodName(meth.methodName().stringValue())) {
|
||||
for(Attribute<?> attr : meth.attributes()) {
|
||||
annoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void matchParameterAnnotation(ClassFile classfile,
|
||||
ExpectedParameterAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Method meth : classfile.methods) {
|
||||
if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
|
||||
for(Attribute attr : meth.attributes) {
|
||||
attr.accept(paramMatcher(classfile.constant_pool), expected);
|
||||
private void matchParameterAnnotation(ClassModel classfile,
|
||||
ExpectedParameterAnnotation expected) {
|
||||
for(MethodModel meth : classfile.methods()) {
|
||||
if (expected.matchMethodName(meth.methodName().stringValue())) {
|
||||
for(Attribute<?> attr : meth.attributes()) {
|
||||
paramMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void matchFieldAnnotation(ClassFile classfile,
|
||||
ExpectedFieldAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Field field : classfile.fields) {
|
||||
if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
|
||||
for(Attribute attr : field.attributes) {
|
||||
attr.accept(annoMatcher(classfile.constant_pool), expected);
|
||||
private void matchFieldAnnotation(ClassModel classfile,
|
||||
ExpectedFieldAnnotation expected) {
|
||||
for(FieldModel field : classfile.fields()) {
|
||||
if (expected.matchFieldName(field.fieldName().stringValue())) {
|
||||
for(Attribute<?> attr : field.attributes()) {
|
||||
annoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void matchClassTypeAnnotation(ClassFile classfile,
|
||||
ExpectedTypeAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Attribute attr : classfile.attributes) {
|
||||
attr.accept(typeAnnoMatcher, expected);
|
||||
private void matchClassTypeAnnotation(ClassModel classfile,
|
||||
ExpectedTypeAnnotation expected) {
|
||||
for(Attribute<?> attr : classfile.attributes()) {
|
||||
typeAnnoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchMethodTypeAnnotation(ClassFile classfile,
|
||||
ExpectedMethodTypeAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Method meth : classfile.methods) {
|
||||
if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
|
||||
for(Attribute attr : meth.attributes) {
|
||||
attr.accept(typeAnnoMatcher, expected);
|
||||
private void matchMethodTypeAnnotation(ClassModel classfile,
|
||||
ExpectedMethodTypeAnnotation expected) {
|
||||
for(MethodModel meth : classfile.methods()) {
|
||||
if (expected.matchMethodName(meth.methodName().stringValue())) {
|
||||
for(Attribute<?> attr : meth.attributes()) {
|
||||
typeAnnoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void matchFieldTypeAnnotation(ClassFile classfile,
|
||||
ExpectedFieldTypeAnnotation expected)
|
||||
throws ConstantPoolException {
|
||||
for(Field field : classfile.fields) {
|
||||
if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
|
||||
for(Attribute attr : field.attributes) {
|
||||
attr.accept(typeAnnoMatcher, expected);
|
||||
private void matchFieldTypeAnnotation(ClassModel classfile,
|
||||
ExpectedFieldTypeAnnotation expected) {
|
||||
for(FieldModel field : classfile.fields()) {
|
||||
if (expected.matchFieldName(field.fieldName().stringValue())) {
|
||||
for(Attribute<?> attr : field.attributes()) {
|
||||
typeAnnoMatcher(attr, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void matchClassAnnotations(ClassFile classfile,
|
||||
ExpectedAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchClassAnnotations(ClassModel classfile,
|
||||
ExpectedAnnotation[] expected) {
|
||||
for(ExpectedAnnotation one : expected) {
|
||||
matchClassAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchMethodAnnotations(ClassFile classfile,
|
||||
ExpectedMethodAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchMethodAnnotations(ClassModel classfile,
|
||||
ExpectedMethodAnnotation[] expected) {
|
||||
for(ExpectedMethodAnnotation one : expected) {
|
||||
matchMethodAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchParameterAnnotations(ClassFile classfile,
|
||||
ExpectedParameterAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchParameterAnnotations(ClassModel classfile,
|
||||
ExpectedParameterAnnotation[] expected) {
|
||||
for(ExpectedParameterAnnotation one : expected) {
|
||||
matchParameterAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchFieldAnnotations(ClassFile classfile,
|
||||
ExpectedFieldAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchFieldAnnotations(ClassModel classfile,
|
||||
ExpectedFieldAnnotation[] expected) {
|
||||
for(ExpectedFieldAnnotation one : expected) {
|
||||
matchFieldAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchClassTypeAnnotations(ClassFile classfile,
|
||||
ExpectedTypeAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchClassTypeAnnotations(ClassModel classfile,
|
||||
ExpectedTypeAnnotation[] expected) {
|
||||
for(ExpectedTypeAnnotation one : expected) {
|
||||
matchClassTypeAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchMethodTypeAnnotations(ClassFile classfile,
|
||||
ExpectedMethodTypeAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchMethodTypeAnnotations(ClassModel classfile,
|
||||
ExpectedMethodTypeAnnotation[] expected) {
|
||||
for(ExpectedMethodTypeAnnotation one : expected) {
|
||||
matchMethodTypeAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
private void matchFieldTypeAnnotations(ClassFile classfile,
|
||||
ExpectedFieldTypeAnnotation[] expected)
|
||||
throws ConstantPoolException {
|
||||
private void matchFieldTypeAnnotations(ClassModel classfile,
|
||||
ExpectedFieldTypeAnnotation[] expected) {
|
||||
for(ExpectedFieldTypeAnnotation one : expected) {
|
||||
matchFieldTypeAnnotation(classfile, one);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a template on a single {@code ClassFile}.
|
||||
* Run a template on a single {@code ClassModel}.
|
||||
*
|
||||
* @param classfile The {@code ClassFile} on which to run tests.
|
||||
* @param classfile The {@code ClassModel} on which to run tests.
|
||||
* @param expected The expected annotation template.
|
||||
*/
|
||||
public void run(ClassFile classfile,
|
||||
Expected... expected)
|
||||
throws ConstantPoolException {
|
||||
run(new ClassFile[] { classfile }, expected);
|
||||
public void run(ClassModel classfile,
|
||||
Expected... expected) {
|
||||
run(new ClassModel[] { classfile }, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a template on multiple {@code ClassFile}s.
|
||||
* Run a template on multiple {@code ClassModel}s.
|
||||
*
|
||||
* @param classfile The {@code ClassFile}s on which to run tests.
|
||||
* @param classfiles The {@code ClassModel}s on which to run tests.
|
||||
* @param expected The expected annotation template.
|
||||
*/
|
||||
public void run(ClassFile[] classfiles,
|
||||
Expected... expected)
|
||||
throws ConstantPoolException {
|
||||
for(ClassFile classfile : classfiles) {
|
||||
public void run(ClassModel[] classfiles,
|
||||
Expected... expected) {
|
||||
for(ClassModel classfile : classfiles) {
|
||||
for(Expected one : expected) {
|
||||
if (one.matchClassName(classfile.getName())) {
|
||||
if (one.matchClassName(classfile.thisClass().name().stringValue())) {
|
||||
if (one.classAnnos != null)
|
||||
matchClassAnnotations(classfile, one.classAnnos);
|
||||
if (one.methodAnnos != null)
|
||||
@ -1165,303 +1161,81 @@ public class ClassfileInspector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@code ClassFile} from its file name.
|
||||
* Get a {@code ClassModel} from its file name.
|
||||
*
|
||||
* @param name The class' file name.
|
||||
* @param host A class in the same package.
|
||||
* @return The {@code ClassFile}
|
||||
* @return The {@code ClassModel}
|
||||
*/
|
||||
public static ClassFile getClassFile(String name,
|
||||
public static ClassModel getClassFile(String name,
|
||||
Class<?> host)
|
||||
throws IOException, ConstantPoolException {
|
||||
throws IOException {
|
||||
final URL url = host.getResource(name);
|
||||
assert url != null;
|
||||
try (InputStream in = url.openStream()) {
|
||||
return ClassFile.read(in);
|
||||
return Classfile.of().parse(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
private static class AbstractAttributeVisitor<T> implements Attribute.Visitor<Void, T> {
|
||||
|
||||
@Override
|
||||
public Void visitDefault(DefaultAttribute attr, T p) {
|
||||
return null;
|
||||
public void typeAnnoMatcher(Attribute<?> attr, ExpectedTypeAnnotation expected) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute vattr -> {
|
||||
if (expected.matchVisibility(true)) {
|
||||
for (TypeAnnotation anno : vattr.annotations()) expected.matchAnnotation(anno);
|
||||
}
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute ivattr -> {
|
||||
if (expected.matchVisibility(false)) {
|
||||
ivattr.annotations().forEach(expected::matchAnnotation);
|
||||
}
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBootstrapMethods(BootstrapMethods_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCode(Code_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCompilationID(CompilationID_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitConstantValue(ConstantValue_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDeprecated(Deprecated_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitExceptions(Exceptions_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitInnerClasses(InnerClasses_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLineNumberTable(LineNumberTable_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestHost(NestHost_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodParameters(MethodParameters_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModule(Module_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleHashes(ModuleHashes_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleMainClass(ModuleMainClass_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModulePackages(ModulePackages_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleResolution(ModuleResolution_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModuleTarget(ModuleTarget_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNestMembers(NestMembers_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSignature(Signature_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSourceFile(SourceFile_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSourceID(SourceID_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitStackMap(StackMap_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitStackMapTable(StackMapTable_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSynthetic(Synthetic_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPermittedSubclasses(PermittedSubclasses_attribute attr, T p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRecord(Record_attribute attr, T p) {
|
||||
return null;
|
||||
public void annoMatcher(Attribute<?> attr, ExpectedAnnotation expected) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute rvattr -> {
|
||||
if (expected.matchVisibility(true)) {
|
||||
for(Annotation anno : rvattr.annotations()) {
|
||||
expected.matchAnnotation(anno);
|
||||
}
|
||||
}
|
||||
}
|
||||
case RuntimeInvisibleAnnotationsAttribute rivattr -> {
|
||||
if (expected.matchVisibility(false)) {
|
||||
for(Annotation anno : rivattr.annotations()) {
|
||||
expected.matchAnnotation(anno);
|
||||
}
|
||||
}
|
||||
}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Attribute.Visitor<Void, ExpectedTypeAnnotation> typeAnnoMatcher
|
||||
= new AbstractAttributeVisitor<ExpectedTypeAnnotation>() {
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
|
||||
ExpectedTypeAnnotation expected) {
|
||||
if (expected.matchVisibility(true)) {
|
||||
for (TypeAnnotation anno : attr.annotations) {
|
||||
private void paramMatcher(Attribute<?> attr, ExpectedParameterAnnotation expected) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleParameterAnnotationsAttribute vattr -> {
|
||||
if (expected.matchVisibility(true)) {
|
||||
if (expected.index < vattr.parameterAnnotations().size()) {
|
||||
for(Annotation anno :
|
||||
vattr.parameterAnnotations().get(expected.index)) {
|
||||
expected.matchAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
|
||||
ExpectedTypeAnnotation expected) {
|
||||
if (expected.matchVisibility(false)) {
|
||||
for (TypeAnnotation anno : attr.annotations) {
|
||||
}
|
||||
case RuntimeInvisibleParameterAnnotationsAttribute ivattr -> {
|
||||
if (expected.matchVisibility(false)) {
|
||||
if (expected.index < ivattr.parameterAnnotations().size()) {
|
||||
for(Annotation anno :
|
||||
ivattr.parameterAnnotations().get(expected.index)) {
|
||||
expected.matchAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
private static Attribute.Visitor<Void, ExpectedAnnotation> annoMatcher(ConstantPool cpool) {
|
||||
return new AbstractAttributeVisitor<ExpectedAnnotation>() {
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
|
||||
ExpectedAnnotation expected) {
|
||||
if (expected.matchVisibility(true)) {
|
||||
for(Annotation anno : attr.annotations) {
|
||||
expected.matchAnnotation(cpool, anno);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
|
||||
ExpectedAnnotation expected) {
|
||||
if (expected.matchVisibility(false)) {
|
||||
for(Annotation anno : attr.annotations) {
|
||||
expected.matchAnnotation(cpool, anno);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Attribute.Visitor<Void, ExpectedParameterAnnotation> paramMatcher(ConstantPool cpool) {
|
||||
return new AbstractAttributeVisitor<ExpectedParameterAnnotation>() {
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
|
||||
ExpectedParameterAnnotation expected) {
|
||||
if (expected.matchVisibility(true)) {
|
||||
if (expected.index < attr.parameter_annotations.length) {
|
||||
for(Annotation anno :
|
||||
attr.parameter_annotations[expected.index]) {
|
||||
expected.matchAnnotation(cpool, anno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
|
||||
ExpectedParameterAnnotation expected) {
|
||||
if (expected.matchVisibility(false)) {
|
||||
if (expected.index < attr.parameter_annotations.length) {
|
||||
for(Annotation anno :
|
||||
attr.parameter_annotations[expected.index]) {
|
||||
expected.matchAnnotation(cpool, anno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,25 +26,23 @@
|
||||
* @bug 8009170
|
||||
* @summary Regression: javac generates redundant bytecode in assignop involving
|
||||
* arrays
|
||||
* @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
|
||||
* @run main RedundantByteCodeInArrayTest
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.CodeAttribute;
|
||||
import jdk.internal.classfile.constantpool.ConstantPool;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.Code_attribute.InvalidIndex;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
|
||||
import com.sun.tools.classfile.Method;
|
||||
|
||||
public class RedundantByteCodeInArrayTest {
|
||||
public static void main(String[] args)
|
||||
throws IOException, ConstantPoolException, InvalidDescriptor, InvalidIndex {
|
||||
throws IOException {
|
||||
new RedundantByteCodeInArrayTest()
|
||||
.checkClassFile(new File(System.getProperty("test.classes", "."),
|
||||
RedundantByteCodeInArrayTest.class.getName() + ".class"));
|
||||
@ -55,18 +53,18 @@ public class RedundantByteCodeInArrayTest {
|
||||
}
|
||||
|
||||
void checkClassFile(File file)
|
||||
throws IOException, ConstantPoolException, InvalidDescriptor, InvalidIndex {
|
||||
ClassFile classFile = ClassFile.read(file);
|
||||
ConstantPool constantPool = classFile.constant_pool;
|
||||
throws IOException {
|
||||
ClassModel classFile = Classfile.of().parse(file.toPath());
|
||||
ConstantPool constantPool = classFile.constantPool();
|
||||
|
||||
//lets get all the methods in the class file.
|
||||
for (Method method : classFile.methods) {
|
||||
if (method.getName(constantPool).equals("arrMethod")) {
|
||||
Code_attribute code = (Code_attribute) method.attributes
|
||||
.get(Attribute.Code);
|
||||
if (code.max_locals > 4)
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
if (method.methodName().equalsString("arrMethod")) {
|
||||
CodeAttribute code = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert code != null;
|
||||
if (code.maxLocals() > 4)
|
||||
throw new AssertionError("Too many locals for method arrMethod");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,14 +21,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.ConstantPool.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8273914
|
||||
* @summary Indy string concat changes order of operations
|
||||
* @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
|
||||
*
|
||||
* @compile -XDstringConcat=indy WellKnownTypes.java
|
||||
* @run main WellKnownTypes
|
||||
|
||||
@ -25,17 +25,18 @@
|
||||
* @test
|
||||
* @bug 7165659
|
||||
* @summary javac incorrectly sets strictfp access flag on inner-classes
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
public class InnerClassAttrMustNotHaveStrictFPFlagTest {
|
||||
@ -50,11 +51,11 @@ public class InnerClassAttrMustNotHaveStrictFPFlagTest {
|
||||
}
|
||||
|
||||
void analyzeClassFile(File path) throws Exception {
|
||||
ClassFile classFile = ClassFile.read(path);
|
||||
InnerClasses_attribute innerClasses =
|
||||
(InnerClasses_attribute) classFile.attributes.get(Attribute.InnerClasses);
|
||||
for (Info classInfo : innerClasses.classes) {
|
||||
Assert.check(!classInfo.inner_class_access_flags.is(AccessFlags.ACC_STRICT),
|
||||
ClassModel classFile = Classfile.of().parse(path.toPath());
|
||||
InnerClassesAttribute innerClasses = classFile.findAttribute(Attributes.INNER_CLASSES).orElse(null);
|
||||
assert innerClasses != null;
|
||||
for (InnerClassInfo classInfo : innerClasses.classes()) {
|
||||
Assert.check(classInfo.flagsMask() != Classfile.ACC_STRICT,
|
||||
"Inner classes attribute must not have the ACC_STRICT flag set");
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
* @test
|
||||
* @bug 8011181
|
||||
* @summary javac, empty UTF8 entry generated for inner class
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
*/
|
||||
|
||||
@ -35,11 +39,8 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
|
||||
import static com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8;
|
||||
import static com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
|
||||
import static com.sun.tools.classfile.ConstantPool.CPInfo;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
|
||||
public class EmptyUTF8ForInnerClassNameTest {
|
||||
|
||||
@ -55,13 +56,13 @@ public class EmptyUTF8ForInnerClassNameTest {
|
||||
}
|
||||
|
||||
void checkClassFile(final Path path) throws Exception {
|
||||
ClassFile classFile = ClassFile.read(
|
||||
new BufferedInputStream(Files.newInputStream(path)));
|
||||
for (CPInfo cpInfo : classFile.constant_pool.entries()) {
|
||||
if (cpInfo.getTag() == CONSTANT_Utf8) {
|
||||
CONSTANT_Utf8_info utf8Info = (CONSTANT_Utf8_info)cpInfo;
|
||||
Assert.check(utf8Info.value.length() > 0,
|
||||
"UTF8 with length 0 found at class " + classFile.getName());
|
||||
ClassModel classFile = Classfile.of().parse(
|
||||
new BufferedInputStream(Files.newInputStream(path)).readAllBytes());
|
||||
for (int i = 1; i < classFile.constantPool().entryCount(); ++i) {
|
||||
PoolEntry pe = classFile.constantPool().entryByIndex(i);
|
||||
if (pe instanceof Utf8Entry utf8Info) {
|
||||
Assert.check(utf8Info.stringValue().length() > 0,
|
||||
"UTF8 with length 0 found at class " + classFile.thisClass().name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
* @test
|
||||
* @bug 8028504
|
||||
* @summary javac generates LocalVariableTable even with -g:none
|
||||
* @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
|
||||
* @compile -g:none DontGenerateLVTForGNoneOpTest.java
|
||||
* @run main DontGenerateLVTForGNoneOpTest
|
||||
*/
|
||||
@ -35,10 +39,8 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.CodeAttribute;
|
||||
|
||||
public class DontGenerateLVTForGNoneOpTest {
|
||||
|
||||
@ -52,11 +54,11 @@ public class DontGenerateLVTForGNoneOpTest {
|
||||
}
|
||||
|
||||
void checkClassFile(final File cfile) throws Exception {
|
||||
ClassFile classFile = ClassFile.read(cfile);
|
||||
for (Method method : classFile.methods) {
|
||||
Code_attribute code = (Code_attribute)method.attributes.get(Attribute.Code);
|
||||
ClassModel classFile = Classfile.of().parse(cfile.toPath());
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
CodeAttribute code = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
if (code != null) {
|
||||
if (code.attributes.get(Attribute.LocalVariableTable) != null) {
|
||||
if (code.findAttribute(Attributes.LOCAL_VARIABLE_TABLE).orElse(null) != null) {
|
||||
throw new AssertionError("LVT shouldn't be generated for g:none");
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
* @test
|
||||
* @summary
|
||||
* @library /tools/lib
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
@ -37,7 +41,8 @@
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
import toolbox.JavacTask;
|
||||
@ -64,11 +69,12 @@ public class NoLocalsMustBeReservedForDCEedVarsTest {
|
||||
.run();
|
||||
|
||||
File cfile = new File(Paths.get(System.getProperty("user.dir"), "Test.class").toUri());
|
||||
ClassFile classFile = ClassFile.read(cfile);
|
||||
for (Method method: classFile.methods) {
|
||||
if (method.getName(classFile.constant_pool).equals("foo")) {
|
||||
Code_attribute codeAttr = (Code_attribute)method.attributes.get("Code");
|
||||
Assert.check(codeAttr.max_locals == 0, "max locals found " + codeAttr.max_locals);
|
||||
ClassModel classFile = Classfile.of().parse(cfile.toPath());
|
||||
for (MethodModel method: classFile.methods()) {
|
||||
if (method.methodName().stringValue().equals("foo")) {
|
||||
CodeAttribute codeAttr = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert codeAttr != null;
|
||||
Assert.check(codeAttr.maxLocals() == 0, "max locals found " + codeAttr.maxLocals());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,12 @@
|
||||
* @bug 8065132
|
||||
* @summary Test generation of annotations on inner class parameters.
|
||||
* @library /lib/annotations/
|
||||
* @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
|
||||
* @build annotations.classfile.ClassfileInspector SyntheticParameters
|
||||
* @run main SyntheticParameters
|
||||
*/
|
||||
@ -36,7 +41,7 @@ import annotations.classfile.ClassfileInspector;
|
||||
import java.io.*;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.ClassModel;
|
||||
|
||||
public class SyntheticParameters extends ClassfileInspector {
|
||||
|
||||
@ -116,7 +121,7 @@ public class SyntheticParameters extends ClassfileInspector {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new SyntheticParameters().run(
|
||||
new ClassFile[] { getClassFile(Inner_class, Inner.class),
|
||||
new ClassModel[] { getClassFile(Inner_class, Inner.class),
|
||||
getClassFile(Foo_class, Foo.class) },
|
||||
new Expected[] { Inner_expected, Foo_expected });
|
||||
}
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* jdk.jdeps/com.sun.tools.javap
|
||||
* @build toolbox.ToolBox toolbox.JavapTask
|
||||
* @run compile -g AnonymousClassTest.java
|
||||
@ -37,31 +42,15 @@
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.Annotation.Annotation_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Array_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Class_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Enum_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Primitive_element_value;
|
||||
import com.sun.tools.classfile.Annotation.element_value;
|
||||
import com.sun.tools.classfile.Annotation.element_value.Visitor;
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
|
||||
import com.sun.tools.classfile.ConstantPool.InvalidIndex;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.TypeAnnotation;
|
||||
import com.sun.tools.classfile.TypeAnnotation.Position;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.CodeAttribute;
|
||||
import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
@ -113,108 +102,108 @@ public class AnonymousClassTest {
|
||||
}
|
||||
|
||||
static void testAnonymousClassDeclaration() throws Exception {
|
||||
ClassFile cf = ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest$1.class"));
|
||||
RuntimeVisibleTypeAnnotations_attribute rvta =
|
||||
(RuntimeVisibleTypeAnnotations_attribute)
|
||||
cf.attributes.get(Attribute.RuntimeVisibleTypeAnnotations);
|
||||
ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$1.class"));
|
||||
RuntimeVisibleTypeAnnotationsAttribute rvta =
|
||||
cm.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null);
|
||||
assert rvta != null;
|
||||
assertEquals(
|
||||
Set.of(
|
||||
"@LAnonymousClassTest$TA;(1) CLASS_EXTENDS, offset=-1, location=[TYPE_ARGUMENT(0)]",
|
||||
"@LAnonymousClassTest$TA;(0) CLASS_EXTENDS, offset=-1, location=[]"),
|
||||
Arrays.stream(rvta.annotations)
|
||||
.map(a -> annotationDebugString(cf, a))
|
||||
rvta.annotations().stream()
|
||||
.map(a -> annotationDebugString(cm, null, a))
|
||||
.collect(toSet()));
|
||||
}
|
||||
|
||||
static void testTopLevelMethod() throws Exception {
|
||||
ClassFile cf = ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
Method method = findMethod(cf, "f");
|
||||
ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
MethodModel method = findMethod(cm, "f");
|
||||
Set<TypeAnnotation> annotations = getRuntimeVisibleTypeAnnotations(method);
|
||||
CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assertEquals(
|
||||
Set.of("@LAnonymousClassTest$TA;(0) NEW, offset=0, location=[INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cf, a)).collect(toSet()));
|
||||
annotations.stream().map(a -> annotationDebugString(cm, cAttr, a)).collect(toSet()));
|
||||
}
|
||||
|
||||
static void testInnerClassMethod() throws Exception {
|
||||
ClassFile cf =
|
||||
ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest$Inner.class"));
|
||||
Method method = findMethod(cf, "g");
|
||||
ClassModel cm =
|
||||
Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$Inner.class"));
|
||||
MethodModel method = findMethod(cm, "g");
|
||||
Set<TypeAnnotation> annotations = getRuntimeVisibleTypeAnnotations(method);
|
||||
CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
// The annotation needs two INNER_TYPE type path entries to apply to
|
||||
// AnonymousClassTest$Inner$1.
|
||||
assertEquals(
|
||||
Set.of(
|
||||
"@LAnonymousClassTest$TA;(2) NEW, offset=0, location=[INNER_TYPE, INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cf, a)).collect(toSet()));
|
||||
annotations.stream().map(a -> annotationDebugString(cm, cAttr, a)).collect(toSet()));
|
||||
}
|
||||
|
||||
static void testQualifiedSuperType() throws Exception {
|
||||
{
|
||||
ClassFile cf =
|
||||
ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
Method method = findMethod(cf, "g");
|
||||
ClassModel cm =
|
||||
Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
MethodModel method = findMethod(cm, "g");
|
||||
Set<TypeAnnotation> annotations = getRuntimeVisibleTypeAnnotations(method);
|
||||
CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
// Only @TA(4) is propagated to the anonymous class declaration.
|
||||
assertEquals(
|
||||
Set.of("@LAnonymousClassTest$TA;(4) NEW, offset=0, location=[INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cf, a)).collect(toSet()));
|
||||
annotations.stream().map(a -> annotationDebugString(cm, cAttr, a)).collect(toSet()));
|
||||
}
|
||||
|
||||
{
|
||||
ClassFile cf =
|
||||
ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest$2.class"));
|
||||
RuntimeVisibleTypeAnnotations_attribute rvta =
|
||||
(RuntimeVisibleTypeAnnotations_attribute)
|
||||
cf.attributes.get(Attribute.RuntimeVisibleTypeAnnotations);
|
||||
ClassModel cm =
|
||||
Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$2.class"));
|
||||
RuntimeVisibleTypeAnnotationsAttribute rvta =
|
||||
cm.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null);
|
||||
assert rvta != null;
|
||||
assertEquals(
|
||||
Set.of(
|
||||
"@LAnonymousClassTest$TA;(3) CLASS_EXTENDS, offset=-1, location=[]",
|
||||
"@LAnonymousClassTest$TA;(4) CLASS_EXTENDS, offset=-1, location=[INNER_TYPE]"),
|
||||
Arrays.stream(rvta.annotations)
|
||||
.map(a -> annotationDebugString(cf, a))
|
||||
rvta.annotations().stream()
|
||||
.map(a -> annotationDebugString(cm, null, a))
|
||||
.collect(toSet()));
|
||||
}
|
||||
}
|
||||
|
||||
static void testInstanceAndClassInit() throws Exception {
|
||||
ClassFile cf = ClassFile.read(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
Method method = findMethod(cf, "<init>");
|
||||
ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class"));
|
||||
MethodModel method = findMethod(cm, "<init>");
|
||||
Set<TypeAnnotation> annotations = getRuntimeVisibleTypeAnnotations(method);
|
||||
CodeAttribute cAttr1 = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assertEquals(
|
||||
Set.of("@LAnonymousClassTest$TA;(5) NEW, offset=4, location=[INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cf, a)).collect(toSet()) );
|
||||
annotations.stream().map(a -> annotationDebugString(cm, cAttr1, a)).collect(toSet()) );
|
||||
|
||||
method = findMethod(cf, "<clinit>");
|
||||
method = findMethod(cm, "<clinit>");
|
||||
annotations = getRuntimeVisibleTypeAnnotations(method);
|
||||
CodeAttribute cAttr2 = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assertEquals(
|
||||
Set.of("@LAnonymousClassTest$TA;(6) NEW, offset=0, location=[INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cf, a)).collect(toSet()) );
|
||||
Set.of("@LAnonymousClassTest$TA;(6) NEW, offset=16, location=[INNER_TYPE]"),
|
||||
annotations.stream().map(a -> annotationDebugString(cm, cAttr2, a)).collect(toSet()) );
|
||||
}
|
||||
|
||||
// Returns the Method's RuntimeVisibleTypeAnnotations, and asserts that there are no RVTIs
|
||||
// erroneously associated with the Method instead of its Code attribute.
|
||||
private static Set<TypeAnnotation> getRuntimeVisibleTypeAnnotations(Method method) {
|
||||
if (method.attributes.get(Attribute.RuntimeVisibleTypeAnnotations) != null) {
|
||||
private static Set<TypeAnnotation> getRuntimeVisibleTypeAnnotations(MethodModel method) {
|
||||
if (method.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null) != null) {
|
||||
throw new AssertionError(
|
||||
"expected no RuntimeVisibleTypeAnnotations attribute on enclosing method");
|
||||
}
|
||||
Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code);
|
||||
RuntimeVisibleTypeAnnotations_attribute rvta =
|
||||
(RuntimeVisibleTypeAnnotations_attribute)
|
||||
code.attributes.get(Attribute.RuntimeVisibleTypeAnnotations);
|
||||
return Set.of(rvta.annotations);
|
||||
CodeAttribute code = method.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert code != null;
|
||||
RuntimeVisibleTypeAnnotationsAttribute rvta =
|
||||
code.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null);
|
||||
assert rvta != null;
|
||||
return new HashSet<>(rvta.annotations());
|
||||
}
|
||||
|
||||
private static Method findMethod(ClassFile cf, String name) {
|
||||
return Arrays.stream(cf.methods)
|
||||
private static MethodModel findMethod(ClassModel cm, String name) {
|
||||
return cm.methods().stream()
|
||||
.filter(
|
||||
m -> {
|
||||
try {
|
||||
return m.getName(cf.constant_pool).contentEquals(name);
|
||||
} catch (ConstantPoolException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
})
|
||||
m -> m.methodName().stringValue().contentEquals(name))
|
||||
.findFirst()
|
||||
.get();
|
||||
}
|
||||
@ -225,73 +214,45 @@ public class AnonymousClassTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static String annotationDebugString(ClassFile cf, TypeAnnotation annotation) {
|
||||
Position pos = annotation.position;
|
||||
private static String annotationDebugString(ClassModel cm, CodeAttribute cAttr, TypeAnnotation annotation) {
|
||||
TypeAnnotation.TargetInfo info = annotation.targetInfo();
|
||||
int offset = info instanceof TypeAnnotation.OffsetTarget offsetInfo? cAttr.labelToBci(offsetInfo.target()): -1;
|
||||
String name;
|
||||
try {
|
||||
name = cf.constant_pool.getUTF8Info(annotation.annotation.type_index).value;
|
||||
name = annotation.classSymbol().descriptorString();
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
List<String> location = new ArrayList<>();
|
||||
for (TypeAnnotation.TypePathComponent path: annotation.targetPath()) {
|
||||
if (path.typePathKind() == TypeAnnotation.TypePathComponent.Kind.INNER_TYPE)location.add(path.typePathKind().name());
|
||||
else location.add(path.typePathKind() + "(" + path.typeArgumentIndex() + ")");
|
||||
}
|
||||
return String.format(
|
||||
"@%s(%s) %s, offset=%d, location=%s",
|
||||
name,
|
||||
annotationValueoDebugString(cf, annotation.annotation),
|
||||
pos.type,
|
||||
pos.offset,
|
||||
pos.location);
|
||||
annotationValueDebugString(cm, annotation),
|
||||
info.targetType(),
|
||||
offset,
|
||||
location);
|
||||
}
|
||||
|
||||
private static String annotationValueoDebugString(ClassFile cf, Annotation annotation) {
|
||||
if (annotation.element_value_pairs.length != 1) {
|
||||
private static String annotationValueDebugString(ClassModel cm, Annotation annotation) {
|
||||
if (annotation.elements().size() != 1) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
try {
|
||||
return elementValueDebugString(cf, annotation.element_value_pairs[0].value);
|
||||
return elementValueDebugString(annotation.elements().get(0).value());
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String elementValueDebugString(ClassFile cf, element_value value) {
|
||||
class Viz implements Visitor<String, Void> {
|
||||
@Override
|
||||
public String visitPrimitive(Primitive_element_value ev, Void aVoid) {
|
||||
try {
|
||||
switch (ev.tag) {
|
||||
case 'I':
|
||||
return Integer.toString(
|
||||
((CONSTANT_Integer_info)
|
||||
cf.constant_pool.get(ev.const_value_index))
|
||||
.value);
|
||||
default:
|
||||
throw new UnsupportedOperationException(String.format("%c", ev.tag));
|
||||
}
|
||||
} catch (InvalidIndex e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitEnum(Enum_element_value ev, Void aVoid) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClass(Class_element_value ev, Void aVoid) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitAnnotation(Annotation_element_value ev, Void aVoid) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitArray(Array_element_value ev, Void aVoid) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
private static String elementValueDebugString(AnnotationValue value) {
|
||||
if (value.tag() == 'I') {
|
||||
return Integer.toString(((AnnotationValue.OfInteger) value).intValue());
|
||||
} else {
|
||||
throw new UnsupportedOperationException(String.format("%c", value.tag()));
|
||||
}
|
||||
return value.accept(new Viz(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,12 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ClassfileTestHelper {
|
||||
@ -59,158 +59,119 @@ public class ClassfileTestHelper {
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
ClassModel getClassFile(String name) throws IOException {
|
||||
URL url = getClass().getResource(name);
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
assert url != null;
|
||||
try (InputStream in = url.openStream()) {
|
||||
return Classfile.of().parse(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
ClassFile getClassFile(URL url) throws IOException, ConstantPoolException {
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
ClassModel getClassFile(URL url) throws IOException {
|
||||
try (InputStream in = url.openStream()) {
|
||||
return Classfile.of().parse(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/************ Helper annotations counting methods ******************/
|
||||
void test(ClassFile cf) {
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
//RuntimeAnnotations since one annotation can result in two attributes.
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
void test(ClassModel cm) {
|
||||
test(cm, false); //For ClassModel, not look for annotations in code attr
|
||||
}
|
||||
// default to not looking in code attribute
|
||||
void test(FieldModel fm) {
|
||||
test(fm, false);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field f, Boolean local) {
|
||||
if (!local) {
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
} else {
|
||||
test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field f) {
|
||||
test(cf, f, false);
|
||||
void test(MethodModel mm ) {
|
||||
test(mm, false);
|
||||
}
|
||||
|
||||
// 'local' determines whether to look for annotations in code attribute or not.
|
||||
void test(ClassFile cf, Method m, Boolean local) {
|
||||
if (!local) {
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
} else {
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
void test(AttributedElement m, Boolean local) {
|
||||
test(m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, local);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, local);
|
||||
test(m, Attributes.RUNTIME_VISIBLE_ANNOTATIONS, local);
|
||||
test(m, Attributes.RUNTIME_INVISIBLE_ANNOTATIONS, local);
|
||||
}
|
||||
|
||||
// default to not looking in code attribute
|
||||
void test(ClassFile cf, Method m ) {
|
||||
test(cf, m, false);
|
||||
}
|
||||
|
||||
// Test the result of Attributes.getIndex according to expectations
|
||||
// Test the result of MethodModel.findAttribute according to expectations
|
||||
// encoded in the class/field/method name; increment annotations counts.
|
||||
void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) {
|
||||
String testtype = ttype;
|
||||
String name = null;
|
||||
int index = -1;
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
boolean isTAattr = annName.contains("TypeAnnotations");
|
||||
try {
|
||||
switch(testtype) {
|
||||
case "FIELD":
|
||||
name = f.getName(cf.constant_pool);
|
||||
index = f.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = f.attributes.get(index);
|
||||
break;
|
||||
case "CODE":
|
||||
name = f.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from code attribute.
|
||||
index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = cf.attributes.get(index);
|
||||
assert attr instanceof Code_attribute;
|
||||
cAttr = (Code_attribute)attr;
|
||||
index = cAttr.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = cAttr.attributes.get(index);
|
||||
}
|
||||
break;
|
||||
case "METHOD":
|
||||
name = m.getName(cf.constant_pool);
|
||||
index = m.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = m.attributes.get(index);
|
||||
break;
|
||||
case "MCODE":
|
||||
name = m.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from 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, annName);
|
||||
if(index!= -1)
|
||||
attr = cAttr.attributes.get(index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
name = cf.getName();
|
||||
index = cf.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1) attr = cf.attributes.get(index);
|
||||
<T extends Attribute<T>>void test(AttributedElement m, AttributeMapper<T> annName, Boolean local) {
|
||||
String name;
|
||||
Attribute<T> attr;
|
||||
boolean isTAattr = annName.name().contains("Type");
|
||||
switch(m) {
|
||||
case FieldModel fm -> {
|
||||
name = fm.fieldName().stringValue();
|
||||
attr = extractAnnotation(m, annName, local);
|
||||
}
|
||||
} catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
|
||||
|
||||
if (index != -1) {
|
||||
if(isTAattr) { //count RuntimeTypeAnnotations
|
||||
RuntimeTypeAnnotations_attribute tAttr =
|
||||
(RuntimeTypeAnnotations_attribute)attr;
|
||||
println(testtype + ": " + name + ", " + annName + ": " +
|
||||
tAttr.annotations.length );
|
||||
if (tAttr.annotations.length > 0) {
|
||||
for (int i = 0; i < tAttr.annotations.length; i++) {
|
||||
println(" types:" + tAttr.annotations[i].position.type);
|
||||
}
|
||||
} else {
|
||||
println("");
|
||||
}
|
||||
allt += tAttr.annotations.length;
|
||||
if (visible)
|
||||
tvisibles += tAttr.annotations.length;
|
||||
else
|
||||
tinvisibles += tAttr.annotations.length;
|
||||
} else {
|
||||
RuntimeAnnotations_attribute tAttr =
|
||||
(RuntimeAnnotations_attribute)attr;
|
||||
println(testtype + ": " + name + ", " + annName + ": " +
|
||||
tAttr.annotations.length );
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
case MethodModel mm -> {
|
||||
name = mm.methodName().stringValue();
|
||||
attr = extractAnnotation(m, annName, local);
|
||||
}
|
||||
default -> {
|
||||
ClassModel cm = (ClassModel) m;
|
||||
name = cm.thisClass().asInternalName();
|
||||
attr = extractAnnotation(cm, annName, local);
|
||||
}
|
||||
}
|
||||
|
||||
if (attr != null) {
|
||||
if(isTAattr) { //count RuntimeTypeAnnotations
|
||||
// List <TypeAnnotation> tAnnots = new ArrayList<TypeAnnotation>();
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute vtAttr -> {
|
||||
List <TypeAnnotation> tAnnots = vtAttr.annotations();
|
||||
tvisibles += tAnnots.size();
|
||||
allt += tAnnots.size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute invtAttr -> {
|
||||
System.err.println(invtAttr.annotations());
|
||||
List <TypeAnnotation> tAnnots = invtAttr.annotations();
|
||||
tinvisibles += tAnnots.size();
|
||||
allt += tAnnots.size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
// This snippet is simply for printlin. which are duplicated in two cases. Therefore, I want to drop it.
|
||||
// if (!tAnnots.isEmpty()) {
|
||||
//// for (TypeAnnotation tAnnot : tAnnots)
|
||||
//// println(" types:" + tAnnot.targetInfo().targetType());
|
||||
//// println("Local: " + local + ", " + name + ", " + annName + ": " + tAnnots.size());
|
||||
// allt += tAnnots.size();
|
||||
// }
|
||||
} else {
|
||||
List <Annotation> annots;
|
||||
switch (attr) {
|
||||
case RuntimeVisibleAnnotationsAttribute tAttr -> {
|
||||
annots = tAttr.annotations();
|
||||
visibles += annots.size();
|
||||
}
|
||||
case RuntimeInvisibleAnnotationsAttribute tAttr -> {
|
||||
annots = tAttr.annotations();
|
||||
invisibles += annots.size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
if (!annots.isEmpty()) {
|
||||
println("Local: " + local + ", " + name + ", " + annName + ": " + annots.size());
|
||||
all += annots.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<T extends Attribute<T>> Attribute<T> extractAnnotation(AttributedElement m, AttributeMapper<T> annName, Boolean local) {
|
||||
CodeAttribute cAttr;
|
||||
Attribute<T> attr = null;
|
||||
if (local) {
|
||||
cAttr = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
if (cAttr != null) {
|
||||
attr = cAttr.findAttribute(annName).orElse(null);
|
||||
}
|
||||
} else {
|
||||
attr = m.findAttribute(annName).orElse(null);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
void countAnnotations() {
|
||||
|
||||
@ -25,10 +25,15 @@
|
||||
* @test
|
||||
* @bug 8005085 8005877 8004829 8005681 8006734 8006775
|
||||
* @summary Combinations of Target ElementTypes on (repeated)type annotations.
|
||||
* @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
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import java.io.File;
|
||||
|
||||
public class CombinationsTargetTest1 extends ClassfileTestHelper {
|
||||
@ -142,16 +147,16 @@ public class CombinationsTargetTest1 extends ClassfileTestHelper {
|
||||
classFile=new File(sb.insert(sb.lastIndexOf(".class"),
|
||||
innerClassname).toString());
|
||||
}
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
|
||||
//Test class,fields and method counts.
|
||||
test(cf);
|
||||
test(cm);
|
||||
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
}
|
||||
countAnnotations();
|
||||
if (errors > 0) {
|
||||
|
||||
@ -25,10 +25,15 @@
|
||||
* @test
|
||||
* @bug 8005085 8005877 8004829 8005681 8006734 8006775 8006507
|
||||
* @summary Combinations of Target ElementTypes on (repeated)type annotations.
|
||||
* @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
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@ -161,22 +166,22 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
|
||||
classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString());
|
||||
println("classfile: " + classFile.getAbsolutePath());
|
||||
}
|
||||
ClassFile cf = ClassFile.read(classFile);
|
||||
ClassModel cm = Classfile.of().parse(classFile.toPath());
|
||||
|
||||
//Test class,fields and method counts.
|
||||
test(cf);
|
||||
test(cm);
|
||||
|
||||
for (Field f : cf.fields) {
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
if(source.local)
|
||||
test(cf, f, true);
|
||||
test(fm, true);
|
||||
else
|
||||
test(cf,f);
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
if(source.local)
|
||||
test(cf, m, true);
|
||||
test(mm, true);
|
||||
else
|
||||
test(cf, m);
|
||||
test(mm);
|
||||
}
|
||||
countAnnotations();
|
||||
if (errors > 0) {
|
||||
|
||||
@ -26,11 +26,19 @@
|
||||
* @bug 8005085 8005681 8008769 8010015
|
||||
* @summary Check (repeating)type annotations on lambda usage.
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @run main CombinationsTargetTest3
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
public class CombinationsTargetTest3 extends ClassfileTestHelper {
|
||||
@ -537,4 +545,139 @@ public class CombinationsTargetTest3 extends ClassfileTestHelper {
|
||||
}
|
||||
return imports + source;
|
||||
}
|
||||
|
||||
/************ Helper annotations counting methods ******************/
|
||||
void test(ClassFile cf) {
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
//RuntimeAnnotations since one annotation can result in two attributes.
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field f, Boolean local) {
|
||||
if (!local) {
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
} else {
|
||||
test("CODE",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("CODE",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field f) {
|
||||
test(cf, f, false);
|
||||
}
|
||||
|
||||
// 'local' determines whether to look for annotations in code attribute or not.
|
||||
void test(ClassFile cf, Method m, Boolean local) {
|
||||
if (!local) {
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
} else {
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
test("MCODE",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
}
|
||||
|
||||
// default to not looking in code attribute
|
||||
void test(ClassFile cf, Method m ) {
|
||||
test(cf, m, false);
|
||||
}
|
||||
|
||||
// Test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the class/field/method name; increment annotations counts.
|
||||
void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) {
|
||||
String testtype = ttype;
|
||||
String name = null;
|
||||
int index = -1;
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
boolean isTAattr = annName.contains("TypeAnnotations");
|
||||
try {
|
||||
switch(testtype) {
|
||||
case "FIELD":
|
||||
name = f.getName(cf.constant_pool);
|
||||
index = f.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = f.attributes.get(index);
|
||||
break;
|
||||
case "CODE":
|
||||
name = f.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from code attribute.
|
||||
index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = cf.attributes.get(index);
|
||||
assert attr instanceof Code_attribute;
|
||||
cAttr = (Code_attribute)attr;
|
||||
index = cAttr.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = cAttr.attributes.get(index);
|
||||
}
|
||||
break;
|
||||
case "METHOD":
|
||||
name = m.getName(cf.constant_pool);
|
||||
index = m.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1)
|
||||
attr = m.attributes.get(index);
|
||||
break;
|
||||
case "MCODE":
|
||||
name = m.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from 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, annName);
|
||||
if(index!= -1)
|
||||
attr = cAttr.attributes.get(index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
name = cf.getName();
|
||||
index = cf.attributes.getIndex(cf.constant_pool, annName);
|
||||
if(index!= -1) attr = cf.attributes.get(index);
|
||||
}
|
||||
} catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
|
||||
|
||||
if (index != -1) {
|
||||
if(isTAattr) { //count RuntimeTypeAnnotations
|
||||
RuntimeTypeAnnotations_attribute tAttr =
|
||||
(RuntimeTypeAnnotations_attribute)attr;
|
||||
System.out.println(testtype + ": " + name + ", " + annName + ": " +
|
||||
tAttr.annotations.length );
|
||||
if (tAttr.annotations.length > 0) {
|
||||
for (int i = 0; i < tAttr.annotations.length; i++) {
|
||||
System.out.println(" types:" + tAttr.annotations[i].position.type);
|
||||
}
|
||||
} else {
|
||||
System.out.println("");
|
||||
}
|
||||
allt += tAttr.annotations.length;
|
||||
if (visible)
|
||||
tvisibles += tAttr.annotations.length;
|
||||
else
|
||||
tinvisibles += tAttr.annotations.length;
|
||||
} else {
|
||||
RuntimeAnnotations_attribute tAttr =
|
||||
(RuntimeAnnotations_attribute)attr;
|
||||
System.out.println(testtype + ": " + name + ", " + annName + ": " +
|
||||
tAttr.annotations.length );
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,13 +26,18 @@ import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6917130 8006775
|
||||
* @summary test that optimized away annotations are not emited 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
*/
|
||||
|
||||
public class DeadCode extends ClassfileTestHelper {
|
||||
@ -43,14 +48,13 @@ public class DeadCode extends ClassfileTestHelper {
|
||||
public void run() throws Exception {
|
||||
expected_tinvisibles = 1;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("DeadCode$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("DeadCode$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m, true);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm, true);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -21,16 +21,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8136419 8200301
|
||||
* @summary test that type annotations on entities in initializers are 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* @compile -XDdeduplicateLambdas=false InstanceInitializer.java
|
||||
* @run main InstanceInitializer
|
||||
*/
|
||||
@ -44,13 +48,13 @@ public class InstanceInitializer extends ClassfileTestHelper {
|
||||
expected_tinvisibles = 4;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("InstanceInitializer$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("InstanceInitializer$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m, true);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm, true);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -21,17 +21,22 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/*
|
||||
* @test ClassLiterals
|
||||
* @summary test that new type arguments are 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
*/
|
||||
|
||||
public class NewTypeArguments extends ClassfileTestHelper{
|
||||
@ -43,13 +48,13 @@ public class NewTypeArguments extends ClassfileTestHelper{
|
||||
expected_tinvisibles = 3;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("NewTypeArguments$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("NewTypeArguments$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m, true);
|
||||
for (MethodModel m: cm.methods()) {
|
||||
test(m, true);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -27,29 +27,35 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test NoTargetAnnotations
|
||||
* @summary test that annotations with no Target meta type is emitted
|
||||
* only once as declaration annotation
|
||||
* @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
|
||||
*/
|
||||
public class NoTargetAnnotations {
|
||||
public class NoTargetAnnotations extends ClassfileTestHelper {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new NoTargetAnnotations().run();
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
ClassFile cf = getClassFile("NoTargetAnnotations$Test.class");
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
testDeclaration(cf, f);
|
||||
ClassModel cm = getClassFile("NoTargetAnnotations$Test.class");
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
testDeclaration(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m);
|
||||
testDeclaration(cf, m);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm);
|
||||
testDeclaration(mm);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
@ -59,90 +65,34 @@ public class NoTargetAnnotations {
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
|
||||
ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
|
||||
ClassModel getClassFile(String name) throws IOException {
|
||||
URL url = getClass().getResource(name);
|
||||
InputStream in = url.openStream();
|
||||
try {
|
||||
return ClassFile.read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
assert url != null;
|
||||
try (InputStream in = url.openStream()) {
|
||||
return Classfile.of().parse(in.readAllBytes());
|
||||
}
|
||||
}
|
||||
|
||||
/************ Helper annotations counting methods ******************/
|
||||
void test(ClassFile cf, Method m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
|
||||
void testDeclaration(AttributedElement m) {
|
||||
testDecl(m, Attributes.RUNTIME_VISIBLE_ANNOTATIONS);
|
||||
testDecl(m, Attributes.RUNTIME_INVISIBLE_ANNOTATIONS);
|
||||
}
|
||||
|
||||
void test(ClassFile cf, Field m) {
|
||||
test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
|
||||
}
|
||||
|
||||
void testDeclaration(ClassFile cf, Method m) {
|
||||
testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
|
||||
void testDeclaration(ClassFile cf, Field m) {
|
||||
testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true);
|
||||
testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false);
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// test the result of AttributedElement.findAttribute according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Method m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void test(ClassFile cf, Field m, String name, boolean visible) {
|
||||
int index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
if (index != -1) {
|
||||
Attribute attr = m.attributes.get(index);
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
|
||||
all += tAttr.annotations.length;
|
||||
if (visible)
|
||||
visibles += tAttr.annotations.length;
|
||||
else
|
||||
invisibles += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void testDecl(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 RuntimeAnnotations_attribute;
|
||||
RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr;
|
||||
this.declAnnotations += tAttr.annotations.length;
|
||||
}
|
||||
}
|
||||
|
||||
// test the result of Attributes.getIndex according to expectations
|
||||
// encoded in the method's name
|
||||
void testDecl(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 RuntimeAnnotations_attribute;
|
||||
RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr;
|
||||
this.declAnnotations += tAttr.annotations.length;
|
||||
<T extends Attribute<T>> void testDecl(AttributedElement m, AttributeMapper<T> name) {
|
||||
Attribute<T> attr = m.findAttribute(name).orElse(null);
|
||||
if (attr != null) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleAnnotationsAttribute tAttr -> {
|
||||
this.declAnnotations += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleAnnotationsAttribute tAttr -> {
|
||||
this.declAnnotations += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,14 +25,19 @@ import java.lang.annotation.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077 8006775
|
||||
* @summary Qualified inner type annotation accessible to the class.
|
||||
* @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
|
||||
*/
|
||||
|
||||
@Scopes.UniqueInner
|
||||
@ -45,8 +50,8 @@ public class Scopes<T extends @Scopes.UniqueInner Object> extends ClassfileTestH
|
||||
expected_tinvisibles = 1;
|
||||
expected_invisibles = 1;
|
||||
|
||||
ClassFile cf = getClassFile("Scopes.class");
|
||||
test(cf);
|
||||
ClassModel cm = getClassFile("Scopes.class");
|
||||
test(cm);
|
||||
|
||||
countAnnotations();
|
||||
|
||||
|
||||
@ -24,13 +24,18 @@
|
||||
import java.lang.annotation.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8136419 8200301
|
||||
* @summary test that type annotations on entities in static initializers are 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* @compile -XDdeduplicateLambdas=false StaticInitializer.java
|
||||
* @run main StaticInitializer
|
||||
*/
|
||||
@ -44,13 +49,13 @@ public class StaticInitializer extends ClassfileTestHelper {
|
||||
expected_tinvisibles = 4;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("StaticInitializer$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("StaticInitializer$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m, true);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm, true);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -25,16 +25,22 @@
|
||||
* @test SyntheticParameters
|
||||
* @summary Test generation of annotations on inner class parameters.
|
||||
* @library /lib/annotations/
|
||||
* @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
|
||||
* @run main SyntheticParameters
|
||||
*/
|
||||
|
||||
import annotations.classfile.ClassfileInspector;
|
||||
import jdk.internal.classfile.ClassModel;
|
||||
import jdk.internal.classfile.TypeAnnotation;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
public class SyntheticParameters extends ClassfileInspector {
|
||||
|
||||
@ -72,8 +78,8 @@ public class SyntheticParameters extends ClassfileInspector {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new SyntheticParameters().run(
|
||||
new ClassFile[] { getClassFile(Inner_class, Inner.class),
|
||||
getClassFile(Foo_class, Foo.class) },
|
||||
new ClassModel[] { getClassFile(Inner_class, Inner.class),
|
||||
getClassFile(Foo_class, Foo.class) },
|
||||
new Expected[] { Inner_expected, Foo_expected });
|
||||
}
|
||||
|
||||
|
||||
@ -26,13 +26,18 @@
|
||||
* @bug 8008762
|
||||
* @summary Type annotation on inner class in anonymous class
|
||||
* shows up as regular annotation
|
||||
* @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
|
||||
*/
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
public class T8008762 extends ClassfileTestHelper{
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -43,13 +48,13 @@ public class T8008762 extends ClassfileTestHelper{
|
||||
expected_tinvisibles = 0;
|
||||
expected_tvisibles = 4;
|
||||
|
||||
ClassFile cf = getClassFile("T8008762$Test$1$InnerAnon.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f, false);
|
||||
ClassModel cm = getClassFile("T8008762$Test$1$InnerAnon.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm, false);
|
||||
}
|
||||
for (Method m : cf.methods) {
|
||||
test(cf, m, false);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm, false);
|
||||
}
|
||||
countAnnotations();
|
||||
|
||||
|
||||
@ -26,12 +26,17 @@
|
||||
* @summary Repeated type-annotations on type parm of local variable
|
||||
* are not written to classfile.
|
||||
* @bug 8008769
|
||||
* @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
|
||||
*/
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
public class T8008769 extends ClassfileTestHelper{
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -40,9 +45,9 @@ public class T8008769 extends ClassfileTestHelper{
|
||||
|
||||
public void run() throws Exception {
|
||||
expected_tvisibles = 4;
|
||||
ClassFile cf = getClassFile("T8008769$Test.class");
|
||||
for (Method m : cf.methods) {
|
||||
test(cf, m, true);
|
||||
ClassModel cm = getClassFile("T8008769$Test.class");
|
||||
for (MethodModel mm : cm.methods()) {
|
||||
test(mm, true);
|
||||
}
|
||||
countAnnotations();
|
||||
|
||||
|
||||
@ -25,13 +25,18 @@
|
||||
* @test
|
||||
* @summary Wrong classfile attribution in inner class of lambda expression.
|
||||
* @bug 8010015
|
||||
* @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
|
||||
*/
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
/*
|
||||
* A type-annotations on a field in an inner class not in a lambda expression
|
||||
@ -47,9 +52,9 @@ public class T8010015 extends ClassfileTestHelper{
|
||||
public void run() throws Exception {
|
||||
expected_tvisibles = 1;
|
||||
expected_visibles = 1;
|
||||
ClassFile cf = getClassFile("T8010015$Test$1innerClass.class");
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("T8010015$Test$1innerClass.class");
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
countAnnotations();
|
||||
|
||||
|
||||
@ -33,13 +33,17 @@
|
||||
* results in 2). Elements with no annotations expect 0.
|
||||
* Source template is read in from testanoninner.template
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
import java.lang.annotation.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import com.sun.tools.classfile.*;
|
||||
import java.util.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.charset.*;
|
||||
import java.io.File;
|
||||
@ -62,11 +66,11 @@ public class TestAnonInnerClasses extends ClassfileTestHelper {
|
||||
int tc = 0, xtc = 180; // 45 x 4 variations of repeated annotations.
|
||||
File testSrc = new File(System.getProperty("test.src"));
|
||||
|
||||
String[] AnnoAttributes = {
|
||||
Attribute.RuntimeVisibleTypeAnnotations,
|
||||
Attribute.RuntimeInvisibleTypeAnnotations,
|
||||
Attribute.RuntimeVisibleAnnotations,
|
||||
Attribute.RuntimeInvisibleAnnotations
|
||||
AttributeMapper<?> [] AnnoAttributes = new AttributeMapper<?>[]{
|
||||
Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS,
|
||||
Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS,
|
||||
Attributes.RUNTIME_VISIBLE_ANNOTATIONS,
|
||||
Attributes.RUNTIME_INVISIBLE_ANNOTATIONS
|
||||
};
|
||||
|
||||
// template for source files
|
||||
@ -146,7 +150,7 @@ public class TestAnonInnerClasses extends ClassfileTestHelper {
|
||||
System.out.println("PASSED all tests.");
|
||||
}
|
||||
|
||||
void test(String ttype, ClassFile cf, Method m, Field f, boolean visible) {
|
||||
<T extends Attribute<T>> void test(AttributedElement m) {
|
||||
int vtaActual = 0,
|
||||
itaActual = 0,
|
||||
vaActual = 0,
|
||||
@ -160,122 +164,55 @@ public class TestAnonInnerClasses extends ClassfileTestHelper {
|
||||
String memberName = null,
|
||||
testcase = "undefined",
|
||||
testClassName = null;
|
||||
Attribute attr = null,
|
||||
Attribute<T> attr = null,
|
||||
cattr = null;
|
||||
Code_attribute CAttr = null;
|
||||
CodeAttribute CAttr = null;
|
||||
// Get counts of 4 annotation Attributes on element being checked.
|
||||
for (String AnnoType : AnnoAttributes) {
|
||||
try {
|
||||
switch (ttype) {
|
||||
case "METHOD":
|
||||
index = m.attributes.getIndex(cf.constant_pool,
|
||||
AnnoType);
|
||||
memberName = m.getName(cf.constant_pool);
|
||||
if (index != -1)
|
||||
attr = m.attributes.get(index);
|
||||
//fetch index annotations from code attribute.
|
||||
index2 = m.attributes.getIndex(cf.constant_pool,
|
||||
Attribute.Code);
|
||||
if (index2 != -1) {
|
||||
cattr = m.attributes.get(index2);
|
||||
assert cattr instanceof Code_attribute;
|
||||
CAttr = (Code_attribute)cattr;
|
||||
index2 = CAttr.attributes.getIndex(cf.constant_pool,
|
||||
AnnoType);
|
||||
if (index2 != -1)
|
||||
cattr = CAttr.attributes.get(index2);
|
||||
}
|
||||
break;
|
||||
case "FIELD":
|
||||
index = f.attributes.getIndex(cf.constant_pool,
|
||||
AnnoType);
|
||||
memberName = f.getName(cf.constant_pool);
|
||||
if (index != -1)
|
||||
attr = f.attributes.get(index);
|
||||
//fetch index annotations from code attribute.
|
||||
index2 = cf.attributes.getIndex(cf.constant_pool,
|
||||
Attribute.Code);
|
||||
if (index2!= -1) {
|
||||
cattr = cf.attributes.get(index2);
|
||||
assert cattr instanceof Code_attribute;
|
||||
CAttr = (Code_attribute)cattr;
|
||||
index2 = CAttr.attributes.getIndex(cf.constant_pool,
|
||||
AnnoType);
|
||||
if (index2!= -1)
|
||||
cattr = CAttr.attributes.get(index2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memberName = cf.getName();
|
||||
index = cf.attributes.getIndex(cf.constant_pool,
|
||||
AnnoType);
|
||||
if (index!= -1) attr = cf.attributes.get(index);
|
||||
break;
|
||||
for (AttributeMapper<?> Anno : AnnoAttributes) {
|
||||
AttributeMapper<T> AnnoType = (AttributeMapper<T>) Anno;
|
||||
if (Objects.requireNonNull(m) instanceof ClassModel) {
|
||||
ClassModel cm = (ClassModel) m;
|
||||
memberName = cm.thisClass().name().stringValue();
|
||||
attr = m.findAttribute(AnnoType).orElse(null);
|
||||
} else {
|
||||
memberName = m instanceof MethodModel ?
|
||||
((MethodModel) m).methodName().stringValue() : ((FieldModel) m).fieldName().stringValue();
|
||||
attr = m.findAttribute(AnnoType).orElse(null);
|
||||
//fetch index annotations from code attribute.
|
||||
CAttr = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
if (CAttr != null) {
|
||||
cattr = CAttr.findAttribute(AnnoType).orElse(null);
|
||||
}
|
||||
}
|
||||
catch (ConstantPoolException cpe) { cpe.printStackTrace(); }
|
||||
try {
|
||||
testClassName=cf.getName();
|
||||
testcase = ttype + ": " + testClassName + ": " +
|
||||
memberName + ", ";
|
||||
}
|
||||
catch (ConstantPoolException cpe) { cpe.printStackTrace(); }
|
||||
if (index != -1) {
|
||||
switch (AnnoType) {
|
||||
case Attribute.RuntimeVisibleTypeAnnotations:
|
||||
//count RuntimeVisibleTypeAnnotations
|
||||
RuntimeVisibleTypeAnnotations_attribute RVTAa =
|
||||
(RuntimeVisibleTypeAnnotations_attribute)attr;
|
||||
vtaActual += RVTAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeVisibleAnnotations:
|
||||
//count RuntimeVisibleAnnotations
|
||||
RuntimeVisibleAnnotations_attribute RVAa =
|
||||
(RuntimeVisibleAnnotations_attribute)attr;
|
||||
vaActual += RVAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeInvisibleTypeAnnotations:
|
||||
//count RuntimeInvisibleTypeAnnotations
|
||||
RuntimeInvisibleTypeAnnotations_attribute RITAa =
|
||||
(RuntimeInvisibleTypeAnnotations_attribute)attr;
|
||||
itaActual += RITAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeInvisibleAnnotations:
|
||||
//count RuntimeInvisibleAnnotations
|
||||
RuntimeInvisibleAnnotations_attribute RIAa =
|
||||
(RuntimeInvisibleAnnotations_attribute)attr;
|
||||
iaActual += RIAa.annotations.length;
|
||||
break;
|
||||
;
|
||||
// testClassName=cm.getName();
|
||||
// testcase = ttype + ": " + testClassName + ": " +
|
||||
// memberName + ", ";
|
||||
if (attr != null) {
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute RVTAa -> //count RuntimeVisibleTypeAnnotations
|
||||
vtaActual += RVTAa.annotations().size();
|
||||
case RuntimeVisibleAnnotationsAttribute RVAa -> //count RuntimeVisibleAnnotations
|
||||
vaActual += RVAa.annotations().size();
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute RITAa -> //count RuntimeInvisibleTypeAnnotations
|
||||
itaActual += RITAa.annotations().size();
|
||||
case RuntimeInvisibleAnnotationsAttribute RIAa -> //count RuntimeInvisibleAnnotations
|
||||
iaActual += RIAa.annotations().size();
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
// annotations from code attribute.
|
||||
if (index2 != -1) {
|
||||
switch (AnnoType) {
|
||||
case Attribute.RuntimeVisibleTypeAnnotations:
|
||||
//count RuntimeVisibleTypeAnnotations
|
||||
RuntimeVisibleTypeAnnotations_attribute RVTAa =
|
||||
(RuntimeVisibleTypeAnnotations_attribute)cattr;
|
||||
vtaActual += RVTAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeVisibleAnnotations:
|
||||
//count RuntimeVisibleAnnotations
|
||||
RuntimeVisibleAnnotations_attribute RVAa =
|
||||
(RuntimeVisibleAnnotations_attribute)cattr;
|
||||
vaActual += RVAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeInvisibleTypeAnnotations:
|
||||
//count RuntimeInvisibleTypeAnnotations
|
||||
RuntimeInvisibleTypeAnnotations_attribute RITAa =
|
||||
(RuntimeInvisibleTypeAnnotations_attribute)cattr;
|
||||
itaActual += RITAa.annotations.length;
|
||||
break;
|
||||
case Attribute.RuntimeInvisibleAnnotations:
|
||||
//count RuntimeInvisibleAnnotations
|
||||
RuntimeInvisibleAnnotations_attribute RIAa =
|
||||
(RuntimeInvisibleAnnotations_attribute)cattr;
|
||||
iaActual += RIAa.annotations.length;
|
||||
break;
|
||||
if (cattr != null) {
|
||||
switch (cattr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute RVTAa -> //count RuntimeVisibleTypeAnnotations
|
||||
vtaActual += RVTAa.annotations().size();
|
||||
case RuntimeVisibleAnnotationsAttribute RVAa -> //count RuntimeVisibleAnnotations
|
||||
vaActual += RVAa.annotations().size();
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute RITAa -> //count RuntimeInvisibleTypeAnnotations
|
||||
itaActual += RITAa.annotations().size();
|
||||
case RuntimeInvisibleAnnotationsAttribute RIAa -> //count RuntimeInvisibleAnnotations
|
||||
iaActual += RIAa.annotations().size();
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,8 +280,8 @@ public class TestAnonInnerClasses extends ClassfileTestHelper {
|
||||
vtaActual,itaActual,vaActual,iaActual);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
ClassFile cf = null;
|
||||
public <T extends Attribute<T>>void run() {
|
||||
ClassModel cm = null;
|
||||
InputStream in = null;
|
||||
int testcount = 1;
|
||||
File testFile = null;
|
||||
@ -384,15 +321,16 @@ public class TestAnonInnerClasses extends ClassfileTestHelper {
|
||||
0,classFile.getAbsolutePath().indexOf(classFile.getPath()));
|
||||
for (String clazz : classes) {
|
||||
try {
|
||||
cf = ClassFile.read(new File(testloc+clazz));
|
||||
cm = Classfile.of().parse(new File(testloc+clazz).toPath());
|
||||
}
|
||||
catch (Exception e) { e.printStackTrace(); }
|
||||
// Test for all methods and fields
|
||||
for (Method m: cf.methods) {
|
||||
test("METHOD", cf, m, null, true);
|
||||
assert cm != null;
|
||||
for (MethodModel m: cm.methods()) {
|
||||
test(m);
|
||||
}
|
||||
for (Field f: cf.fields) {
|
||||
test("FIELD", cf, null, f, true);
|
||||
for (FieldModel f: cm.fields()) {
|
||||
test(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,14 +25,21 @@
|
||||
* @test
|
||||
* @bug 8005681
|
||||
* @summary Repeated annotations on new,array,cast.
|
||||
* @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
|
||||
*/
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.Objects;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@ -73,67 +80,53 @@ public class TestNewCastArray {
|
||||
System.out.println("PASS");
|
||||
}
|
||||
|
||||
void test(String clazz, String ttype, ClassFile cf, Method m, Field f,
|
||||
String name, boolean codeattr) {
|
||||
<T extends Attribute<T>> void test(String clazz, AttributedElement m, AttributeMapper<T> name, Boolean codeattr) {
|
||||
int actual = 0;
|
||||
int expected = 0, cexpected = 0;
|
||||
int index = 0;
|
||||
String memberName = null;
|
||||
Attribute attr = null;
|
||||
Code_attribute cAttr = null;
|
||||
String testcase = "undefined";
|
||||
try {
|
||||
switch(ttype) {
|
||||
case "METHOD":
|
||||
index = m.attributes.getIndex(cf.constant_pool, name);
|
||||
memberName = m.getName(cf.constant_pool);
|
||||
if(index != -1)
|
||||
attr = m.attributes.get(index);
|
||||
break;
|
||||
case "MCODE":
|
||||
memberName = m.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from 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);
|
||||
String memberName;
|
||||
Attribute<T> attr = null;
|
||||
CodeAttribute cAttr;
|
||||
String testcase;
|
||||
switch (m) {
|
||||
case MethodModel mm -> {
|
||||
memberName = mm.methodName().stringValue();
|
||||
if(codeattr) {
|
||||
//fetch index of and code attribute and annotations from code attribute.
|
||||
cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
|
||||
if(cAttr != null) {
|
||||
attr = cAttr.findAttribute(name).orElse(null);
|
||||
}
|
||||
} else {
|
||||
attr = mm.findAttribute(name).orElse(null);
|
||||
}
|
||||
break;
|
||||
case "FIELD":
|
||||
index = f.attributes.getIndex(cf.constant_pool, name);
|
||||
memberName = f.getName(cf.constant_pool);
|
||||
if(index != -1)
|
||||
attr = f.attributes.get(index);
|
||||
break;
|
||||
case "CODE":
|
||||
memberName = f.getName(cf.constant_pool);
|
||||
//fetch index of and code attribute and annotations from code attribute.
|
||||
index = cf.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
if(index!= -1) {
|
||||
attr = cf.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);
|
||||
}
|
||||
case FieldModel fm -> {
|
||||
memberName = fm.fieldName().stringValue();
|
||||
if(codeattr) {
|
||||
cAttr = fm.findAttribute(Attributes.CODE).orElse(null);
|
||||
if(cAttr != null) {
|
||||
attr = cAttr.findAttribute(name).orElse(null);
|
||||
}
|
||||
} else {
|
||||
attr = fm.findAttribute(name).orElse(null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
} catch(ConstantPoolException cpe) { cpe.printStackTrace(); }
|
||||
testcase = clazz+" "+ttype + ": " + memberName + ", " + name;
|
||||
if(index != -1) {
|
||||
testcase = clazz+" , Local: "+ codeattr + ": " + memberName + ", " + name;
|
||||
if(attr != null) {
|
||||
//count RuntimeTypeAnnotations
|
||||
assert attr instanceof RuntimeTypeAnnotations_attribute;
|
||||
RuntimeTypeAnnotations_attribute tAttr =
|
||||
(RuntimeTypeAnnotations_attribute)attr;
|
||||
actual += tAttr.annotations.length;
|
||||
switch (attr) {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute tAttr -> {
|
||||
actual += tAttr.annotations().size();
|
||||
}
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute tAttr -> {
|
||||
actual += tAttr.annotations().size();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
}
|
||||
assert memberName != null;
|
||||
if(memberName.compareTo("<init>")==0) memberName=clazz+memberName;
|
||||
switch ( memberName ) {
|
||||
//METHOD:
|
||||
@ -204,27 +197,28 @@ public class TestNewCastArray {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
ClassFile cf = null;
|
||||
InputStream in = null;
|
||||
ClassModel cm = null;
|
||||
InputStream in;
|
||||
for( String clazz : testclasses) {
|
||||
String testclazz = "TestNewCastArray$" + clazz + ".class";
|
||||
System.out.println("Testing " + testclazz);
|
||||
try {
|
||||
in = getClass().getResource(testclazz).openStream();
|
||||
cf = ClassFile.read(in);
|
||||
in = Objects.requireNonNull(getClass().getResource(testclazz)).openStream();
|
||||
cm = Classfile.of().parse(in.readAllBytes());
|
||||
in.close();
|
||||
} catch(Exception e) { e.printStackTrace(); }
|
||||
|
||||
assert cm != null;
|
||||
if(clazz.startsWith("Test1")) {
|
||||
for (Field f: cf.fields)
|
||||
test(clazz, "FIELD", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, false);
|
||||
for (Method m: cf.methods)
|
||||
test(clazz, "METHOD", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, false);
|
||||
for (FieldModel fm: cm.fields())
|
||||
test(clazz, fm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, false);
|
||||
for (MethodModel mm: cm.methods())
|
||||
test(clazz, mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, false);
|
||||
} else {
|
||||
for (Field f: cf.fields)
|
||||
test(clazz, "CODE", cf, null, f, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
for (Method m: cf.methods)
|
||||
test(clazz, "MCODE", cf, m, null, Attribute.RuntimeVisibleTypeAnnotations, true);
|
||||
for (FieldModel fm: cm.fields())
|
||||
test(clazz, fm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, true);
|
||||
for (MethodModel mm: cm.methods())
|
||||
test(clazz, mm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, true);
|
||||
}
|
||||
}
|
||||
report();
|
||||
@ -350,7 +344,7 @@ public class TestNewCastArray {
|
||||
// Cast expressions
|
||||
static class Test5a {
|
||||
Test5a(){}
|
||||
Object o = new Integer(1);
|
||||
Object o = 1;
|
||||
// expect 2+2=4
|
||||
Integer ci11 = (@A @B Integer)o; // OK expect 3, got 3
|
||||
Integer ci21 = (@A @A @B Integer)o; // OK expect 3, got 3
|
||||
@ -358,7 +352,7 @@ public class TestNewCastArray {
|
||||
|
||||
static class Test5b {
|
||||
Test5b(){}
|
||||
Object o = new Integer(1);
|
||||
Object o = 1;
|
||||
// Cast expressions
|
||||
// expect 1+2=3
|
||||
Integer ci2 = (@A @A Integer)o; // FAIL expect 2, got 1
|
||||
|
||||
@ -25,21 +25,24 @@
|
||||
* @test
|
||||
* @bug 8144185
|
||||
* @summary javac produces incorrect RuntimeInvisibleTypeAnnotations length 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
*/
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
|
||||
import com.sun.tools.classfile.TypeAnnotation;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.CodeAttribute;
|
||||
import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TypeAnnotationPropagationTest extends ClassfileTestHelper {
|
||||
@ -48,26 +51,36 @@ public class TypeAnnotationPropagationTest extends ClassfileTestHelper {
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
ClassFile cf = getClassFile("TypeAnnotationPropagationTest$Test.class");
|
||||
ClassModel cm = getClassFile("TypeAnnotationPropagationTest$Test.class");
|
||||
|
||||
Method f = null;
|
||||
for (Method m : cf.methods) {
|
||||
if (m.getName(cf.constant_pool).contains("f")) {
|
||||
f = m;
|
||||
MethodModel f = null;
|
||||
for (MethodModel mm : cm.methods()) {
|
||||
if (mm.methodName().stringValue().contains("f")) {
|
||||
f = mm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = f.attributes.getIndex(cf.constant_pool, Attribute.Code);
|
||||
Code_attribute cattr = (Code_attribute) f.attributes.get(idx);
|
||||
idx = cattr.attributes.getIndex(cf.constant_pool, Attribute.RuntimeVisibleTypeAnnotations);
|
||||
RuntimeVisibleTypeAnnotations_attribute attr =
|
||||
(RuntimeVisibleTypeAnnotations_attribute) cattr.attributes.get(idx);
|
||||
assert f != null;
|
||||
CodeAttribute cattr = f.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert cattr != null;
|
||||
RuntimeVisibleTypeAnnotationsAttribute attr = cattr.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null);
|
||||
|
||||
TypeAnnotation anno = attr.annotations[0];
|
||||
assertEquals(anno.position.lvarOffset, new int[] {3}, "start_pc");
|
||||
assertEquals(anno.position.lvarLength, new int[] {8}, "length");
|
||||
assertEquals(anno.position.lvarIndex, new int[] {1}, "index");
|
||||
assert attr != null;
|
||||
List<TypeAnnotation.LocalVarTargetInfo> annosPosition = ((TypeAnnotation.LocalVarTarget) attr.annotations().get(0).targetInfo()).table();
|
||||
int[] lvarOffset = annosPosition.stream()
|
||||
.map(e -> cattr.labelToBci(e.startLabel()))
|
||||
.mapToInt(t -> t).toArray();
|
||||
int[] lvarLength = annosPosition.stream()
|
||||
.map(e -> cattr.labelToBci(e.endLabel()) - cattr.labelToBci(e.startLabel()))
|
||||
.mapToInt(t -> t).toArray();
|
||||
int[] lvarIndex = annosPosition.stream()
|
||||
.map(TypeAnnotation.LocalVarTargetInfo::index)
|
||||
.mapToInt(t -> t).toArray();
|
||||
|
||||
assertEquals(lvarOffset, new int[] {3}, "start_pc");
|
||||
assertEquals(lvarLength, new int[] {8}, "length");
|
||||
assertEquals(lvarIndex, new int[] {1}, "index");
|
||||
}
|
||||
|
||||
void assertEquals(int[] actual, int[] expected, String message) {
|
||||
|
||||
@ -26,14 +26,18 @@ import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843077 8006775
|
||||
* @summary test that typecasts annotation are emitted if only the cast
|
||||
* expression is optimized away
|
||||
* @modules jdk.jdeps/com.sun.tools.classfile
|
||||
* @modules java.base/jdk.internal.classfile
|
||||
* java.base/jdk.internal.classfile.attribute
|
||||
* java.base/jdk.internal.classfile.constantpool
|
||||
* java.base/jdk.internal.classfile.instruction
|
||||
* java.base/jdk.internal.classfile.components
|
||||
*/
|
||||
|
||||
public class TypeCasts extends ClassfileTestHelper{
|
||||
@ -44,14 +48,13 @@ public class TypeCasts extends ClassfileTestHelper{
|
||||
public void run() throws Exception {
|
||||
expected_tinvisibles = 4;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("TypeCasts$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("TypeCasts$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m, true);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm, true);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -26,13 +26,17 @@ import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
|
||||
/*
|
||||
* @test Wildcards
|
||||
* @bug 6843077 8006775
|
||||
* @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 extends ClassfileTestHelper {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -43,13 +47,13 @@ public class Wildcards extends ClassfileTestHelper {
|
||||
expected_tinvisibles = 3;
|
||||
expected_tvisibles = 0;
|
||||
|
||||
ClassFile cf = getClassFile("Wildcards$Test.class");
|
||||
test(cf);
|
||||
for (Field f : cf.fields) {
|
||||
test(cf, f);
|
||||
ClassModel cm = getClassFile("Wildcards$Test.class");
|
||||
test(cm);
|
||||
for (FieldModel fm : cm.fields()) {
|
||||
test(fm);
|
||||
}
|
||||
for (Method m: cf.methods) {
|
||||
test(cf, m,false);
|
||||
for (MethodModel mm: cm.methods()) {
|
||||
test(mm,false);
|
||||
}
|
||||
|
||||
countAnnotations();
|
||||
|
||||
@ -28,24 +28,31 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build AnnotationDefaultTest AnnotationDefaultVerifier
|
||||
* @run main AnnotationDefaultTest
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
public class AnnotationDefaultTest extends TestResult {
|
||||
|
||||
@ -68,14 +75,13 @@ public class AnnotationDefaultTest extends TestResult {
|
||||
// Map <method-name, expected-annotation-default-values>
|
||||
Map<String, ExpectedValues> expectedValues =
|
||||
getExpectedValues(forName(className, fileManager));
|
||||
ClassFile classFile = readClassFile(fileManager.getClasses().get(className));
|
||||
ClassModel classFile = readClassFile(fileManager.getClasses().get(className));
|
||||
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = method.getName(classFile.constant_pool);
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
String methodName = method.methodName().stringValue();
|
||||
printf("Testing method : %s\n", methodName);
|
||||
AnnotationDefault_attribute attr =
|
||||
(AnnotationDefault_attribute) method.attributes
|
||||
.get(Attribute.AnnotationDefault);
|
||||
AnnotationDefaultAttribute attr =
|
||||
method.findAttribute(Attributes.ANNOTATION_DEFAULT).orElse(null);
|
||||
|
||||
if (hasDefault && !checkNotNull(attr, "Attribute is not null")
|
||||
|| !hasDefault && checkNull(attr, "Attribute is null")) {
|
||||
@ -83,20 +89,19 @@ public class AnnotationDefaultTest extends TestResult {
|
||||
continue;
|
||||
}
|
||||
|
||||
checkEquals(countNumberOfAttributes(method.attributes.attrs),
|
||||
1l,
|
||||
checkEquals(countNumberOfAttributes(method.attributes()),
|
||||
1L,
|
||||
"Number of AnnotationDefault attribute");
|
||||
checkEquals(classFile.constant_pool
|
||||
.getUTF8Value(attr.attribute_name_index),
|
||||
checkEquals(attr.attributeName(),
|
||||
"AnnotationDefault", "attribute_name_index");
|
||||
|
||||
ExpectedValues expectedValue = expectedValues.get(methodName);
|
||||
checkEquals((char) attr.default_value.tag, expectedValue.tag(),
|
||||
checkEquals(attr.defaultValue().tag(), expectedValue.tag(),
|
||||
String.format("check tag : %c %s", expectedValue.tag(), expectedValue.name()));
|
||||
verifier.testElementValue(attr.default_value.tag,
|
||||
this, classFile, attr.default_value,
|
||||
verifier.testElementValue((int)attr.defaultValue().tag(),
|
||||
this, classFile, attr.defaultValue(),
|
||||
expectedValue.values());
|
||||
verifier.testLength(attr.default_value.tag, this, attr);
|
||||
verifier.testLength((int)attr.defaultValue().tag(), this, attr);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
addFailure(e);
|
||||
@ -124,9 +129,9 @@ public class AnnotationDefaultTest extends TestResult {
|
||||
return ans;
|
||||
}
|
||||
|
||||
private long countNumberOfAttributes(Attribute[] attrs) {
|
||||
return Stream.of(attrs)
|
||||
.filter(x -> x instanceof AnnotationDefault_attribute)
|
||||
private long countNumberOfAttributes(List<Attribute<?>> attrs) {
|
||||
return attrs.stream()
|
||||
.filter(x -> x instanceof AnnotationDefaultAttribute)
|
||||
.count();
|
||||
}
|
||||
|
||||
|
||||
@ -21,10 +21,10 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.AnnotationDefault_attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.constantpool.ConstantPoolBuilder;
|
||||
import jdk.internal.classfile.impl.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@ -51,13 +51,12 @@ public class AnnotationDefaultVerifier {
|
||||
verifiers.put((int) '@', new TestAnnotationElementValue());
|
||||
}
|
||||
|
||||
public void testLength(int tag, TestResult testResult, AnnotationDefault_attribute attr) {
|
||||
public void testLength(int tag, TestResult testResult, AnnotationDefaultAttribute attr) {
|
||||
verifiers.get(tag).testLength(testResult, attr);
|
||||
}
|
||||
|
||||
public void testElementValue(int tag, TestResult testResult, ClassFile classFile,
|
||||
Annotation.element_value element_value, String[] values)
|
||||
throws ConstantPool.UnexpectedEntry, ConstantPool.InvalidIndex {
|
||||
public void testElementValue(int tag, TestResult testResult, ClassModel classFile,
|
||||
AnnotationValue element_value, String[] values) {
|
||||
get(tag).testElementValue(testResult, classFile, element_value, values);
|
||||
}
|
||||
|
||||
@ -70,8 +69,10 @@ public class AnnotationDefaultVerifier {
|
||||
}
|
||||
|
||||
private abstract class TestElementValue {
|
||||
public void testLength(TestResult testCase, AnnotationDefault_attribute attr) {
|
||||
testCase.checkEquals(attr.attribute_length, 1 + attr.default_value.length(),
|
||||
public void testLength(TestResult testCase, AnnotationDefaultAttribute attr) {
|
||||
BufWriter buf = new BufWriterImpl(ConstantPoolBuilder.of(), (ClassfileImpl) Classfile.of());
|
||||
attr.defaultValue().writeTo(buf);
|
||||
testCase.checkEquals(((BoundAttribute<?>)attr).payloadLen(), buf.size(),
|
||||
"attribute_length");
|
||||
}
|
||||
|
||||
@ -85,10 +86,9 @@ public class AnnotationDefaultVerifier {
|
||||
|
||||
public abstract void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values)
|
||||
throws ConstantPool.InvalidIndex, ConstantPool.UnexpectedEntry;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values);
|
||||
}
|
||||
|
||||
private class TestIntegerElementValue extends TestElementValue {
|
||||
@ -96,15 +96,26 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values) throws ConstantPool.InvalidIndex {
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Integer_info info =
|
||||
(ConstantPool.CONSTANT_Integer_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testCase.checkEquals(info.value, Integer.parseInt(values[0]), "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
switch (element_value) {
|
||||
case AnnotationValue.OfByte ev -> {
|
||||
testCase.checkEquals((int)ev.byteValue(), Integer.parseInt(values[0]), "const_value_index");
|
||||
}
|
||||
case AnnotationValue.OfCharacter ev -> {
|
||||
testCase.checkEquals((int)ev.charValue(), Integer.parseInt(values[0]), "const_value_index");
|
||||
}
|
||||
case AnnotationValue.OfShort ev -> {
|
||||
testCase.checkEquals((int)ev.shortValue(), Integer.parseInt(values[0]), "const_value_index");
|
||||
}
|
||||
case AnnotationValue.OfBoolean ev -> {
|
||||
testCase.checkEquals(ev.booleanValue()? 1: 0, Integer.parseInt(values[0]), "const_value_index");
|
||||
}
|
||||
default -> {
|
||||
testCase.checkEquals(((AnnotationValue.OfInteger) element_value).intValue(), Integer.parseInt(values[0]), "const_value_index");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,15 +123,12 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values) throws ConstantPool.InvalidIndex {
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Long_info info =
|
||||
(ConstantPool.CONSTANT_Long_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testCase.checkEquals(info.value, Long.parseLong(values[0]), "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfLong ev =
|
||||
(AnnotationValue.OfLong) element_value;
|
||||
testCase.checkEquals(ev.longValue(), Long.parseLong(values[0]), "const_value_index");
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,15 +136,12 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values) throws ConstantPool.InvalidIndex {
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Float_info info =
|
||||
(ConstantPool.CONSTANT_Float_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testCase.checkEquals(info.value, Float.parseFloat(values[0]), "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfFloat ev =
|
||||
(AnnotationValue.OfFloat) element_value;
|
||||
testCase.checkEquals(ev.floatValue(), Float.parseFloat(values[0]), "const_value_index");
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,15 +149,12 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values) throws ConstantPool.InvalidIndex {
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Double_info info =
|
||||
(ConstantPool.CONSTANT_Double_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testCase.checkEquals(info.value, Double.parseDouble(values[0]), "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfDouble ev =
|
||||
(AnnotationValue.OfDouble) element_value;
|
||||
testCase.checkEquals(ev.doubleValue(), Double.parseDouble(values[0]), "const_value_index");
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,15 +162,12 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values) throws ConstantPool.InvalidIndex {
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Utf8_info info =
|
||||
(ConstantPool.CONSTANT_Utf8_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testCase.checkEquals(info.value, values[0], "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfString ev =
|
||||
(AnnotationValue.OfString) element_value;
|
||||
testCase.checkEquals(ev.stringValue(), values[0], "const_value_index");
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,14 +181,13 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values)
|
||||
throws ConstantPool.InvalidIndex, ConstantPool.UnexpectedEntry {
|
||||
Annotation.Enum_element_value ev = (Annotation.Enum_element_value) element_value;
|
||||
testCase.checkEquals(classFile.constant_pool.getUTF8Info(ev.type_name_index).value,
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfEnum ev = (AnnotationValue.OfEnum) element_value;
|
||||
testCase.checkEquals(ev.classSymbol().descriptorString(),
|
||||
values[0], "type_name_index");
|
||||
testCase.checkEquals(classFile.constant_pool.getUTF8Info(ev.const_name_index).value,
|
||||
testCase.checkEquals(ev.constantName().stringValue(),
|
||||
values[1], "const_name_index");
|
||||
}
|
||||
}
|
||||
@ -198,20 +196,19 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values)
|
||||
throws ConstantPool.InvalidIndex, ConstantPool.UnexpectedEntry {
|
||||
Annotation.Class_element_value ev = (Annotation.Class_element_value) element_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfClass ev = (AnnotationValue.OfClass) element_value;
|
||||
testCase.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(ev.class_info_index).value,
|
||||
ev.classSymbol().descriptorString(),
|
||||
values[0], "class_info_index");
|
||||
}
|
||||
}
|
||||
|
||||
private class TestAnnotationElementValue extends TestElementValue {
|
||||
@Override
|
||||
public void testLength(TestResult testCase, AnnotationDefault_attribute attr) {
|
||||
public void testLength(TestResult testCase, AnnotationDefaultAttribute attr) {
|
||||
// Suppress, since it is hard to test the length of this kind of element values.
|
||||
}
|
||||
|
||||
@ -225,60 +222,49 @@ public class AnnotationDefaultVerifier {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values)
|
||||
throws ConstantPool.InvalidIndex, ConstantPool.UnexpectedEntry {
|
||||
Annotation ev = ((Annotation.Annotation_element_value) element_value)
|
||||
.annotation_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
Annotation ev = ((AnnotationValue.OfAnnotation) element_value)
|
||||
.annotation();
|
||||
testCase.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(ev.type_index).value,
|
||||
ev.classSymbol().descriptorString(),
|
||||
values[0],
|
||||
"type_index");
|
||||
for (int i = 0; i < ev.num_element_value_pairs; ++i) {
|
||||
Annotation.element_value_pair pair = ev.element_value_pairs[i];
|
||||
for (int i = 0; i < ev.elements().size(); ++i) {
|
||||
AnnotationElement pair = ev.elements().get(i);
|
||||
testCase.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(pair.element_name_index).value,
|
||||
pair.name().stringValue(),
|
||||
values[2 * i + 1],
|
||||
"element_name_index");
|
||||
TestElementValue testElementValue = verifiers.get(pair.value.tag);
|
||||
TestElementValue testElementValue = verifiers.get((int)pair.value().tag());
|
||||
testElementValue.testElementValue(
|
||||
testCase,
|
||||
classFile,
|
||||
pair.value,
|
||||
pair.value(),
|
||||
new String[]{values[2 * i + 2]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TestArrayElementValue extends TestElementValue {
|
||||
@Override
|
||||
public void testLength(TestResult testCase, AnnotationDefault_attribute attr) {
|
||||
Annotation.Array_element_value ev =
|
||||
(Annotation.Array_element_value) attr.default_value;
|
||||
int sizeOfTag = ev.values[0].tag == 'e' ? 0 : 1;
|
||||
// tag (1 byte) + array header (2 byte) + length of entries
|
||||
testCase.checkEquals(attr.attribute_length, 1 + 2 +
|
||||
(sizeOfTag + ev.length() / ev.num_values) * ev.num_values, "attribute_length");
|
||||
}
|
||||
|
||||
// testLength method is the same as in TestElementValue class
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testCase,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value,
|
||||
String[] values)
|
||||
throws ConstantPool.InvalidIndex, ConstantPool.UnexpectedEntry {
|
||||
Annotation.Array_element_value ev =
|
||||
(Annotation.Array_element_value) element_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value,
|
||||
String[] values) {
|
||||
AnnotationValue.OfArray ev =
|
||||
(AnnotationValue.OfArray) element_value;
|
||||
int index = 0;
|
||||
for (int i = 0; i < ev.num_values; ++i) {
|
||||
TestElementValue testElementValue = verifiers.get(ev.values[i].tag);
|
||||
for (int i = 0; i < ev.values().size(); ++i) {
|
||||
TestElementValue testElementValue = verifiers.get((int)ev.values().get(i).tag());
|
||||
int length = testElementValue.getLength();
|
||||
testElementValue.testElementValue(
|
||||
testCase,
|
||||
classFile,
|
||||
ev.values[i],
|
||||
ev.values().get(i),
|
||||
testElementValue.getValues(values, index, length));
|
||||
index += length;
|
||||
}
|
||||
|
||||
@ -28,14 +28,19 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @run main EnclosingMethodTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.EnclosingMethod_attribute;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.EnclosingMethodAttribute;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
@ -140,10 +145,10 @@ public class EnclosingMethodTest extends TestResult {
|
||||
for (Class<?> clazz : noEnclosingMethod) {
|
||||
try {
|
||||
addTestCase("Class should not have EnclosingMethod attribute : " + clazz);
|
||||
ClassFile classFile = readClassFile(clazz);
|
||||
ClassModel classFile = readClassFile(clazz);
|
||||
checkEquals(countEnclosingMethodAttributes(classFile),
|
||||
0l, "number of the EnclosingMethod attribute in the class is zero : "
|
||||
+ classFile.getName());
|
||||
0L, "number of the EnclosingMethod attribute in the class is zero : "
|
||||
+ classFile.thisClass().name());
|
||||
} catch (Exception e) {
|
||||
addFailure(e);
|
||||
}
|
||||
@ -157,25 +162,24 @@ public class EnclosingMethodTest extends TestResult {
|
||||
+ (clazz.isAnonymousClass() ? "anonymous" : "local");
|
||||
addTestCase(info);
|
||||
printf("Testing test case : %s\n", info);
|
||||
ClassFile classFile = readClassFile(clazz);
|
||||
ClassModel classFile = readClassFile(clazz);
|
||||
String className = clazz.getName();
|
||||
checkEquals(countEnclosingMethodAttributes(classFile), 1l,
|
||||
"number of the EnclosingMethod attribute in the class is one : "
|
||||
+ clazz);
|
||||
EnclosingMethod_attribute attr = (EnclosingMethod_attribute)
|
||||
classFile.getAttribute(Attribute.EnclosingMethod);
|
||||
EnclosingMethodAttribute attr = classFile.findAttribute(Attributes.ENCLOSING_METHOD).orElse(null);
|
||||
|
||||
if (!checkNotNull(attr, "the EnclosingMethod attribute is not null : " + className)) {
|
||||
// stop checking, attr is null. test case failed
|
||||
return;
|
||||
}
|
||||
checkEquals(classFile.constant_pool.getUTF8Value(attr.attribute_name_index),
|
||||
checkEquals(attr.attributeName(),
|
||||
"EnclosingMethod",
|
||||
"attribute_name_index of EnclosingMethod attribute in the class : " + className);
|
||||
checkEquals(attr.attribute_length, 4,
|
||||
checkEquals(((BoundAttribute<?>)attr).payloadLen(), 4,
|
||||
"attribute_length of EnclosingMethod attribute in the class : " + className);
|
||||
String expectedClassName = enclosingMethod.enclosingClazz().getName();
|
||||
checkEquals(classFile.constant_pool.getClassInfo(attr.class_index).getName(),
|
||||
checkEquals(attr.enclosingClass().name().stringValue(),
|
||||
expectedClassName, String.format(
|
||||
"enclosing class of EnclosingMethod attribute in the class %s is %s",
|
||||
className, expectedClassName));
|
||||
@ -183,10 +187,10 @@ public class EnclosingMethodTest extends TestResult {
|
||||
String expectedMethodName = enclosingMethod.enclosingMethod();
|
||||
if (expectedMethodName.isEmpty()) {
|
||||
// class does not have an enclosing method
|
||||
checkEquals(attr.method_index, 0, String.format(
|
||||
checkEquals(attr.enclosingMethod().isPresent()? attr.enclosingMethod().get().index(): 0, 0, String.format(
|
||||
"enclosing method of EnclosingMethod attribute in the class %s is null", className));
|
||||
} else {
|
||||
String methodName = classFile.constant_pool.getNameAndTypeInfo(attr.method_index).getName();
|
||||
String methodName = attr.enclosingMethodName().get().stringValue() + attr.enclosingMethodType().get().stringValue();
|
||||
checkTrue(methodName.startsWith(expectedMethodName), String.format(
|
||||
"enclosing method of EnclosingMethod attribute in the class %s" +
|
||||
" is method name %s" +
|
||||
@ -199,9 +203,9 @@ public class EnclosingMethodTest extends TestResult {
|
||||
});
|
||||
}
|
||||
|
||||
private long countEnclosingMethodAttributes(ClassFile classFile) {
|
||||
return Stream.of(classFile.attributes.attrs)
|
||||
.filter(x -> x instanceof EnclosingMethod_attribute)
|
||||
private long countEnclosingMethodAttributes(ClassModel classFile) {
|
||||
return classFile.attributes().stream()
|
||||
.filter(x -> x instanceof EnclosingMethodAttribute)
|
||||
.count();
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase
|
||||
* @build LineNumberTestBase Container TestCase
|
||||
* @run main LineNumberTest
|
||||
|
||||
@ -21,7 +21,9 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Paths;
|
||||
@ -32,8 +34,6 @@ import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import static com.sun.tools.classfile.Attribute.Code;
|
||||
import static com.sun.tools.classfile.Attribute.LineNumberTable;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
@ -67,27 +67,28 @@ public class LineNumberTestBase extends TestBase {
|
||||
writeToFileIfEnabled(Paths.get(testCase.getName() + ".java"), testCase.src);
|
||||
Set<Integer> coveredLines = new HashSet<>();
|
||||
for (JavaFileObject file : compile(testCase.extraCompilerOptions, testCase.src).getClasses().values()) {
|
||||
ClassFile classFile;
|
||||
ClassModel classFile;
|
||||
try (InputStream input = file.openInputStream()) {
|
||||
classFile = ClassFile.read(input);
|
||||
classFile = Classfile.of().parse(input.readAllBytes());
|
||||
}
|
||||
for (Method m : classFile.methods) {
|
||||
Code_attribute code_attribute = (Code_attribute) m.attributes.get(Code);
|
||||
for (MethodModel m : classFile.methods()) {
|
||||
CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
|
||||
assert code_attribute != null;
|
||||
assertEquals(
|
||||
countAttributes(LineNumberTable, code_attribute.attributes.attrs, classFile.constant_pool),
|
||||
countAttributes(Attributes.LINE_NUMBER_TABLE, code_attribute),
|
||||
1,
|
||||
"Can be more than one LNT attribute, but javac should generate only one.");
|
||||
|
||||
LineNumberTable_attribute tableAttribute =
|
||||
(LineNumberTable_attribute) code_attribute.attributes.get(LineNumberTable);
|
||||
checkAttribute(testCase, tableAttribute, code_attribute.code_length);
|
||||
LineNumberTableAttribute tableAttribute = code_attribute.findAttribute(Attributes.LINE_NUMBER_TABLE).orElse(null);
|
||||
assert tableAttribute != null;
|
||||
checkAttribute(testCase, tableAttribute, code_attribute.codeLength());
|
||||
Set<Integer> methodCoveredLines =
|
||||
Stream.of(tableAttribute.line_number_table)
|
||||
.map(e -> e.line_number)
|
||||
tableAttribute.lineNumbers().stream()
|
||||
.map(LineNumberInfo::lineNumber)
|
||||
.collect(toSet());
|
||||
|
||||
TestCase.MethodData expected = testCase.findData(m.getName(classFile.constant_pool));
|
||||
TestCase.MethodData expected = testCase.findData(m.methodName().stringValue());
|
||||
|
||||
if (expected != null) {
|
||||
verifyCoveredLines(methodCoveredLines, expected);
|
||||
@ -134,26 +135,27 @@ public class LineNumberTestBase extends TestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private int countAttributes(String name, Attribute[] attrs, ConstantPool constant_pool) throws ConstantPoolException {
|
||||
private <T extends Attribute<T>> int countAttributes(AttributeMapper<T> attr, AttributedElement attributedElement) {
|
||||
int i = 0;
|
||||
for (Attribute attribute : attrs) {
|
||||
if (name.equals(attribute.getName(constant_pool))) {
|
||||
for (Attribute<?> attribute : attributedElement.attributes()) {
|
||||
if (attribute.attributeName().equals(attr.name())) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private void checkAttribute(TestCase testCase, LineNumberTable_attribute tableAttribute, int code_length) {
|
||||
assertEquals(tableAttribute.line_number_table_length, tableAttribute.line_number_table.length,
|
||||
"Incorrect line number table length.");
|
||||
private void checkAttribute(TestCase testCase, LineNumberTableAttribute tableAttribute, int code_length) {
|
||||
// This test is unnecessary
|
||||
// assertEquals(tableAttribute.line_number_table_length, tableAttribute.line_number_table.length,
|
||||
// "Incorrect line number table length.");
|
||||
//attribute length is offset(line_number_table_length) + element_size*element_count
|
||||
assertEquals(tableAttribute.attribute_length, 2 + 4 * tableAttribute.line_number_table_length,
|
||||
assertEquals(((BoundAttribute<?>)tableAttribute).payloadLen(), 2 + 4 * tableAttribute.lineNumbers().size(),
|
||||
"Incorrect attribute length");
|
||||
testNonEmptyLine(testCase.src.split("\n"), tableAttribute);
|
||||
assertEquals(
|
||||
Stream.of(tableAttribute.line_number_table)
|
||||
.filter(e -> e.start_pc >= code_length)
|
||||
tableAttribute.lineNumbers().stream()
|
||||
.filter(e -> e.startPc() >= code_length)
|
||||
.count()
|
||||
, 0L, "StartPC is out of bounds.");
|
||||
}
|
||||
@ -162,11 +164,11 @@ public class LineNumberTestBase extends TestBase {
|
||||
* Expects line number table point to non empty lines.
|
||||
* The method can't recognize commented lines as empty(insensible) in case of multiline comment.
|
||||
*/
|
||||
private void testNonEmptyLine(String[] source, LineNumberTable_attribute attribute) {
|
||||
for (LineNumberTable_attribute.Entry e : attribute.line_number_table) {
|
||||
String line = source[e.line_number - 1].trim();
|
||||
private void testNonEmptyLine(String[] source, LineNumberTableAttribute attribute) {
|
||||
for (LineNumberInfo e : attribute.lineNumbers()) {
|
||||
String line = source[e.lineNumber() - 1].trim();
|
||||
assertTrue(!("".equals(line) || line.startsWith("//") || line.startsWith("/*")),
|
||||
format("Expect that line #%d is not empty.%n", e.line_number));
|
||||
format("Expect that line #%d is not empty.%n", e.lineNumber()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase
|
||||
* @build LineNumberTestBase TestCase
|
||||
* @run main MultipleRecordPatterns
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase
|
||||
* @build LineNumberTestBase TestCase
|
||||
* @run main RuleSwitchBreaks
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase
|
||||
* @build LineNumberTestBase TestCase
|
||||
* @run main StringSwitchBreaks
|
||||
|
||||
@ -2,7 +2,12 @@
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8050993
|
||||
* @summary Verify that the condition in the conditional lexpression gets a LineNumberTable entry
|
||||
* @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
|
||||
* @compile -g T8050993.java
|
||||
* @run main T8050993
|
||||
*/
|
||||
@ -14,21 +19,24 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
public class T8050993 {
|
||||
public static void main(String[] args) throws IOException, ConstantPoolException {
|
||||
ClassFile someTestIn = ClassFile.read(T8050993.class.getResourceAsStream("T8050993.class"));
|
||||
public static void main(String[] args) throws IOException {
|
||||
ClassModel someTestIn = Classfile.of().parse(T8050993.class.getResourceAsStream("T8050993.class").readAllBytes());
|
||||
Set<Integer> expectedLineNumbers = new HashSet<>(Arrays.asList(49, 50, 47, 48));
|
||||
for (Method m : someTestIn.methods) {
|
||||
if ("method".equals(m.getName(someTestIn.constant_pool))) {
|
||||
Code_attribute code_attribute = (Code_attribute) m.attributes.get(Attribute.Code);
|
||||
for (Attribute at : code_attribute.attributes) {
|
||||
if (Attribute.LineNumberTable.equals(at.getName(someTestIn.constant_pool))) {
|
||||
LineNumberTable_attribute att = (LineNumberTable_attribute) at;
|
||||
Set<Integer> actualLinesNumbers = Arrays.stream(att.line_number_table)
|
||||
.map(e -> e.line_number)
|
||||
.collect(Collectors.toSet());
|
||||
for (MethodModel m : someTestIn.methods()) {
|
||||
if (m.methodName().equalsString("method")) {
|
||||
CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert code_attribute != null;
|
||||
for (Attribute<?> at : code_attribute.attributes()) {
|
||||
if (Attributes.LINE_NUMBER_TABLE.equals(at)) {
|
||||
assert at instanceof LineNumberTableAttribute;
|
||||
LineNumberTableAttribute att = (LineNumberTableAttribute) at;
|
||||
Set<Integer> actualLinesNumbers = Arrays.stream(att.lineNumbers().toArray(new LineNumberInfo[0]))
|
||||
.map(LineNumberInfo::lineNumber)
|
||||
.collect(Collectors.toSet());
|
||||
if (!Objects.equals(expectedLineNumbers, actualLinesNumbers)) {
|
||||
throw new AssertionError("Expected LineNumber entries not found;" +
|
||||
"actual=" + actualLinesNumbers + ";" +
|
||||
|
||||
@ -29,15 +29,20 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase
|
||||
* @build LocalVariableTestBase
|
||||
* @compile -g LocalVariableTableTest.java
|
||||
* @run main LocalVariableTableTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.LocalVariableTable_attribute;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@ -74,11 +79,11 @@ public class LocalVariableTableTest extends LocalVariableTestBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<VariableTable> getVariableTables(Code_attribute codeAttribute) {
|
||||
return Stream.of(codeAttribute.attributes.attrs)
|
||||
.filter(at -> at instanceof LocalVariableTable_attribute)
|
||||
.map(at -> (LocalVariableTable_attribute) at)
|
||||
.map((t) -> new LocalVariableTable(t)).collect(toList());
|
||||
protected List<VariableTable> getVariableTables(CodeAttribute codeAttribute) {
|
||||
return codeAttribute.attributes().stream()
|
||||
.filter(at -> at instanceof LocalVariableTableAttribute)
|
||||
.map(at -> (LocalVariableTableAttribute) at)
|
||||
.map(LocalVariableTable::new).collect(toList());
|
||||
}
|
||||
|
||||
@ExpectedLocals(name = "l", type = "J")
|
||||
@ -185,58 +190,58 @@ public class LocalVariableTableTest extends LocalVariableTestBase {
|
||||
|
||||
class LocalVariableTable implements VariableTable {
|
||||
|
||||
final LocalVariableTable_attribute att;
|
||||
final LocalVariableTableAttribute att;
|
||||
|
||||
public LocalVariableTable(LocalVariableTable_attribute att) {
|
||||
public LocalVariableTable(LocalVariableTableAttribute att) {
|
||||
this.att = att;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int localVariableTableLength() {
|
||||
return att.local_variable_table_length;
|
||||
return att.localVariables().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entry> entries() {
|
||||
return Stream.of(att.local_variable_table).map(LocalVariableTableEntry::new).collect(toList());
|
||||
return att.localVariables().stream().map(LocalVariableTableEntry::new).collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attributeLength() {
|
||||
return att.attribute_length;
|
||||
return ((BoundAttribute<?>) att).payloadLen();
|
||||
}
|
||||
|
||||
private class LocalVariableTableEntry implements Entry {
|
||||
|
||||
final LocalVariableTable_attribute.Entry entry;
|
||||
final LocalVariableInfo entry;
|
||||
|
||||
private LocalVariableTableEntry(LocalVariableTable_attribute.Entry entry) {
|
||||
private LocalVariableTableEntry(LocalVariableInfo entry) {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index() {
|
||||
return entry.index;
|
||||
return entry.slot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startPC() {
|
||||
return entry.start_pc;
|
||||
return entry.startPc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return entry.length;
|
||||
return entry.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return getString(entry.name_index);
|
||||
return entry.name().stringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return getString(entry.descriptor_index);
|
||||
return entry.type().stringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Repeatable;
|
||||
@ -50,7 +51,7 @@ import static java.util.stream.Collectors.*;
|
||||
*/
|
||||
public abstract class LocalVariableTestBase extends TestBase {
|
||||
public static final int DEFAULT_SCOPE = 0;
|
||||
private final ClassFile classFile;
|
||||
private final ClassModel classFile;
|
||||
private final Class<?> clazz;
|
||||
|
||||
/**
|
||||
@ -59,13 +60,13 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
public LocalVariableTestBase(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
try {
|
||||
this.classFile = ClassFile.read(getClassFile(clazz));
|
||||
} catch (IOException | ConstantPoolException e) {
|
||||
this.classFile = Classfile.of().parse(getClassFile(clazz).toPath());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("Can't read classfile for specified class", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<VariableTable> getVariableTables(Code_attribute codeAttribute);
|
||||
protected abstract List<VariableTable> getVariableTables(CodeAttribute codeAttribute);
|
||||
|
||||
/**
|
||||
* Finds expected variables with their type in VariableTable.
|
||||
@ -74,7 +75,7 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
public void test() throws IOException {
|
||||
List<java.lang.reflect.Method> testMethods = Stream.of(clazz.getDeclaredMethods())
|
||||
.filter(m -> m.getAnnotationsByType(ExpectedLocals.class).length > 0)
|
||||
.collect(toList());
|
||||
.toList();
|
||||
int failed = 0;
|
||||
for (java.lang.reflect.Method method : testMethods) {
|
||||
try {
|
||||
@ -99,12 +100,12 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
public void test(String methodName, Map<String, String> expectedLocals2Types, Map<String, Integer> sig2scope)
|
||||
throws IOException {
|
||||
|
||||
for (Method m : classFile.methods) {
|
||||
String mName = getString(m.name_index);
|
||||
for (MethodModel m : classFile.methods()) {
|
||||
String mName = m.methodName().stringValue();
|
||||
if (methodName.equals(mName)) {
|
||||
System.out.println("Testing local variable table in method " + mName);
|
||||
Code_attribute code_attribute = (Code_attribute) m.attributes.get(Attribute.Code);
|
||||
|
||||
CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElse(null);
|
||||
assert code_attribute != null;
|
||||
List<? extends VariableTable> variableTables = getVariableTables(code_attribute);
|
||||
generalLocalVariableTableCheck(variableTables);
|
||||
|
||||
@ -115,7 +116,7 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
generalEntriesCheck(entries, code_attribute);
|
||||
assertIndexesAreUnique(entries, sig2scope);
|
||||
checkNamesAndTypes(entries, expectedLocals2Types);
|
||||
checkDoubleAndLongIndexes(entries, sig2scope, code_attribute.max_locals);
|
||||
checkDoubleAndLongIndexes(entries, sig2scope, code_attribute.maxLocals());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,17 +132,17 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private void generalEntriesCheck(List<VariableTable.Entry> entries, Code_attribute code_attribute) {
|
||||
private void generalEntriesCheck(List<VariableTable.Entry> entries, CodeAttribute code_attribute) {
|
||||
for (VariableTable.Entry e : entries) {
|
||||
assertTrue(e.index() >= 0 && e.index() < code_attribute.max_locals,
|
||||
"Index " + e.index() + " out of variable array. Size of array is " + code_attribute.max_locals);
|
||||
assertTrue(e.index() >= 0 && e.index() < code_attribute.maxLocals(),
|
||||
"Index " + e.index() + " out of variable array. Size of array is " + code_attribute.maxLocals());
|
||||
assertTrue(e.startPC() >= 0, "StartPC is less then 0. StartPC = " + e.startPC());
|
||||
assertTrue(e.length() >= 0, "Length is less then 0. Length = " + e.length());
|
||||
assertTrue(e.startPC() + e.length() <= code_attribute.code_length,
|
||||
assertTrue(e.startPC() + e.length() <= code_attribute.codeLength(),
|
||||
format("StartPC+Length > code length.%n" +
|
||||
"%s%n" +
|
||||
"code_length = %s"
|
||||
, e, code_attribute.code_length));
|
||||
, e, code_attribute.codeLength()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,14 +206,15 @@ public abstract class LocalVariableTestBase extends TestBase {
|
||||
return entries.stream().collect(groupingBy(e -> scopes.getOrDefault(e.name() + "&" + e.type(), DEFAULT_SCOPE)));
|
||||
}
|
||||
|
||||
protected String getString(int i) {
|
||||
try {
|
||||
return classFile.constant_pool.getUTF8Info(i).value;
|
||||
} catch (ConstantPool.InvalidIndex | ConstantPool.UnexpectedEntry ex) {
|
||||
ex.printStackTrace();
|
||||
throw new AssertionFailedException("Issue while reading constant pool");
|
||||
}
|
||||
}
|
||||
// Don't need the getString method now
|
||||
// protected String getString(int i) {
|
||||
// try {
|
||||
// return classFile.constant_pool.getUTF8Info(i).value;
|
||||
// } catch (ConstantPool.InvalidIndex | ConstantPool.UnexpectedEntry ex) {
|
||||
// ex.printStackTrace();
|
||||
// throw new AssertionFailedException("Issue while reading constant pool");
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* LocalVariableTable and LocalVariableTypeTable are similar.
|
||||
|
||||
@ -29,14 +29,19 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase LocalVariableTestBase
|
||||
* @compile -g LocalVariableTypeTableTest.java
|
||||
* @run main LocalVariableTypeTableTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
@ -58,10 +63,10 @@ public class LocalVariableTypeTableTest<THIS> extends LocalVariableTestBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<VariableTable> getVariableTables(Code_attribute codeAttribute) {
|
||||
return Stream.of(codeAttribute.attributes.attrs)
|
||||
.filter(at -> at instanceof LocalVariableTypeTable_attribute)
|
||||
.map(at -> (LocalVariableTypeTable_attribute) at)
|
||||
protected List<VariableTable> getVariableTables(CodeAttribute codeAttribute) {
|
||||
return codeAttribute.attributes().stream()
|
||||
.filter(at -> at instanceof LocalVariableTypeTableAttribute)
|
||||
.map(at -> (LocalVariableTypeTableAttribute) at)
|
||||
.map(LocalVariableTypeTable::new).collect(toList());
|
||||
}
|
||||
|
||||
@ -135,59 +140,59 @@ public class LocalVariableTypeTableTest<THIS> extends LocalVariableTestBase {
|
||||
|
||||
class LocalVariableTypeTable implements VariableTable {
|
||||
|
||||
final LocalVariableTypeTable_attribute att;
|
||||
final LocalVariableTypeTableAttribute att;
|
||||
|
||||
|
||||
public LocalVariableTypeTable(LocalVariableTypeTable_attribute att) {
|
||||
public LocalVariableTypeTable(LocalVariableTypeTableAttribute att) {
|
||||
this.att = att;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int localVariableTableLength() {
|
||||
return att.local_variable_table_length;
|
||||
return att.localVariableTypes().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entry> entries() {
|
||||
return Stream.of(att.local_variable_table).map(LocalVariableTypeTableEntry::new).collect(toList());
|
||||
return att.localVariableTypes().stream().map(LocalVariableTypeTableEntry::new).collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attributeLength() {
|
||||
return att.attribute_length;
|
||||
return ((BoundAttribute<?>)att).payloadLen();
|
||||
}
|
||||
|
||||
private class LocalVariableTypeTableEntry implements Entry {
|
||||
|
||||
final LocalVariableTypeTable_attribute.Entry entry;
|
||||
final LocalVariableTypeInfo entry;
|
||||
|
||||
private LocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry) {
|
||||
private LocalVariableTypeTableEntry(LocalVariableTypeInfo entry) {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index() {
|
||||
return entry.index;
|
||||
return entry.slot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startPC() {
|
||||
return entry.start_pc;
|
||||
return entry.startPc();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return entry.length;
|
||||
return entry.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return getString(entry.name_index);
|
||||
return entry.name().stringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String type() {
|
||||
return getString(entry.signature_index);
|
||||
return entry.signature().stringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -29,14 +29,19 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox toolbox.JavacTask toolbox.ToolBox
|
||||
* @run main ModuleFlagTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import jdk.internal.classfile.AccessFlags;
|
||||
import jdk.internal.classfile.Classfile;
|
||||
import java.lang.reflect.AccessFlag;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
@ -46,7 +51,7 @@ import toolbox.JavacTask;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class ModuleFlagTest {
|
||||
public static void main(String[] args) throws IOException, ConstantPoolException {
|
||||
public static void main(String[] args) throws IOException {
|
||||
Path outdir = Paths.get(".");
|
||||
ToolBox tb = new ToolBox();
|
||||
final Path moduleInfo = Paths.get("module-info.java");
|
||||
@ -56,9 +61,9 @@ public class ModuleFlagTest {
|
||||
.files(moduleInfo)
|
||||
.run();
|
||||
|
||||
AccessFlags accessFlags = ClassFile.read(outdir.resolve("module-info.class"))
|
||||
.access_flags;
|
||||
if (!accessFlags.is(AccessFlags.ACC_MODULE)) {
|
||||
AccessFlags accessFlags = Classfile.of().parse(outdir.resolve("module-info.class"))
|
||||
.flags();
|
||||
if (!accessFlags.has(AccessFlag.MODULE)) {
|
||||
throw new RuntimeException("Classfile doesn't have module access flag");
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib ../lib /tools/javac/lib
|
||||
* @build toolbox.ToolBox toolbox.JavacTask toolbox.ToolBox
|
||||
* TestBase TestResult ModuleTestBase
|
||||
|
||||
@ -21,10 +21,9 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Module_attribute;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -70,98 +69,101 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
protected void testModuleAttribute(Path modulePath, ModuleDescriptor moduleDescriptor) throws Exception {
|
||||
ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
|
||||
Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
|
||||
ConstantPool constantPool = classFile.constant_pool;
|
||||
testModuleName(moduleDescriptor, moduleAttribute, constantPool);
|
||||
ClassModel classFile = Classfile.of().parse(modulePath.resolve("module-info.class"));
|
||||
ModuleAttribute moduleAttribute = classFile.findAttribute(Attributes.MODULE).orElse(null);
|
||||
assert moduleAttribute != null;
|
||||
testModuleName(moduleDescriptor, moduleAttribute);
|
||||
testModuleFlags(moduleDescriptor, moduleAttribute);
|
||||
testRequires(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testExports(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testOpens(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testProvides(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testUses(moduleDescriptor, moduleAttribute, constantPool);
|
||||
testRequires(moduleDescriptor, moduleAttribute);
|
||||
testExports(moduleDescriptor, moduleAttribute);
|
||||
testOpens(moduleDescriptor, moduleAttribute);
|
||||
testProvides(moduleDescriptor, moduleAttribute);
|
||||
testUses(moduleDescriptor, moduleAttribute);
|
||||
}
|
||||
|
||||
private void testModuleName(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(constantPool.getModuleInfo(module.module_name).getName(), moduleDescriptor.name, "Unexpected module name");
|
||||
private void testModuleName(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.moduleName().name().stringValue(), moduleDescriptor.name, "Unexpected module name");
|
||||
}
|
||||
|
||||
private void testModuleFlags(ModuleDescriptor moduleDescriptor, Module_attribute module) {
|
||||
tr.checkEquals(module.module_flags, moduleDescriptor.flags, "Unexpected module flags");
|
||||
private void testModuleFlags(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.moduleFlagsMask(), moduleDescriptor.flags, "Unexpected module flags");
|
||||
}
|
||||
|
||||
private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires.");
|
||||
private void testRequires(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.requires().size(), moduleDescriptor.requires.size(), "Wrong amount of requires.");
|
||||
|
||||
List<Requires> actualRequires = new ArrayList<>();
|
||||
for (Module_attribute.RequiresEntry require : module.requires) {
|
||||
for (ModuleRequireInfo require : module.requires()) {
|
||||
actualRequires.add(new Requires(
|
||||
require.getRequires(constantPool),
|
||||
require.requires_flags));
|
||||
require.requires().name().stringValue(),
|
||||
require.requiresFlagsMask()));
|
||||
}
|
||||
tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
|
||||
}
|
||||
|
||||
private void testExports(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.exports_count, moduleDescriptor.exports.size(), "Wrong amount of exports.");
|
||||
for (Module_attribute.ExportsEntry export : module.exports) {
|
||||
String pkg = constantPool.getPackageInfo(export.exports_index).getName();
|
||||
private void testExports(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.exports().size(), moduleDescriptor.exports.size(), "Wrong amount of exports.");
|
||||
for (ModuleExportInfo export : module.exports()) {
|
||||
String pkg = export.exportedPackage().name().stringValue();
|
||||
if (tr.checkTrue(moduleDescriptor.exports.containsKey(pkg), "Unexpected export " + pkg)) {
|
||||
Export expectedExport = moduleDescriptor.exports.get(pkg);
|
||||
tr.checkEquals(expectedExport.mask, export.exports_flags, "Wrong export flags");
|
||||
tr.checkEquals(expectedExport.mask, export.exportsFlagsMask(), "Wrong export flags");
|
||||
List<String> expectedTo = expectedExport.to;
|
||||
tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
|
||||
tr.checkEquals(export.exportsTo().size(), expectedTo.size(), "Wrong amount of exports to");
|
||||
List<String> actualTo = new ArrayList<>();
|
||||
for (int toIdx : export.exports_to_index) {
|
||||
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
|
||||
for (ModuleEntry toIdx : export.exportsTo()) {
|
||||
actualTo.add(toIdx.name().stringValue());
|
||||
}
|
||||
tr.checkContains(actualTo, expectedTo, "Lists of \"exports to\" don't match.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testOpens(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.opens_count, moduleDescriptor.opens.size(), "Wrong amount of opens.");
|
||||
for (Module_attribute.OpensEntry open : module.opens) {
|
||||
String pkg = constantPool.getPackageInfo(open.opens_index).getName();
|
||||
private void testOpens(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.opens().size(), moduleDescriptor.opens.size(), "Wrong amount of opens.");
|
||||
for (ModuleOpenInfo open : module.opens()) {
|
||||
String pkg = open.openedPackage().name().stringValue();
|
||||
if (tr.checkTrue(moduleDescriptor.opens.containsKey(pkg), "Unexpected open " + pkg)) {
|
||||
Open expectedOpen = moduleDescriptor.opens.get(pkg);
|
||||
tr.checkEquals(expectedOpen.mask, open.opens_flags, "Wrong open flags");
|
||||
tr.checkEquals(expectedOpen.mask, open.opensFlagsMask(), "Wrong open flags");
|
||||
List<String> expectedTo = expectedOpen.to;
|
||||
tr.checkEquals(open.opens_to_count, expectedTo.size(), "Wrong amount of opens to");
|
||||
tr.checkEquals(open.opensTo().size(), expectedTo.size(), "Wrong amount of opens to");
|
||||
List<String> actualTo = new ArrayList<>();
|
||||
for (int toIdx : open.opens_to_index) {
|
||||
actualTo.add(constantPool.getModuleInfo(toIdx).getName());
|
||||
for (ModuleEntry toIdx : open.opensTo()) {
|
||||
actualTo.add(toIdx.name().stringValue());
|
||||
}
|
||||
tr.checkContains(actualTo, expectedTo, "Lists of \"opens to\" don't match.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
|
||||
private void testUses(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
tr.checkEquals(module.uses().size(), moduleDescriptor.uses.size(), "Wrong amount of uses.");
|
||||
List<String> actualUses = new ArrayList<>();
|
||||
for (int usesIdx : module.uses_index) {
|
||||
String uses = constantPool.getClassInfo(usesIdx).getBaseName();
|
||||
for (ClassEntry usesIdx : module.uses()) {
|
||||
if (!usesIdx.asSymbol().isClassOrInterface()) continue; //get basename
|
||||
String uses = usesIdx.asInternalName();
|
||||
actualUses.add(uses);
|
||||
}
|
||||
tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
|
||||
}
|
||||
|
||||
private void testProvides(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
|
||||
int moduleProvidesCount = Arrays.asList(module.provides).stream()
|
||||
.mapToInt(e -> e.with_index.length)
|
||||
private void testProvides(ModuleDescriptor moduleDescriptor, ModuleAttribute module) {
|
||||
int moduleProvidesCount = module.provides().stream()
|
||||
.mapToInt(e -> e.providesWith().size())
|
||||
.sum();
|
||||
int moduleDescriptorProvidesCount = moduleDescriptor.provides.values().stream()
|
||||
.mapToInt(impls -> impls.size())
|
||||
.sum();
|
||||
tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
|
||||
Map<String, List<String>> actualProvides = new HashMap<>();
|
||||
for (Module_attribute.ProvidesEntry provide : module.provides) {
|
||||
String provides = constantPool.getClassInfo(provide.provides_index).getBaseName();
|
||||
for (ModuleProvideInfo provide : module.provides()) {
|
||||
if (!provide.provides().asSymbol().isClassOrInterface()) continue;
|
||||
String provides = provide.provides().asInternalName();
|
||||
List<String> impls = new ArrayList<>();
|
||||
for (int i = 0; i < provide.with_count; i++) {
|
||||
String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName();
|
||||
for (ClassEntry withEntry: provide.providesWith()) {
|
||||
if (!withEntry.asSymbol().isClassOrInterface()) continue;
|
||||
String with = withEntry.asInternalName();
|
||||
impls.add(with);
|
||||
}
|
||||
actualProvides.put(provides, impls);
|
||||
@ -191,7 +193,7 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public enum ModuleFlag implements Mask {
|
||||
OPEN("open", Module_attribute.ACC_OPEN);
|
||||
OPEN("open", Classfile.ACC_OPEN);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
@ -208,9 +210,9 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public enum RequiresFlag implements Mask {
|
||||
TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE),
|
||||
STATIC("static", Module_attribute.ACC_STATIC_PHASE),
|
||||
MANDATED("", Module_attribute.ACC_MANDATED);
|
||||
TRANSITIVE("transitive", Classfile.ACC_TRANSITIVE),
|
||||
STATIC("static", Classfile.ACC_STATIC_PHASE),
|
||||
MANDATED("", Classfile.ACC_MANDATED);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
@ -227,7 +229,7 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public enum ExportsFlag implements Mask {
|
||||
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
|
||||
SYNTHETIC("", Classfile.ACC_SYNTHETIC);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
@ -244,7 +246,7 @@ public class ModuleTestBase {
|
||||
}
|
||||
|
||||
public enum OpensFlag implements Mask {
|
||||
SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
|
||||
SYNTHETIC("", Classfile.ACC_SYNTHETIC);
|
||||
|
||||
private final String token;
|
||||
private final int mask;
|
||||
@ -326,7 +328,7 @@ public class ModuleTestBase {
|
||||
|
||||
private static final String LINE_END = ";\n";
|
||||
|
||||
StringBuilder content = new StringBuilder("");
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
||||
public ModuleDescriptor(String moduleName, ModuleFlag... flags) {
|
||||
this.name = moduleName;
|
||||
@ -370,7 +372,7 @@ public class ModuleTestBase {
|
||||
List<String> tos = Pattern.compile(",")
|
||||
.splitAsStream(to)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
this.exports.compute(toInternalForm(pkg), (k,v) -> new Export(k, computeMask(flags)))
|
||||
.to.addAll(tos);
|
||||
|
||||
@ -396,7 +398,7 @@ public class ModuleTestBase {
|
||||
List<String> tos = Pattern.compile(",")
|
||||
.splitAsStream(to)
|
||||
.map(String::trim)
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
this.opens.compute(toInternalForm(pkg), (k,v) -> new Open(toInternalForm(k), computeMask(flags)))
|
||||
.to.addAll(tos);
|
||||
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build ConstructorTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver ConstructorTest
|
||||
|
||||
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.Field;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.SignatureAttribute;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
@ -34,6 +35,7 @@ import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.lang.reflect.AccessFlag;
|
||||
|
||||
/**
|
||||
* The main class of Signature tests.
|
||||
@ -49,9 +51,6 @@ import java.util.stream.Stream;
|
||||
* of ExpectedSignature must return true.
|
||||
*/
|
||||
public class Driver extends TestResult {
|
||||
|
||||
private final static String ACC_BRIDGE = "ACC_BRIDGE";
|
||||
|
||||
private final String topLevelClassName;
|
||||
private final File[] files;
|
||||
|
||||
@ -78,7 +77,7 @@ public class Driver extends TestResult {
|
||||
// is located in its enclosing class.
|
||||
boolean isAnonymous = isAnonymous(className);
|
||||
clazz = isAnonymous ? getEnclosingClass(className) : clazz;
|
||||
return Stream.of(clazz.getAnnotationsByType(ExpectedSignature.class))
|
||||
return Arrays.stream(clazz.getAnnotationsByType(ExpectedSignature.class))
|
||||
.filter(s -> s.isAnonymous() == isAnonymous)
|
||||
.collect(Collectors.toMap(ExpectedSignature::descriptor, Function.identity()))
|
||||
.get(className);
|
||||
@ -97,7 +96,7 @@ public class Driver extends TestResult {
|
||||
|
||||
private Map<String, ExpectedSignature> getExpectedExecutableSignatures(Executable[] executables,
|
||||
Predicate<Executable> filterBridge) {
|
||||
return Stream.of(executables)
|
||||
return Arrays.stream(executables)
|
||||
.filter(filterBridge)
|
||||
.map(e -> e.getAnnotation(ExpectedSignature.class))
|
||||
.filter(Objects::nonNull)
|
||||
@ -115,7 +114,7 @@ public class Driver extends TestResult {
|
||||
}
|
||||
|
||||
private Map<String, ExpectedSignature> getExpectedFieldSignatures(Class<?> clazz) {
|
||||
return Stream.of(clazz.getDeclaredFields())
|
||||
return Arrays.stream(clazz.getDeclaredFields())
|
||||
.map(f -> f.getAnnotation(ExpectedSignature.class))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(ExpectedSignature::descriptor, Function.identity()));
|
||||
@ -130,13 +129,12 @@ public class Driver extends TestResult {
|
||||
String className = file.getName().replace(".class", "");
|
||||
Class<?> clazz = Class.forName(className);
|
||||
printf("Testing class %s\n", className);
|
||||
ClassFile classFile = readClassFile(file);
|
||||
ClassModel classFile = readClassFile(file);
|
||||
|
||||
// test class signature
|
||||
testAttribute(
|
||||
className,
|
||||
classFile,
|
||||
() -> (Signature_attribute) classFile.getAttribute(Attribute.Signature),
|
||||
() -> classFile.findAttribute(Attributes.SIGNATURE).orElse(null),
|
||||
getClassExpectedSignature(className, clazz).get(className));
|
||||
|
||||
testFields(getExpectedFieldSignatures(clazz), classFile);
|
||||
@ -163,21 +161,19 @@ public class Driver extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private void testMethods(Map<String, ExpectedSignature> expectedSignatures, ClassFile classFile)
|
||||
throws ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
String className = classFile.getName();
|
||||
private void testMethods(Map<String, ExpectedSignature> expectedSignatures, ClassModel classFile) {
|
||||
String className = classFile.thisClass().name().stringValue();
|
||||
Set<String> foundMethods = new HashSet<>();
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = getMethodName(classFile, method);
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
String methodName = getMethodName(method);
|
||||
printf("Testing method %s\n", methodName);
|
||||
if (method.access_flags.getMethodFlags().contains(ACC_BRIDGE)) {
|
||||
if (method.flags().has(AccessFlag.BRIDGE)) {
|
||||
printf("Bridge method is skipped : %s\n", methodName);
|
||||
continue;
|
||||
}
|
||||
testAttribute(
|
||||
methodName,
|
||||
classFile,
|
||||
() -> (Signature_attribute) method.attributes.get(Attribute.Signature),
|
||||
() -> method.findAttribute(Attributes.SIGNATURE).orElse(null),
|
||||
expectedSignatures.get(methodName));
|
||||
foundMethods.add(methodName);
|
||||
}
|
||||
@ -185,24 +181,30 @@ public class Driver extends TestResult {
|
||||
"Checking that all methods of class " + className + " with Signature attribute found");
|
||||
}
|
||||
|
||||
private String getMethodName(ClassFile classFile, Method method)
|
||||
throws ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
return String.format("%s%s",
|
||||
method.getName(classFile.constant_pool),
|
||||
method.descriptor.getParameterTypes(classFile.constant_pool));
|
||||
private String getMethodName(MethodModel method) {
|
||||
StringBuilder methodName = new StringBuilder(method.methodName().stringValue() + "(");
|
||||
List<ClassDesc> paras = method.methodTypeSymbol().parameterList();
|
||||
for (int i = 0; i < method.methodTypeSymbol().parameterCount(); ++i) {
|
||||
if (i != 0) {
|
||||
methodName.append(", ");
|
||||
}
|
||||
ClassDesc para = paras.get(i);
|
||||
String prefix = para.componentType() == null? para.packageName(): para.componentType().packageName();
|
||||
methodName.append(prefix).append(Objects.equals(prefix, "") ? "":".").append(para.displayName());
|
||||
}
|
||||
methodName.append(")");
|
||||
return methodName.toString();
|
||||
}
|
||||
|
||||
private void testFields(Map<String, ExpectedSignature> expectedSignatures, ClassFile classFile)
|
||||
throws ConstantPoolException {
|
||||
String className = classFile.getName();
|
||||
private void testFields(Map<String, ExpectedSignature> expectedSignatures, ClassModel classFile) {
|
||||
String className = classFile.thisClass().name().stringValue();
|
||||
Set<String> foundFields = new HashSet<>();
|
||||
for (Field field : classFile.fields) {
|
||||
String fieldName = field.getName(classFile.constant_pool);
|
||||
for (FieldModel field : classFile.fields()) {
|
||||
String fieldName = field.fieldName().stringValue();
|
||||
printf("Testing field %s\n", fieldName);
|
||||
testAttribute(
|
||||
fieldName,
|
||||
classFile,
|
||||
() -> (Signature_attribute) field.attributes.get(Attribute.Signature),
|
||||
() -> field.findAttribute(Attributes.SIGNATURE).orElse(null),
|
||||
expectedSignatures.get(fieldName));
|
||||
foundFields.add(fieldName);
|
||||
}
|
||||
@ -212,17 +214,15 @@ public class Driver extends TestResult {
|
||||
|
||||
private void testAttribute(
|
||||
String memberName,
|
||||
ClassFile classFile,
|
||||
Supplier<Signature_attribute> sup,
|
||||
ExpectedSignature expectedSignature)
|
||||
throws ConstantPoolException {
|
||||
Supplier<SignatureAttribute> sup,
|
||||
ExpectedSignature expectedSignature) {
|
||||
|
||||
Signature_attribute attribute = sup.get();
|
||||
SignatureAttribute attribute = sup.get();
|
||||
if (expectedSignature != null && checkNotNull(attribute, memberName + " must have attribute")) {
|
||||
checkEquals(classFile.constant_pool.getUTF8Value(attribute.attribute_name_index),
|
||||
checkEquals(attribute.attributeName(),
|
||||
"Signature", "Attribute's name : " + memberName);
|
||||
checkEquals(attribute.attribute_length, 2, "Attribute's length : " + memberName);
|
||||
checkEquals(attribute.getSignature(classFile.constant_pool),
|
||||
checkEquals(((BoundAttribute<?>)attribute).payloadLen(), 2, "Attribute's length : " + memberName);
|
||||
checkEquals(attribute.signature().stringValue(),
|
||||
expectedSignature.signature(),
|
||||
"Testing signature of : " + memberName);
|
||||
} else {
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build EnumTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver EnumTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build ExceptionTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver ExceptionTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build FieldTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver FieldTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver InnerClassTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build MethodParameterTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver MethodParameterTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build MethodTypeBoundTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver MethodTypeBoundTest
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* @modules java.desktop
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build ReturnTypeTest Driver ExpectedSignature ExpectedSignatureContainer
|
||||
* @run main Driver ReturnTypeTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main AnonymousClassTest
|
||||
*/
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main InnerClassTest
|
||||
*/
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main LocalClassTest
|
||||
*/
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main MixTest
|
||||
*/
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox toolbox.JavacTask InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main ModuleInfoTest
|
||||
*/
|
||||
|
||||
@ -28,15 +28,19 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @compile -g:none NoSourceFileAttribute.java
|
||||
* @run main NoSourceFileAttribute
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -46,9 +50,9 @@ public class NoSourceFileAttribute extends TestBase {
|
||||
new NoSourceFileAttribute().test();
|
||||
}
|
||||
|
||||
public void test() throws IOException, ConstantPoolException {
|
||||
public void test() throws IOException {
|
||||
assertNull(
|
||||
ClassFile.read(getClassFile(NoSourceFileAttribute.class)).getAttribute(Attribute.SourceFile),
|
||||
Classfile.of().parse(getClassFile(NoSourceFileAttribute.class).toPath()).findAttribute(Attributes.SOURCE_FILE).orElse(null),
|
||||
"Classfile should have no SourceFile attribute when compiled without debug information.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,9 +21,9 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.SourceFileAttribute;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
@ -50,7 +50,7 @@ public class SourceFileTestBase extends TestBase {
|
||||
* @param fileName expected name of the file from which the test file is compiled.
|
||||
*/
|
||||
protected void test(Class<?> classToTest, String fileName) throws Exception {
|
||||
assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName);
|
||||
assertAttributePresent(Classfile.of().parse(getClassFile(classToTest).toPath()), fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +60,7 @@ public class SourceFileTestBase extends TestBase {
|
||||
* @param fileName expected name of the file from which the test file is compiled.
|
||||
*/
|
||||
protected void test(String classToTest, String fileName) throws Exception {
|
||||
assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName);
|
||||
assertAttributePresent(Classfile.of().parse(getClassFile(classToTest + ".class").toPath()), fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +70,7 @@ public class SourceFileTestBase extends TestBase {
|
||||
* @param fileName expected name of the file from which the test file is compiled.
|
||||
*/
|
||||
protected void test(Path classToTest, String fileName) throws Exception {
|
||||
assertAttributePresent(ClassFile.read(classToTest), fileName);
|
||||
assertAttributePresent(Classfile.of().parse(classToTest), fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,33 +85,32 @@ public class SourceFileTestBase extends TestBase {
|
||||
Map<String, ? extends JavaFileObject> classes = compile(sourceCode).getClasses();
|
||||
String fileName = ToolBox.getJavaFileNameFromSource(sourceCode);
|
||||
for (String className : classesToTest) {
|
||||
ClassFile classFile;
|
||||
ClassModel classFile;
|
||||
try (InputStream input = classes.get(className).openInputStream()) {
|
||||
classFile = ClassFile.read(input);
|
||||
classFile = Classfile.of().parse(input.readAllBytes());
|
||||
}
|
||||
assertAttributePresent(classFile, fileName);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertAttributePresent(ClassFile classFile, String fileName) throws Exception {
|
||||
private void assertAttributePresent(ClassModel classFile, String fileName) throws Exception {
|
||||
|
||||
//We need to count attributes with the same names because there is no appropriate API in the ClassFile.
|
||||
|
||||
List<SourceFile_attribute> sourceFileAttributes = new ArrayList<>();
|
||||
for (Attribute a : classFile.attributes.attrs) {
|
||||
if (Attribute.SourceFile.equals(a.getName(classFile.constant_pool))) {
|
||||
sourceFileAttributes.add((SourceFile_attribute) a);
|
||||
List<SourceFileAttribute> sourceFileAttributes = new ArrayList<>();
|
||||
for (Attribute<?> a : classFile.attributes()) {
|
||||
if (a instanceof SourceFileAttribute) {
|
||||
sourceFileAttributes.add((SourceFileAttribute) a);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(sourceFileAttributes.size(), 1, "Should be the only SourceFile attribute");
|
||||
|
||||
SourceFile_attribute attribute = sourceFileAttributes.get(0);
|
||||
SourceFileAttribute attribute = sourceFileAttributes.get(0);
|
||||
|
||||
assertEquals(classFile.constant_pool.getUTF8Info(attribute.attribute_name_index).value,
|
||||
Attribute.SourceFile, "Incorrect attribute name");
|
||||
assertEquals(classFile.constant_pool.getUTF8Info(attribute.sourcefile_index).value, fileName,
|
||||
assertEquals(attribute.attributeName(), Attributes.SOURCE_FILE.name(), "Incorrect attribute name");
|
||||
assertEquals(attribute.sourceFile().stringValue(), fileName,
|
||||
"Incorrect source file name");
|
||||
assertEquals(attribute.attribute_length, 2, "Incorrect attribute length");
|
||||
assertEquals(((BoundAttribute<?>)attribute).payloadLen(), 2, "Incorrect attribute length");
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @compile -source 10 -target 10 SyntheticClassTest.java
|
||||
* @run main SyntheticClassTest true
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase
|
||||
* @run main TopLevelClassesOneFileTest
|
||||
*/
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Synthetic anonymous class used as access constructor tag conflicting with a top level class.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult
|
||||
* @build AccessToPrivateInnerClassConstructorsTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* generated to access to private methods and fields.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult
|
||||
* @build AccessToPrivateInnerClassMembersTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* generated to access to private methods and fields.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build AccessToPrivateSiblingsTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for assert statement.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build AssertFieldTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for bridge method generated for generic method.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build BridgeMethodForGenericMethodTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -29,7 +29,12 @@
|
||||
* compiling with --release 14.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* generated for lambda expressions and method references.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for enum members.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build EnumTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for package-info.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
@ -31,8 +32,10 @@ import java.util.function.Supplier;
|
||||
import java.util.regex.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.lang.reflect.AccessFlag;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.SyntheticAttribute;
|
||||
|
||||
/**
|
||||
* The tests work as follows. Firstly, it looks through the test cases
|
||||
@ -48,15 +51,12 @@ import com.sun.tools.classfile.*;
|
||||
* See the appropriate class for more information about a test case.
|
||||
*/
|
||||
public class SyntheticTestDriver extends TestResult {
|
||||
|
||||
private static final String ACC_SYNTHETIC = "ACC_SYNTHETIC";
|
||||
|
||||
private final String testCaseName;
|
||||
private final Map<String, ClassFile> classes;
|
||||
private final Map<String, ClassModel> classes;
|
||||
private final Map<String, ExpectedClass> expectedClasses;
|
||||
|
||||
public static void main(String[] args)
|
||||
throws TestFailedException, ConstantPoolException, IOException, ClassNotFoundException {
|
||||
throws TestFailedException, IOException, ClassNotFoundException {
|
||||
if (args.length != 1 && args.length != 2) {
|
||||
throw new IllegalArgumentException("Usage: SyntheticTestDriver <class-name> [<number-of-synthetic-classes>]");
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class SyntheticTestDriver extends TestResult {
|
||||
new SyntheticTestDriver(args[0]).test(numberOfSyntheticClasses);
|
||||
}
|
||||
|
||||
public SyntheticTestDriver(String testCaseName) throws IOException, ConstantPoolException, ClassNotFoundException {
|
||||
public SyntheticTestDriver(String testCaseName) throws IOException, ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName(testCaseName);
|
||||
this.testCaseName = testCaseName;
|
||||
this.expectedClasses = Stream.of(clazz.getAnnotationsByType(ExpectedClass.class))
|
||||
@ -75,7 +75,7 @@ public class SyntheticTestDriver extends TestResult {
|
||||
List<Path> paths = Files.walk(classDir)
|
||||
.map(p -> classDir.relativize(p.toAbsolutePath()))
|
||||
.filter(p -> filePattern.matcher(p.toString()).matches())
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
for (Path path : paths) {
|
||||
String className = path.toString().replace(".class", "").replace(File.separatorChar, '.');
|
||||
classes.put(className, readClassFile(classDir.resolve(path).toFile()));
|
||||
@ -91,11 +91,19 @@ public class SyntheticTestDriver extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private String getMethodName(ClassFile classFile, Method method)
|
||||
throws ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
String methodName = method.getName(classFile.constant_pool);
|
||||
String parameters = method.descriptor.getParameterTypes(classFile.constant_pool);
|
||||
return methodName + parameters;
|
||||
private String getMethodName(MethodModel method) {
|
||||
StringBuilder methodName = new StringBuilder(method.methodName().stringValue() + "(");
|
||||
List<ClassDesc> paras = method.methodTypeSymbol().parameterList();
|
||||
for (int i = 0; i < method.methodTypeSymbol().parameterCount(); ++i) {
|
||||
if (i != 0) {
|
||||
methodName.append(", ");
|
||||
}
|
||||
ClassDesc para = paras.get(i);
|
||||
String prefix = para.componentType() == null? para.packageName(): para.componentType().packageName();
|
||||
methodName.append(prefix).append(Objects.equals(prefix, "") ? "":".").append(para.displayName());
|
||||
}
|
||||
methodName.append(")");
|
||||
return methodName.toString();
|
||||
}
|
||||
|
||||
public void test(int expectedNumberOfSyntheticClasses) throws TestFailedException {
|
||||
@ -104,14 +112,14 @@ public class SyntheticTestDriver extends TestResult {
|
||||
Set<String> foundClasses = new HashSet<>();
|
||||
|
||||
int numberOfSyntheticClasses = 0;
|
||||
for (Map.Entry<String, ClassFile> entry : classes.entrySet()) {
|
||||
for (Map.Entry<String, ClassModel> entry : classes.entrySet()) {
|
||||
String className = entry.getKey();
|
||||
ClassFile classFile = entry.getValue();
|
||||
ClassModel classFile = entry.getValue();
|
||||
foundClasses.add(className);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) classFile.getAttribute(Attribute.Synthetic),
|
||||
classFile.access_flags::getClassFlags,
|
||||
() -> classFile.findAttribute(Attributes.SYNTHETIC).orElse(null),
|
||||
classFile.flags()::flags,
|
||||
expectedClasses.keySet(),
|
||||
className,
|
||||
"Testing class " + className)) {
|
||||
@ -123,13 +131,13 @@ public class SyntheticTestDriver extends TestResult {
|
||||
: new HashSet<>();
|
||||
int numberOfSyntheticMethods = 0;
|
||||
Set<String> foundMethods = new HashSet<>();
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = getMethodName(classFile, method);
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
String methodName = getMethodName(method);
|
||||
foundMethods.add(methodName);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) method.attributes.get(Attribute.Synthetic),
|
||||
method.access_flags::getMethodFlags,
|
||||
() -> method.findAttribute(Attributes.SYNTHETIC).orElse(null),
|
||||
method.flags()::flags,
|
||||
expectedMethods,
|
||||
methodName,
|
||||
"Testing method " + methodName + " in class "
|
||||
@ -149,13 +157,13 @@ public class SyntheticTestDriver extends TestResult {
|
||||
: new HashSet<>();
|
||||
int numberOfSyntheticFields = 0;
|
||||
Set<String> foundFields = new HashSet<>();
|
||||
for (Field field : classFile.fields) {
|
||||
String fieldName = field.getName(classFile.constant_pool);
|
||||
for (FieldModel field : classFile.fields()) {
|
||||
String fieldName = field.fieldName().stringValue();
|
||||
foundFields.add(fieldName);
|
||||
if (testAttribute(
|
||||
classFile,
|
||||
() -> (Synthetic_attribute) field.attributes.get(Attribute.Synthetic),
|
||||
field.access_flags::getFieldFlags,
|
||||
() -> field.findAttribute(Attributes.SYNTHETIC).orElse(null),
|
||||
field.flags()::flags,
|
||||
expectedFields,
|
||||
fieldName,
|
||||
"Testing field " + fieldName + " in class "
|
||||
@ -181,25 +189,25 @@ public class SyntheticTestDriver extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean testAttribute(ClassFile classFile,
|
||||
Supplier<Synthetic_attribute> getSyntheticAttribute,
|
||||
Supplier<Set<String>> getAccessFlags,
|
||||
private boolean testAttribute(ClassModel classFile,
|
||||
Supplier<SyntheticAttribute> getSyntheticAttribute,
|
||||
Supplier<Set<AccessFlag>> getAccessFlags,
|
||||
Set<String> expectedMembers, String memberName,
|
||||
String info) throws ConstantPoolException {
|
||||
String info) {
|
||||
echo(info);
|
||||
String className = classFile.getName();
|
||||
Synthetic_attribute attr = getSyntheticAttribute.get();
|
||||
Set<String> flags = getAccessFlags.get();
|
||||
String className = classFile.thisClass().name().stringValue();
|
||||
SyntheticAttribute attr = getSyntheticAttribute.get();
|
||||
Set<AccessFlag> flags = getAccessFlags.get();
|
||||
if (expectedMembers.contains(memberName)) {
|
||||
checkNull(attr, "Member must not have synthetic attribute : "
|
||||
+ memberName);
|
||||
checkFalse(flags.contains(ACC_SYNTHETIC),
|
||||
checkFalse(flags.contains(AccessFlag.SYNTHETIC),
|
||||
"Member must not have synthetic flag : " + memberName
|
||||
+ " in class : " + className);
|
||||
return false;
|
||||
} else {
|
||||
return checkNull(attr, "Synthetic attribute should not be generated")
|
||||
&& checkTrue(flags.contains(ACC_SYNTHETIC), "Member must have synthetic flag : "
|
||||
&& checkTrue(flags.contains(AccessFlag.SYNTHETIC), "Member must have synthetic flag : "
|
||||
+ memberName + " in class : " + className);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,12 @@
|
||||
* @summary Checking ACC_SYNTHETIC flag is generated for "this$0" field.
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build ThisFieldTest SyntheticTestDriver ExpectedClass ExpectedClasses
|
||||
|
||||
@ -21,9 +21,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import jdk.internal.classfile.Attribute;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
@ -105,7 +103,7 @@ public abstract class AnnotationsTestBase extends TestResult {
|
||||
public abstract List<TestCase> generateTestCases();
|
||||
|
||||
public abstract void test(TestCase testCase, Map<String, ? extends JavaFileObject> classes)
|
||||
throws IOException, ConstantPoolException, Descriptor.InvalidDescriptor;
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The method is used to create a repeatable annotation.
|
||||
@ -176,7 +174,7 @@ public abstract class AnnotationsTestBase extends TestResult {
|
||||
combinations.addAll(list.stream()
|
||||
.map(Collections::singletonList)
|
||||
.map(TestAnnotationInfos::new)
|
||||
.collect(Collectors.toList()));
|
||||
.toList());
|
||||
|
||||
// add cases with a repeatable annotation
|
||||
for (Annotations annotationName2 : Annotations.values()) {
|
||||
@ -203,9 +201,9 @@ public abstract class AnnotationsTestBase extends TestResult {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
|
||||
protected long countNumberOfAttributes(Attribute[] attrs,
|
||||
Class<? extends Attribute> clazz) {
|
||||
return Stream.of(attrs)
|
||||
protected long countNumberOfAttributes(List<Attribute<?>> attrs,
|
||||
Class<? extends Attribute<?>> clazz) {
|
||||
return attrs.stream()
|
||||
.filter(clazz::isInstance)
|
||||
.count();
|
||||
}
|
||||
|
||||
@ -26,7 +26,12 @@
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute.
|
||||
* Checks that the attribute is generated for bridge method.
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
@ -70,10 +75,10 @@ public class RuntimeAnnotationsForGenericMethodTest extends RuntimeAnnotationsTe
|
||||
TestAnnotationInfos annotations = groupedAnnotations.get(i);
|
||||
// generate: public class Test extends java.util.ArrayList<Integer>
|
||||
TestCase.TestClassInfo clazz = testCase.addClassInfo("java.util.ArrayList<Integer>", ClassType.CLASS, "Test" + i);
|
||||
TestCase.TestMethodInfo method = clazz.addMethodInfo("add(java.lang.Integer)", "public");
|
||||
TestCase.TestMethodInfo method = clazz.addMethodInfo("add(Integer)", "public");
|
||||
method.addParameter("Integer", "i");
|
||||
annotations.annotate(method);
|
||||
TestCase.TestMethodInfo synMethod = clazz.addMethodInfo("add(java.lang.Object)", true, "public");
|
||||
TestCase.TestMethodInfo synMethod = clazz.addMethodInfo("add(Object)", true, "public");
|
||||
annotations.annotate(synMethod);
|
||||
}
|
||||
testCases.add(testCase);
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -34,14 +35,14 @@ public abstract class RuntimeAnnotationsTestBase extends AnnotationsTestBase {
|
||||
|
||||
@Override
|
||||
public void test(TestCase testCase, Map<String, ? extends JavaFileObject> classes)
|
||||
throws IOException, ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
throws IOException {
|
||||
for (Map.Entry<String, ? extends JavaFileObject> entry : classes.entrySet()) {
|
||||
String className = entry.getKey();
|
||||
TestCase.TestClassInfo clazz = testCase.getTestClassInfo(className);
|
||||
echo("Testing class : " + className);
|
||||
ClassFile classFile = readClassFile(entry.getValue());
|
||||
ClassModel classFile = readClassFile(entry.getValue());
|
||||
|
||||
testAttributes(clazz, classFile, () -> classFile.attributes);
|
||||
testAttributes(clazz, classFile, classFile);
|
||||
|
||||
testMethods(clazz, classFile);
|
||||
|
||||
@ -49,13 +50,13 @@ public abstract class RuntimeAnnotationsTestBase extends AnnotationsTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private void testMethods(TestCase.TestClassInfo clazz, ClassFile classFile)
|
||||
throws ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
private void testMethods(TestCase.TestClassInfo clazz, ClassModel classFile) {
|
||||
String className = clazz.getName();
|
||||
Set<String> foundMethods = new HashSet<>();
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = method.getName(classFile.constant_pool) +
|
||||
method.descriptor.getParameterTypes(classFile.constant_pool);
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
String methodName = method.methodName().stringValue() +
|
||||
method.methodTypeSymbol().displayDescriptor();
|
||||
methodName = methodName.substring(0, methodName.indexOf(")") + 1);
|
||||
if (methodName.startsWith("<init>")) {
|
||||
String constructorName = className.replaceAll(".*\\$", "");
|
||||
methodName = methodName.replace("<init>", constructorName);
|
||||
@ -67,16 +68,15 @@ public abstract class RuntimeAnnotationsTestBase extends AnnotationsTestBase {
|
||||
if (testMethod == null) {
|
||||
continue;
|
||||
}
|
||||
testAttributes(testMethod, classFile, () -> method.attributes);
|
||||
testAttributes(testMethod, classFile, method);
|
||||
}
|
||||
checkContains(foundMethods, clazz.methods.keySet(), "Methods in class : " + className);
|
||||
}
|
||||
|
||||
private void testFields(TestCase.TestClassInfo clazz, ClassFile classFile)
|
||||
throws ConstantPoolException {
|
||||
private void testFields(TestCase.TestClassInfo clazz, ClassModel classFile) {
|
||||
Set<String> foundFields = new HashSet<>();
|
||||
for (Field field : classFile.fields) {
|
||||
String fieldName = field.getName(classFile.constant_pool);
|
||||
for (FieldModel field : classFile.fields()) {
|
||||
String fieldName = field.fieldName().stringValue();
|
||||
echo("Testing field : " + fieldName);
|
||||
|
||||
TestCase.TestFieldInfo testField = clazz.getTestFieldInfo(fieldName);
|
||||
@ -84,26 +84,23 @@ public abstract class RuntimeAnnotationsTestBase extends AnnotationsTestBase {
|
||||
if (testField == null) {
|
||||
continue;
|
||||
}
|
||||
testAttributes(testField, classFile, () -> field.attributes);
|
||||
testAttributes(testField, classFile, field);
|
||||
}
|
||||
checkContains(foundFields, clazz.fields.keySet(), "Fields in class : " + clazz.getName());
|
||||
}
|
||||
|
||||
private void testAttributes(
|
||||
TestCase.TestMemberInfo member,
|
||||
ClassFile classFile,
|
||||
Supplier<Attributes> attributes)
|
||||
throws ConstantPoolException {
|
||||
ClassModel classFile,
|
||||
AttributedElement attributedElement) {
|
||||
Map<String, Annotation> actualInvisible = collectAnnotations(
|
||||
classFile,
|
||||
member,
|
||||
attributes.get(),
|
||||
Attribute.RuntimeInvisibleAnnotations);
|
||||
attributedElement,
|
||||
Attributes.RUNTIME_INVISIBLE_ANNOTATIONS);
|
||||
Map<String, Annotation> actualVisible = collectAnnotations(
|
||||
classFile,
|
||||
member,
|
||||
attributes.get(),
|
||||
Attribute.RuntimeVisibleAnnotations);
|
||||
attributedElement,
|
||||
Attributes.RUNTIME_VISIBLE_ANNOTATIONS);
|
||||
|
||||
checkEquals(actualInvisible.keySet(),
|
||||
member.getRuntimeInvisibleAnnotations(), "RuntimeInvisibleAnnotations");
|
||||
@ -126,32 +123,41 @@ public abstract class RuntimeAnnotationsTestBase extends AnnotationsTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Annotation> collectAnnotations(
|
||||
ClassFile classFile,
|
||||
private <T extends Attribute<T>> Map<String, Annotation> collectAnnotations(
|
||||
TestCase.TestMemberInfo member,
|
||||
Attributes attributes,
|
||||
String attribute) throws ConstantPoolException {
|
||||
AttributedElement attributedElement,
|
||||
AttributeMapper<T> attribute) {
|
||||
|
||||
RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute) attributes.get(attribute);
|
||||
Object attr = attributedElement.findAttribute(attribute).orElse(null);
|
||||
Map<String, Annotation> actualAnnotations = new HashMap<>();
|
||||
RetentionPolicy policy = getRetentionPolicy(attribute);
|
||||
RetentionPolicy policy = getRetentionPolicy(attribute.name());
|
||||
if (member.isAnnotated(policy)) {
|
||||
if (!checkNotNull(attr, String.format("%s should be not null value", attribute))) {
|
||||
if (!checkNotNull(attr, String.format("%s should be not null value", attribute.name()))) {
|
||||
// test case failed, stop checking
|
||||
return actualAnnotations;
|
||||
}
|
||||
for (Annotation ann : attr.annotations) {
|
||||
String name = classFile.constant_pool.getUTF8Value(ann.type_index);
|
||||
actualAnnotations.put(name.substring(1, name.length() - 1), ann);
|
||||
List<Annotation> annotationList;
|
||||
switch (attr) {
|
||||
case RuntimeVisibleAnnotationsAttribute annots -> {
|
||||
annotationList = annots.annotations();
|
||||
}
|
||||
case RuntimeInvisibleAnnotationsAttribute annots -> {
|
||||
annotationList = annots.annotations();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
checkEquals(countNumberOfAttributes(attributes.attrs,
|
||||
getRetentionPolicy(attribute) == RetentionPolicy.RUNTIME
|
||||
? RuntimeVisibleAnnotations_attribute.class
|
||||
: RuntimeInvisibleAnnotations_attribute.class),
|
||||
1l,
|
||||
String.format("Number of %s", attribute));
|
||||
for (Annotation ann : annotationList) {
|
||||
String name = ann.classSymbol().displayName();
|
||||
actualAnnotations.put(name, ann);
|
||||
}
|
||||
checkEquals(countNumberOfAttributes(attributedElement.attributes(),
|
||||
getRetentionPolicy(attribute.name()) == RetentionPolicy.RUNTIME
|
||||
? RuntimeVisibleAnnotationsAttribute.class
|
||||
: RuntimeInvisibleAnnotationsAttribute.class),
|
||||
1L,
|
||||
String.format("Number of %s", attribute.name()));
|
||||
} else {
|
||||
checkNull(attr, String.format("%s should be null", attribute));
|
||||
checkNull(attr, String.format("%s should be null", attribute.name()));
|
||||
}
|
||||
return actualAnnotations;
|
||||
}
|
||||
|
||||
@ -26,7 +26,12 @@
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations attribute.
|
||||
* Checks that the attribute is generated for bridge method.
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
@ -68,9 +73,9 @@ public class RuntimeParameterAnnotationsForGenericMethodTest extends RuntimePara
|
||||
// generate: public class Test extends java.util.ArrayList<Integer>
|
||||
TestCase testCase = new TestCase();
|
||||
TestCase.TestClassInfo clazz = testCase.addClassInfo("java.util.ArrayList<Integer>", ClassType.CLASS, "Test");
|
||||
TestCase.TestParameterInfo parameter = clazz.addMethodInfo("add(java.lang.Integer)", "public").addParameter("Integer", "i");
|
||||
TestCase.TestParameterInfo parameter = clazz.addMethodInfo("add(Integer)", "public").addParameter("Integer", "i");
|
||||
annotations.annotate(parameter);
|
||||
TestCase.TestParameterInfo synParameter = clazz.addMethodInfo("add(java.lang.Object)", true, "public").addParameter("Object", "i");
|
||||
TestCase.TestParameterInfo synParameter = clazz.addMethodInfo("add(Object)", true, "public").addParameter("Object", "i");
|
||||
annotations.annotate(synParameter);
|
||||
testCases.add(testCase);
|
||||
}
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411 8079060 8138612
|
||||
* @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
@ -35,10 +40,15 @@
|
||||
* @run main RuntimeParameterAnnotationsForLambdaTest
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.Attributes;
|
||||
import jdk.internal.classfile.ClassModel;
|
||||
import jdk.internal.classfile.MethodModel;
|
||||
import jdk.internal.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute;
|
||||
import jdk.internal.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/**
|
||||
* RuntimeParameterAnnotationsForLambdaTest is a test which checks that RuntimeVisibleParameterAnnotationsAttribute
|
||||
@ -55,9 +65,9 @@ public class RuntimeParameterAnnotationsForLambdaTest extends RuntimeParameterAn
|
||||
private static final String CLASS_NAME = "Test";
|
||||
private static final String SOURCE_TEMPLATE =
|
||||
"public class " + CLASS_NAME + " {\n" +
|
||||
" interface I { void method(int a, double b, String c); }\n" +
|
||||
" %SOURCE%\n" +
|
||||
"}";
|
||||
" interface I { void method(int a, double b, String c); }\n" +
|
||||
" %SOURCE%\n" +
|
||||
"}";
|
||||
|
||||
public static void main(String[] args) throws TestFailedException {
|
||||
new RuntimeParameterAnnotationsForLambdaTest().test();
|
||||
@ -77,12 +87,12 @@ public class RuntimeParameterAnnotationsForLambdaTest extends RuntimeParameterAn
|
||||
String source = SOURCE_TEMPLATE.replace("%SOURCE%", generateLambdaSource(testMethodInfo));
|
||||
addTestCase(source);
|
||||
echo("Testing:\n" + source);
|
||||
ClassFile classFile = readClassFile(compile(source).getClasses().get(CLASS_NAME));
|
||||
ClassModel classFile = readClassFile(compile(source).getClasses().get(CLASS_NAME));
|
||||
boolean isFoundLambda = false;
|
||||
for (Method method : classFile.methods) {
|
||||
if (method.getName(classFile.constant_pool).startsWith("lambda$")) {
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
if (method.methodName().stringValue().startsWith("lambda$")) {
|
||||
isFoundLambda = true;
|
||||
testAttributes(testMethodInfo, classFile, method);
|
||||
testAttributes(testMethodInfo, method);
|
||||
}
|
||||
}
|
||||
checkTrue(isFoundLambda, "The tested lambda method was not found.");
|
||||
@ -97,13 +107,11 @@ public class RuntimeParameterAnnotationsForLambdaTest extends RuntimeParameterAn
|
||||
|
||||
protected void testAttributes(
|
||||
TestCase.TestMethodInfo testMethod,
|
||||
ClassFile classFile,
|
||||
Method method) throws ConstantPoolException {
|
||||
Attributes attributes = method.attributes;
|
||||
RuntimeParameterAnnotations_attribute attr = (RuntimeParameterAnnotations_attribute) attributes.get(Attribute.RuntimeInvisibleParameterAnnotations);
|
||||
checkNull(attr, String.format("%s should be null", Attribute.RuntimeInvisibleParameterAnnotations));
|
||||
attr = (RuntimeParameterAnnotations_attribute) attributes.get(Attribute.RuntimeVisibleParameterAnnotations);
|
||||
checkNull(attr, String.format("%s should be null", Attribute.RuntimeVisibleParameterAnnotations));
|
||||
MethodModel method) {
|
||||
RuntimeInvisibleParameterAnnotationsAttribute invAttr = method.findAttribute(Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS).orElse(null);
|
||||
checkNull(invAttr, String.format("%s should be null", Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS));
|
||||
RuntimeVisibleParameterAnnotationsAttribute vAttr = method.findAttribute(Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS).orElse(null);
|
||||
checkNull(vAttr, String.format("%s should be null", Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS));
|
||||
}
|
||||
|
||||
public String generateLambdaSource(TestCase.TestMethodInfo method) {
|
||||
|
||||
@ -25,7 +25,12 @@
|
||||
* @test
|
||||
* @bug 8044411
|
||||
* @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations 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
|
||||
* java.base/jdk.internal.classfile.impl
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
@ -85,7 +90,7 @@ public class RuntimeParameterAnnotationsTest extends RuntimeParameterAnnotations
|
||||
* @param mods an array of modifiers
|
||||
*/
|
||||
private void initMethod(TestAnnotationInfos annotations, TestCase.TestClassInfo clazz, String methodName, String...mods) {
|
||||
String methodDescriptor = methodName + "(int, double, java.lang.String)";
|
||||
String methodDescriptor = methodName + "(int,double,String)";
|
||||
TestCase.TestMethodInfo method = clazz.addMethodInfo(methodDescriptor, mods);
|
||||
TestCase.TestParameterInfo p1 = method.addParameter("int", "a");
|
||||
annotations.annotate(p1);
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
@ -32,15 +33,16 @@ public abstract class RuntimeParameterAnnotationsTestBase extends AnnotationsTes
|
||||
|
||||
@Override
|
||||
public void test(TestCase testCase, Map<String, ? extends JavaFileObject> classes)
|
||||
throws IOException, ConstantPoolException, Descriptor.InvalidDescriptor {
|
||||
throws IOException {
|
||||
for (Map.Entry<String, ? extends JavaFileObject> entry : classes.entrySet()) {
|
||||
ClassFile classFile = readClassFile(classes.get(entry.getKey()));
|
||||
ClassModel classFile = readClassFile(classes.get(entry.getKey()));
|
||||
Set<String> foundMethods = new HashSet<>();
|
||||
String className = classFile.getName();
|
||||
String className = classFile.thisClass().name().stringValue();
|
||||
TestCase.TestClassInfo testClassInfo = testCase.classes.get(className);
|
||||
for (Method method : classFile.methods) {
|
||||
String methodName = method.getName(classFile.constant_pool) +
|
||||
method.descriptor.getParameterTypes(classFile.constant_pool);
|
||||
for (MethodModel method : classFile.methods()) {
|
||||
String methodName = method.methodName().stringValue() +
|
||||
method.methodTypeSymbol().displayDescriptor();
|
||||
methodName = methodName.substring(0, methodName.indexOf(")") + 1);
|
||||
if (methodName.startsWith("<init>")) {
|
||||
methodName = methodName.replace("<init>", className);
|
||||
}
|
||||
@ -59,18 +61,18 @@ public abstract class RuntimeParameterAnnotationsTestBase extends AnnotationsTes
|
||||
|
||||
protected void testAttributes(
|
||||
TestCase.TestMethodInfo testMethod,
|
||||
ClassFile classFile,
|
||||
Method method) throws ConstantPoolException {
|
||||
ClassModel classFile,
|
||||
MethodModel method) {
|
||||
List<Map<String, Annotation>> actualInvisible = collectAnnotations(
|
||||
classFile,
|
||||
testMethod,
|
||||
method,
|
||||
Attribute.RuntimeInvisibleParameterAnnotations);
|
||||
Attributes.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
|
||||
List<Map<String, Annotation>> actualVisible = collectAnnotations(
|
||||
classFile,
|
||||
testMethod,
|
||||
method,
|
||||
Attribute.RuntimeVisibleParameterAnnotations);
|
||||
Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
|
||||
|
||||
List<TestCase.TestParameterInfo> parameters = testMethod.parameters;
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
@ -103,38 +105,46 @@ public abstract class RuntimeParameterAnnotationsTestBase extends AnnotationsTes
|
||||
}
|
||||
}
|
||||
|
||||
private List<Map<String, Annotation>> collectAnnotations(
|
||||
ClassFile classFile,
|
||||
private <T extends Attribute<T>> List<Map<String, Annotation>> collectAnnotations(
|
||||
ClassModel classFile,
|
||||
TestCase.TestMethodInfo testMethod,
|
||||
Method method,
|
||||
String attribute) throws ConstantPoolException {
|
||||
|
||||
Attributes attributes = method.attributes;
|
||||
RuntimeParameterAnnotations_attribute attr = (RuntimeParameterAnnotations_attribute) attributes.get(attribute);
|
||||
MethodModel method,
|
||||
AttributeMapper<T> attribute) {
|
||||
|
||||
Object attr = method.findAttribute(attribute).orElse(null);
|
||||
List<Map<String, Annotation>> actualAnnotations = new ArrayList<>();
|
||||
RetentionPolicy policy = getRetentionPolicy(attribute);
|
||||
RetentionPolicy policy = getRetentionPolicy(attribute.name());
|
||||
if (testMethod.isParameterAnnotated(policy)) {
|
||||
if (!checkNotNull(attr, "Attribute " + attribute + " must not be null")) {
|
||||
if (!checkNotNull(attr, "Attribute " + attribute.name() + " must not be null")) {
|
||||
testMethod.parameters.forEach($ -> actualAnnotations.add(new HashMap<>()));
|
||||
return actualAnnotations;
|
||||
}
|
||||
for (Annotation[] anns : attr.parameter_annotations) {
|
||||
List<List<Annotation>> annotationList;
|
||||
switch (attr) {
|
||||
case RuntimeVisibleParameterAnnotationsAttribute pAnnots -> {
|
||||
annotationList = pAnnots.parameterAnnotations();
|
||||
}
|
||||
case RuntimeInvisibleParameterAnnotationsAttribute pAnnots -> {
|
||||
annotationList = pAnnots.parameterAnnotations();
|
||||
}
|
||||
default -> throw new AssertionError();
|
||||
}
|
||||
for (List<Annotation> anns: annotationList) {
|
||||
Map<String, Annotation> annotations = new HashMap<>();
|
||||
for (Annotation ann : anns) {
|
||||
String name = classFile.constant_pool.getUTF8Value(ann.type_index);
|
||||
annotations.put(name.substring(1, name.length() - 1), ann);
|
||||
for (Annotation ann: anns) {
|
||||
String name = ann.classSymbol().displayName();
|
||||
annotations.put(name, ann);
|
||||
}
|
||||
actualAnnotations.add(annotations);
|
||||
}
|
||||
checkEquals(countNumberOfAttributes(attributes.attrs,
|
||||
getRetentionPolicy(attribute) == RetentionPolicy.RUNTIME
|
||||
? RuntimeVisibleParameterAnnotations_attribute.class
|
||||
: RuntimeInvisibleParameterAnnotations_attribute.class),
|
||||
1l,
|
||||
String.format("Number of %s", attribute));
|
||||
checkEquals(countNumberOfAttributes(method.attributes(),
|
||||
getRetentionPolicy(attribute.name()) == RetentionPolicy.RUNTIME
|
||||
? RuntimeVisibleParameterAnnotationsAttribute.class
|
||||
: RuntimeInvisibleParameterAnnotationsAttribute.class),
|
||||
1L,
|
||||
String.format("Number of %s", attribute.name()));
|
||||
} else {
|
||||
checkNull(attr, String.format("%s should be null", attribute));
|
||||
checkNull(attr, String.format("%s should be null", attribute.name()));
|
||||
testMethod.parameters.forEach($ -> actualAnnotations.add(new HashMap<>()));
|
||||
}
|
||||
return actualAnnotations;
|
||||
|
||||
@ -21,10 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.AnnotationValue;
|
||||
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.*;
|
||||
@ -47,21 +45,20 @@ public class TestAnnotationInfo {
|
||||
elementValues = Arrays.asList(values);
|
||||
}
|
||||
|
||||
public void testAnnotation(TestResult testResult, ClassFile classFile, Annotation annotation)
|
||||
throws ConstantPoolException {
|
||||
testResult.checkEquals(classFile.constant_pool.getUTF8Value(annotation.type_index),
|
||||
public void testAnnotation(TestResult testResult, ClassModel classFile, Annotation annotation) {
|
||||
testResult.checkEquals(annotation.classSymbol().descriptorString(),
|
||||
String.format("L%s;", annotationName), "Testing annotation name : " + annotationName);
|
||||
testResult.checkEquals(annotation.num_element_value_pairs,
|
||||
testResult.checkEquals(annotation.elements().size(),
|
||||
elementValues.size(), "Number of element values");
|
||||
if (!testResult.checkEquals(annotation.num_element_value_pairs, elementValues.size(),
|
||||
if (!testResult.checkEquals(annotation.elements().size(), elementValues.size(),
|
||||
"Number of element value pairs")) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < annotation.num_element_value_pairs; ++i) {
|
||||
Annotation.element_value_pair pair = annotation.element_value_pairs[i];
|
||||
testResult.checkEquals(classFile.constant_pool.getUTF8Value(pair.element_name_index),
|
||||
for (int i = 0; i < annotation.elements().size(); ++i) {
|
||||
AnnotationElement pair = annotation.elements().get(i);
|
||||
testResult.checkEquals(pair.name().stringValue(),
|
||||
elementValues.get(i).elementName, "element_name_index : " + elementValues.get(i).elementName);
|
||||
elementValues.get(i).elementValue.testElementValue(testResult, classFile, pair.value);
|
||||
elementValues.get(i).elementValue.testElementValue(testResult, classFile, pair.value());
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,9 +98,8 @@ public class TestAnnotationInfo {
|
||||
}
|
||||
|
||||
public abstract void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value);
|
||||
}
|
||||
|
||||
public static class TestIntegerElementValue extends TestElementValue {
|
||||
@ -116,15 +112,19 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Integer_info info =
|
||||
(ConstantPool.CONSTANT_Integer_info) classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value, "const_value_index : " + value);
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
switch (element_value.tag()) {
|
||||
case 'B':
|
||||
testResult.checkEquals((int)((AnnotationValue.OfByte) element_value).byteValue(), value, "const_value_index : " + value);
|
||||
break;
|
||||
case 'S':
|
||||
testResult.checkEquals((int)((AnnotationValue.OfShort) element_value).shortValue(), value, "const_value_index : " + value);
|
||||
break;
|
||||
default:
|
||||
testResult.checkEquals(((AnnotationValue.OfInteger) element_value).intValue(), value, "const_value_index : " + value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,15 +143,11 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Integer_info info =
|
||||
(ConstantPool.CONSTANT_Integer_info) classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value ? 1 : 0, "const_value_index : " + value);
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfBoolean ev = (AnnotationValue.OfBoolean) element_value;
|
||||
testResult.checkEquals(ev.booleanValue(), value, "const_value_index : " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,16 +166,12 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Integer_info info =
|
||||
(ConstantPool.CONSTANT_Integer_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, (int) value, "const_value_index : " + value);
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfCharacter ev =
|
||||
(AnnotationValue.OfCharacter) element_value;
|
||||
testResult.checkEquals(ev.charValue(), value, "const_value_index : " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -198,15 +190,12 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPool.InvalidIndex {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Long_info info =
|
||||
(ConstantPool.CONSTANT_Long_info) classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value, "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfLong ev =
|
||||
(AnnotationValue.OfLong) element_value;
|
||||
testResult.checkEquals(ev.longValue(), value, "const_value_index");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,15 +214,12 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPool.InvalidIndex {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Float_info info =
|
||||
(ConstantPool.CONSTANT_Float_info) classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value, "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfFloat ev =
|
||||
(AnnotationValue.OfFloat) element_value;
|
||||
testResult.checkEquals(ev.floatValue(), value, "const_value_index");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -252,15 +238,12 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Double_info info = (ConstantPool.CONSTANT_Double_info)
|
||||
classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value, "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfDouble ev =
|
||||
(AnnotationValue.OfDouble) element_value;
|
||||
testResult.checkEquals(ev.doubleValue(), value, "const_value_index");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -279,15 +262,12 @@ public class TestAnnotationInfo {
|
||||
|
||||
@Override
|
||||
public void testElementValue(TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Primitive_element_value ev =
|
||||
(Annotation.Primitive_element_value) element_value;
|
||||
ConstantPool.CONSTANT_Utf8_info info =
|
||||
(ConstantPool.CONSTANT_Utf8_info) classFile.constant_pool.get(ev.const_value_index);
|
||||
testResult.checkEquals(info.value, value, "const_value_index");
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfString ev =
|
||||
(AnnotationValue.OfString) element_value;
|
||||
testResult.checkEquals(ev.stringValue(), value, "const_value_index");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -309,14 +289,13 @@ public class TestAnnotationInfo {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Enum_element_value ev = (Annotation.Enum_element_value) element_value;
|
||||
testResult.checkEquals(classFile.constant_pool.getUTF8Info(ev.type_name_index).value,
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfEnum ev = (AnnotationValue.OfEnum) element_value;
|
||||
testResult.checkEquals(ev.classSymbol().descriptorString(),
|
||||
String.format("L%s;", typeName), "type_name_index");
|
||||
testResult.checkEquals(classFile.constant_pool.getUTF8Info(ev.const_name_index).value,
|
||||
testResult.checkEquals(ev.constantName().stringValue(),
|
||||
constName, "const_name_index");
|
||||
}
|
||||
|
||||
@ -351,16 +330,14 @@ public class TestAnnotationInfo {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Class_element_value ev = (Annotation.Class_element_value) element_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfClass ev = (AnnotationValue.OfClass) element_value;
|
||||
String expectedClassName = className.replace(".class", "");
|
||||
expectedClassName = mappedClassName.getOrDefault(expectedClassName,
|
||||
String.format("Ljava/lang/%s;", expectedClassName));
|
||||
testResult.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(ev.class_info_index).value,
|
||||
testResult.checkEquals(ev.classSymbol().descriptorString(),
|
||||
expectedClassName, "class_info_index : " + expectedClassName);
|
||||
}
|
||||
|
||||
@ -381,14 +358,13 @@ public class TestAnnotationInfo {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation.Array_element_value ev = (Annotation.Array_element_value) element_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
AnnotationValue.OfArray ev = (AnnotationValue.OfArray) element_value;
|
||||
|
||||
for (int i = 0; i < values.size(); ++i) {
|
||||
values.get(i).testElementValue(testResult, classFile, ev.values[i]);
|
||||
values.get(i).testElementValue(testResult, classFile, ev.values().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,21 +389,20 @@ public class TestAnnotationInfo {
|
||||
@Override
|
||||
public void testElementValue(
|
||||
TestResult testResult,
|
||||
ClassFile classFile,
|
||||
Annotation.element_value element_value)
|
||||
throws ConstantPoolException {
|
||||
testTag(testResult, element_value.tag);
|
||||
Annotation ev = ((Annotation.Annotation_element_value) element_value).annotation_value;
|
||||
ClassModel classFile,
|
||||
AnnotationValue element_value) {
|
||||
testTag(testResult, element_value.tag());
|
||||
Annotation ev = ((AnnotationValue.OfAnnotation) element_value).annotation();
|
||||
testResult.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(ev.type_index).value,
|
||||
ev.classSymbol().descriptorString(),
|
||||
String.format("L%s;", annotationName),
|
||||
"type_index");
|
||||
for (int i = 0; i < ev.num_element_value_pairs; ++i) {
|
||||
Annotation.element_value_pair pair = ev.element_value_pairs[i];
|
||||
for (int i = 0; i < ev.elements().size(); ++i) {
|
||||
AnnotationElement pair = ev.elements().get(i);
|
||||
Pair expectedPair = annotation.elementValues.get(i);
|
||||
expectedPair.elementValue.testElementValue(testResult, classFile, pair.value);
|
||||
expectedPair.elementValue.testElementValue(testResult, classFile, pair.value());
|
||||
testResult.checkEquals(
|
||||
classFile.constant_pool.getUTF8Info(pair.element_name_index).value,
|
||||
pair.name().stringValue(),
|
||||
expectedPair.elementName,
|
||||
"element_name_index");
|
||||
}
|
||||
|
||||
@ -29,14 +29,19 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @run main DeprecatedPackageTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Deprecated_attribute;
|
||||
import jdk.internal.classfile.Attributes;
|
||||
import jdk.internal.classfile.ClassModel;
|
||||
import jdk.internal.classfile.attribute.DeprecatedAttribute;
|
||||
|
||||
public class DeprecatedPackageTest extends TestResult {
|
||||
|
||||
@ -78,12 +83,11 @@ public class DeprecatedPackageTest extends TestResult {
|
||||
addTestCase(src);
|
||||
printf("Testing test case: \n%s\n", src);
|
||||
try {
|
||||
ClassFile cf = readClassFile(compile(
|
||||
ClassModel cm = readClassFile(compile(
|
||||
new String[]{"package-info.java", package_info},
|
||||
new String[]{"notDeprecated.java", src})
|
||||
.getClasses().get(CLASS_NAME));
|
||||
Deprecated_attribute attr =
|
||||
(Deprecated_attribute) cf.getAttribute(Attribute.Deprecated);
|
||||
DeprecatedAttribute attr = cm.findAttribute(Attributes.DEPRECATED).orElse(null);
|
||||
checkNull(attr, "Class can not have deprecated attribute : " + CLASS_NAME);
|
||||
} catch (Exception e) {
|
||||
addFailure(e);
|
||||
|
||||
@ -30,19 +30,19 @@
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @run main DeprecatedTest
|
||||
*/
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Deprecated_attribute;
|
||||
import com.sun.tools.classfile.Field;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.io.IOException;
|
||||
@ -244,9 +244,8 @@ public class DeprecatedTest extends TestResult {
|
||||
? "deprecated"
|
||||
: "notDeprecated";
|
||||
echo("Testing outer class : " + outerClassName);
|
||||
ClassFile cf = readClassFile(classes.get(outerClassName));
|
||||
Deprecated_attribute attr = (Deprecated_attribute)
|
||||
cf.getAttribute(Attribute.Deprecated);
|
||||
ClassModel cf = readClassFile(classes.get(outerClassName));
|
||||
DeprecatedAttribute attr = cf.findAttribute(Attributes.DEPRECATED).orElse(null);
|
||||
testAttribute(outerClassName, attr, cf);
|
||||
testInnerClasses(cf, classes);
|
||||
testMethods(cf);
|
||||
@ -256,18 +255,17 @@ public class DeprecatedTest extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private void testInnerClasses(ClassFile cf, Map<String, ? extends JavaFileObject> classes)
|
||||
throws ConstantPoolException, IOException {
|
||||
InnerClasses_attribute innerAttr = (InnerClasses_attribute)
|
||||
cf.getAttribute(Attribute.InnerClasses);
|
||||
for (Info innerClass : innerAttr.classes) {
|
||||
String innerClassName = cf.constant_pool.
|
||||
getClassInfo(innerClass.inner_class_info_index).getName();
|
||||
private void testInnerClasses(ClassModel cf, Map<String, ? extends JavaFileObject> classes)
|
||||
throws IOException {
|
||||
InnerClassesAttribute innerAttr = cf.findAttribute(Attributes.INNER_CLASSES).orElse(null);
|
||||
assert innerAttr != null;
|
||||
for (InnerClassInfo innerClass : innerAttr.classes()) {
|
||||
String innerClassName = innerClass.innerClass().name().stringValue();
|
||||
echo("Testing inner class : " + innerClassName);
|
||||
ClassFile innerCf = readClassFile(classes.get(innerClassName));
|
||||
Deprecated_attribute attr = (Deprecated_attribute)
|
||||
innerCf.getAttribute(Attribute.Deprecated);
|
||||
String innerClassSimpleName = innerClass.getInnerName(cf.constant_pool);
|
||||
ClassModel innerCf = readClassFile(classes.get(innerClassName));
|
||||
DeprecatedAttribute attr = innerCf.findAttribute(Attributes.DEPRECATED).orElse(null);
|
||||
assert innerClass.innerName().isPresent();
|
||||
String innerClassSimpleName = innerClass.innerName().get().stringValue();
|
||||
testAttribute(innerClassSimpleName, attr, innerCf);
|
||||
if (innerClassName.contains("Local")) {
|
||||
testMethods(innerCf);
|
||||
@ -276,29 +274,25 @@ public class DeprecatedTest extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private void testMethods(ClassFile cf)
|
||||
throws ConstantPoolException {
|
||||
for (Method m : cf.methods) {
|
||||
String methodName = cf.constant_pool.getUTF8Value(m.name_index);
|
||||
private void testMethods(ClassModel cf) {
|
||||
for (MethodModel m : cf.methods()) {
|
||||
String methodName = m.methodName().stringValue();
|
||||
echo("Testing method : " + methodName);
|
||||
Deprecated_attribute attr = (Deprecated_attribute)
|
||||
m.attributes.get(Attribute.Deprecated);
|
||||
DeprecatedAttribute attr = m.findAttribute(Attributes.DEPRECATED).orElse(null);
|
||||
testAttribute(methodName, attr, cf);
|
||||
}
|
||||
}
|
||||
|
||||
private void testFields(ClassFile cf) throws ConstantPoolException {
|
||||
for (Field f : cf.fields) {
|
||||
String fieldName = cf.constant_pool.getUTF8Value(f.name_index);
|
||||
private void testFields(ClassModel cm) {
|
||||
for (FieldModel f : cm.fields()) {
|
||||
String fieldName = f.fieldName().stringValue();
|
||||
echo("Testing field : " + fieldName);
|
||||
Deprecated_attribute attr = (Deprecated_attribute)
|
||||
f.attributes.get(Attribute.Deprecated);
|
||||
testAttribute(fieldName, attr, cf);
|
||||
DeprecatedAttribute attr = f.findAttribute(Attributes.DEPRECATED).orElse(null);
|
||||
testAttribute(fieldName, attr, cm);
|
||||
}
|
||||
}
|
||||
|
||||
private void testAttribute(String name, Deprecated_attribute attr, ClassFile cf)
|
||||
throws ConstantPoolException {
|
||||
private void testAttribute(String name, DeprecatedAttribute attr, ClassModel cf) {
|
||||
if (name.contains("deprecated")) {
|
||||
testDeprecatedAttribute(name, attr, cf);
|
||||
} else {
|
||||
@ -306,13 +300,11 @@ public class DeprecatedTest extends TestResult {
|
||||
}
|
||||
}
|
||||
|
||||
private void testDeprecatedAttribute(String name, Deprecated_attribute attr, ClassFile cf)
|
||||
throws ConstantPoolException {
|
||||
private void testDeprecatedAttribute(String name, DeprecatedAttribute attr, ClassModel cm) {
|
||||
if (checkNotNull(attr, name + " must have deprecated attribute")) {
|
||||
checkEquals(0, attr.attribute_length,
|
||||
checkEquals(0, ((BoundAttribute<?>)attr).payloadLen(),
|
||||
"attribute_length should equal to 0");
|
||||
checkEquals("Deprecated",
|
||||
cf.constant_pool.getUTF8Value(attr.attribute_name_index),
|
||||
checkEquals("Deprecated", attr.attributeName(),
|
||||
name + " attribute_name_index");
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerAnnotationsInInnerAnnotationTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerAnnotationsInInnerClassTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerAnnotationsInInnerEnumTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerAnnotationsInInnerInterfaceTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @run main InnerClassesHierarchyTest
|
||||
*/
|
||||
@ -40,8 +45,9 @@ import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
|
||||
public class InnerClassesHierarchyTest extends TestResult {
|
||||
|
||||
@ -55,13 +61,12 @@ public class InnerClassesHierarchyTest extends TestResult {
|
||||
FilenameFilter filter =
|
||||
(dir, name) -> name.matches(outerClassName + ".*\\.class");
|
||||
for (File file : Arrays.asList(classDir.listFiles(filter))) {
|
||||
ClassFile classFile = readClassFile(file);
|
||||
String className = classFile.getName();
|
||||
for (ConstantPool.CPInfo info : classFile.constant_pool.entries()) {
|
||||
if (info instanceof ConstantPool.CONSTANT_Class_info) {
|
||||
ConstantPool.CONSTANT_Class_info classInfo =
|
||||
(ConstantPool.CONSTANT_Class_info) info;
|
||||
String cpClassName = classInfo.getBaseName();
|
||||
ClassModel classFile = readClassFile(file);
|
||||
String className = classFile.thisClass().name().stringValue();
|
||||
for (int i = 1; i < classFile.constantPool().entryCount(); ++i) {
|
||||
if (classFile.constantPool().entryByIndex(i) instanceof ClassEntry classInfo
|
||||
&& classInfo.asSymbol().isClassOrInterface()) {
|
||||
String cpClassName = classInfo.asInternalName();
|
||||
if (isInnerClass(cpClassName)) {
|
||||
get(className).add(cpClassName);
|
||||
}
|
||||
@ -96,9 +101,8 @@ public class InnerClassesHierarchyTest extends TestResult {
|
||||
if (!currentClassName.startsWith(outerClassName)) {
|
||||
continue;
|
||||
}
|
||||
ClassFile cf = readClassFile(currentClassName);
|
||||
InnerClasses_attribute attr = (InnerClasses_attribute)
|
||||
cf.getAttribute(Attribute.InnerClasses);
|
||||
ClassModel cf = readClassFile(currentClassName);
|
||||
InnerClassesAttribute attr = cf.findAttribute(Attributes.INNER_CLASSES).orElse(null);
|
||||
checkNotNull(attr, "Class should not contain "
|
||||
+ "inner classes attribute : " + currentClassName);
|
||||
checkTrue(innerClasses.containsKey(currentClassName),
|
||||
@ -107,12 +111,13 @@ public class InnerClassesHierarchyTest extends TestResult {
|
||||
if (setClasses == null) {
|
||||
continue;
|
||||
}
|
||||
checkEquals(attr.number_of_classes,
|
||||
checkEquals(attr.classes().size(),
|
||||
setClasses.size(),
|
||||
"Check number of inner classes : " + setClasses);
|
||||
for (Info info : attr.classes) {
|
||||
for (InnerClassInfo info : attr.classes()) {
|
||||
if (!info.innerClass().asSymbol().isClassOrInterface()) continue;
|
||||
String innerClassName = info
|
||||
.getInnerClassInfo(cf.constant_pool).getBaseName();
|
||||
.innerClass().asInternalName();
|
||||
checkTrue(setClasses.contains(innerClassName),
|
||||
currentClassName + " contains inner class : "
|
||||
+ innerClassName);
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesTestBase
|
||||
* @run main InnerClassesInAnonymousClassTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerClassesInInnerAnnotationTest
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerClassesInInnerClassTest true
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerClassesInInnerEnumTest true
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesInInnerClassTestBase InnerClassesTestBase
|
||||
* @run main InnerClassesInInnerInterfaceTest
|
||||
|
||||
@ -26,7 +26,12 @@
|
||||
* @bug 8042251
|
||||
* @summary Testing InnerClasses_attribute of inner classes in local class.
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @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
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
|
||||
@ -28,22 +28,27 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @run main InnerClassesIndexTest
|
||||
*/
|
||||
|
||||
import jdk.internal.classfile.*;
|
||||
import jdk.internal.classfile.attribute.*;
|
||||
import jdk.internal.classfile.constantpool.ClassEntry;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute.Info;
|
||||
|
||||
public class InnerClassesIndexTest extends TestResult {
|
||||
|
||||
@ -58,7 +63,7 @@ public class InnerClassesIndexTest extends TestResult {
|
||||
|
||||
private Set<String> getInnerClasses() {
|
||||
FilenameFilter filter = (dir, name) -> name.matches("InnerClassesIndexTest\\$.*\\.class");
|
||||
return Stream.of(getClassDir().listFiles(filter))
|
||||
return Arrays.stream(Objects.requireNonNull(getClassDir().listFiles(filter)))
|
||||
.map(File::getName)
|
||||
.map(s -> s.replace(".class", ""))
|
||||
.collect(Collectors.toSet());
|
||||
@ -67,24 +72,24 @@ public class InnerClassesIndexTest extends TestResult {
|
||||
public void test() throws TestFailedException {
|
||||
try {
|
||||
addTestCase("Source is InnerClassesIndexTest.java");
|
||||
ClassFile classFile = readClassFile(InnerClassesIndexTest.class);
|
||||
InnerClasses_attribute attr = (InnerClasses_attribute)
|
||||
classFile.getAttribute(Attribute.InnerClasses);
|
||||
ClassModel classFile = readClassFile(InnerClassesIndexTest.class);
|
||||
InnerClassesAttribute attr = classFile.findAttribute(Attributes.INNER_CLASSES).orElse(null);
|
||||
|
||||
Set<String> foundClasses = new HashSet<>();
|
||||
for (Info info : attr.classes) {
|
||||
String innerName = classFile.constant_pool.
|
||||
getClassInfo(info.inner_class_info_index).getBaseName();
|
||||
assert attr != null;
|
||||
for (InnerClassInfo info : attr.classes()) {
|
||||
String innerName = info.innerClass().asInternalName();
|
||||
echo("Testing class : " + innerName);
|
||||
if (isExcluded(innerName)) {
|
||||
echo("Ignored : " + innerName);
|
||||
continue;
|
||||
}
|
||||
foundClasses.add(innerName);
|
||||
checkEquals(info.outer_class_info_index, 0,
|
||||
ClassEntry out = info.outerClass().orElse(null);
|
||||
checkEquals(out == null? 0: out.index(), 0,
|
||||
"outer_class_info_index of " + innerName);
|
||||
if (innerName.matches("\\$\\d+")) {
|
||||
checkEquals(info.inner_name_index, 0,
|
||||
checkEquals(Objects.requireNonNull(info.innerName().orElse(null)).index(), 0,
|
||||
"inner_name_index of anonymous class");
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,12 @@
|
||||
* @library /tools/lib /tools/javac/lib ../lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* 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
|
||||
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
||||
* @build InnerClassesTestBase
|
||||
* @run main InnerClassesTest true
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user