8313422: test/langtools/tools/javac 144 test classes uses com.sun.tools.classfile library

Reviewed-by: asotona
This commit is contained in:
Qing Xiao 2023-09-07 15:37:25 +00:00 committed by Adam Sotona
parent 8557205a82
commit 8f7e29b2cd
144 changed files with 2743 additions and 2762 deletions

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 4241573 * @bug 4241573
* @summary SourceFile attribute includes full path * @summary SourceFile attribute includes full path
* @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.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.Attributes;
import com.sun.tools.classfile.SourceFile_attribute; import jdk.internal.classfile.attribute.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.jar.*; import java.util.jar.*;
@ -107,9 +112,9 @@ public class T4241573 {
void verifySourceFileAttribute(File f) { void verifySourceFileAttribute(File f) {
System.err.println("verify: " + f); System.err.println("verify: " + f);
try { try {
ClassFile cf = ClassFile.read(f); ClassModel cf = Classfile.of().parse(f.toPath());
SourceFile_attribute sfa = (SourceFile_attribute) cf.getAttribute(Attribute.SourceFile); SourceFileAttribute sfa = cf.findAttribute(Attributes.SOURCE_FILE).orElseThrow();
String found = sfa.getSourceFile(cf.constant_pool); String found = sfa.sourceFile().stringValue();
String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java"); String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java");
if (!expect.equals(found)) { if (!expect.equals(found)) {
error("bad value found: " + found + ", expected: " + expect); error("bad value found: " + found + ", expected: " + expect);

View File

@ -25,16 +25,19 @@
* @test * @test
* @bug 7003595 * @bug 7003595
* @summary IncompatibleClassChangeError with unreferenced local class with subclass * @summary IncompatibleClassChangeError with unreferenced local class with subclass
* @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.api
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
*/ */
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.InnerClasses_attribute;
import com.sun.tools.classfile.ConstantPool.*;
import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.api.JavacTool;
import java.io.File; import java.io.File;
@ -159,17 +162,17 @@ public class T7003595 {
String filename = cks[i].getClassfileName(cnames, cks, i); String filename = cks[i].getClassfileName(cnames, cks, i);
File compiledTest = new File(filename + ".class"); File compiledTest = new File(filename + ".class");
try { try {
ClassFile cf = ClassFile.read(compiledTest); ClassModel cf = Classfile.of().parse(compiledTest.toPath());
if (cf == null) { if (cf == null) {
throw new Error("Classfile not found: " + filename); throw new Error("Classfile not found: " + filename);
} }
InnerClasses_attribute innerClasses = (InnerClasses_attribute)cf.getAttribute(Attribute.InnerClasses); InnerClassesAttribute innerClasses = cf.findAttribute(Attributes.INNER_CLASSES).orElse(null);
ArrayList<String> foundInnerSig = new ArrayList<>(); ArrayList<String> foundInnerSig = new ArrayList<>();
if (innerClasses != null) { if (innerClasses != null) {
for (InnerClasses_attribute.Info info : innerClasses.classes) { for (InnerClassInfo info : innerClasses.classes()) {
String foundSig = info.getInnerClassInfo(cf.constant_pool).getName(); String foundSig = info.innerClass().asInternalName();
foundInnerSig.add(foundSig); foundInnerSig.add(foundSig);
} }
} }
@ -187,7 +190,7 @@ public class T7003595 {
if (expectedInnerSig.size() != foundInnerSig.size()) { if (expectedInnerSig.size() != foundInnerSig.size()) {
throw new Error("InnerClasses attribute for " + cnames[i] + " has wrong size\n" + throw new Error("InnerClasses attribute for " + cnames[i] + " has wrong size\n" +
"expected " + expectedInnerSig.size() + "\n" + "expected " + expectedInnerSig.size() + "\n" +
"found " + innerClasses.number_of_classes + "\n" + "found " + (innerClasses == null? 0: innerClasses.classes().size()) + "\n" +
source); source);
} }

View File

@ -25,15 +25,19 @@
* @test * @test
* @bug 7153958 8073372 * @bug 7153958 8073372
* @summary add constant pool reference to class containing inlined constants * @summary add constant pool reference to class containing inlined constants
* @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 pkg/ClassToBeStaticallyImportedA.java pkg/ClassToBeStaticallyImportedB.java CPoolRefClassContainingInlinedCts.java * @compile pkg/ClassToBeStaticallyImportedA.java pkg/ClassToBeStaticallyImportedB.java CPoolRefClassContainingInlinedCts.java
* @run main CPoolRefClassContainingInlinedCts * @run main CPoolRefClassContainingInlinedCts
*/ */
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; import jdk.internal.classfile.constantpool.ClassEntry;
import com.sun.tools.classfile.ConstantPool.CPInfo; import jdk.internal.classfile.constantpool.PoolEntry;
import com.sun.tools.classfile.ConstantPoolException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -66,19 +70,19 @@ public class CPoolRefClassContainingInlinedCts {
} }
} }
void checkReferences() throws IOException, ConstantPoolException { void checkReferences() throws IOException {
File testClasses = new File(System.getProperty("test.classes")); File testClasses = new File(System.getProperty("test.classes"));
File file = new File(testClasses, File file = new File(testClasses,
CPoolRefClassContainingInlinedCts.class.getName() + ".class"); CPoolRefClassContainingInlinedCts.class.getName() + ".class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
int i = 1; int i = 1;
CPInfo cpInfo; PoolEntry cpInfo;
while (i < classFile.constant_pool.size()) { while (i < classFile.constantPool().entryCount()) {
cpInfo = classFile.constant_pool.get(i); cpInfo = classFile.constantPool().entryByIndex(i);
if (cpInfo instanceof CONSTANT_Class_info) { if (cpInfo instanceof ClassEntry classEntry) {
checkClassName(((CONSTANT_Class_info)cpInfo).getName()); checkClassName(classEntry.asInternalName());
} }
i += cpInfo.size(); i += cpInfo.width();
} }
if (numberOfReferencedClassesToBeChecked != 16) { if (numberOfReferencedClassesToBeChecked != 16) {
throw new AssertionError("Class reference missing in the constant pool"); throw new AssertionError("Class reference missing in the constant pool");

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 7166455 * @bug 7166455
* @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp class * @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp 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
* @compile -source 16 -target 16 CheckACC_STRICTFlagOnclinitTest.java * @compile -source 16 -target 16 CheckACC_STRICTFlagOnclinitTest.java
* @run main CheckACC_STRICTFlagOnclinitTest * @run main CheckACC_STRICTFlagOnclinitTest
*/ */
@ -34,13 +39,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Method;
import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
public strictfp class CheckACC_STRICTFlagOnclinitTest { public strictfp class CheckACC_STRICTFlagOnclinitTest {
private static final String AssertionErrorMessage = private static final String AssertionErrorMessage =
@ -65,13 +64,11 @@ public strictfp class CheckACC_STRICTFlagOnclinitTest {
private List<String> errors = new ArrayList<>(); private List<String> errors = new ArrayList<>();
public static void main(String[] args) public static void main(String[] args) throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
new CheckACC_STRICTFlagOnclinitTest().run(); new CheckACC_STRICTFlagOnclinitTest().run();
} }
private void run() private void run() throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
String testClasses = System.getProperty("test.classes"); String testClasses = System.getProperty("test.classes");
check(testClasses, check(testClasses,
"CheckACC_STRICTFlagOnclinitTest.class", "CheckACC_STRICTFlagOnclinitTest.class",
@ -86,19 +83,15 @@ public strictfp class CheckACC_STRICTFlagOnclinitTest {
} }
} }
void check(String dir, String... fileNames) void check(String dir, String... fileNames) throws IOException{
throws
IOException,
ConstantPoolException,
Descriptor.InvalidDescriptor {
for (String fileName : fileNames) { for (String fileName : fileNames) {
ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); ClassModel classFileToCheck = Classfile.of().parse(new File(dir, fileName).toPath());
for (Method method : classFileToCheck.methods) { for (MethodModel method : classFileToCheck.methods()) {
if ((method.access_flags.flags & ACC_STRICT) == 0) { if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) {
errors.add(String.format(offendingMethodErrorMessage, errors.add(String.format(offendingMethodErrorMessage,
method.getName(classFileToCheck.constant_pool), method.methodName().stringValue(),
classFileToCheck.getName())); classFileToCheck.thisClass().asInternalName()));
} }
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 7199823 * @bug 7199823
* @summary javac generates inner class that can't be verified * @summary javac generates inner class that can't be verified
* @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 InnerClassCannotBeVerified * @run main InnerClassCannotBeVerified
*/ */
@ -37,8 +42,7 @@ import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPoolException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -85,17 +89,17 @@ public class InnerClassCannotBeVerified {
} }
} }
private void check(CompilationKind ck) throws IOException, ConstantPoolException { private void check(CompilationKind ck) throws IOException {
try { try {
File file = new File("Test$1.class"); File file = new File("Test$1.class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
if (ck == CompilationKind.POST_NESTMATES) { if (ck == CompilationKind.POST_NESTMATES) {
throw new AssertionError("Unexpected constructor tag class!"); throw new AssertionError("Unexpected constructor tag class!");
} }
boolean inheritsFromObject = boolean inheritsFromObject =
classFile.getSuperclassName().equals("java/lang/Object"); classFile.superclass().orElseThrow().asInternalName().equals("java/lang/Object");
boolean implementsNoInterface = classFile.interfaces.length == 0; boolean implementsNoInterface = classFile.interfaces().size() == 0;
boolean noMethods = classFile.methods.length == 0; boolean noMethods = classFile.methods().size() == 0;
if (!(inheritsFromObject && if (!(inheritsFromObject &&
implementsNoInterface && implementsNoInterface &&
noMethods)) { noMethods)) {

View File

@ -26,13 +26,18 @@
* @bug 8000518 * @bug 8000518
* @summary Javac generates duplicate name_and_type constant pool entry for * @summary Javac generates duplicate name_and_type constant pool entry for
* class BinaryOpValueExp.java * class BinaryOpValueExp.java
* @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 DuplicateConstantPoolEntry * @run main DuplicateConstantPoolEntry
*/ */
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPoolException; import jdk.internal.classfile.constantpool.ConstantPool;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -87,17 +92,18 @@ public class DuplicateConstantPoolEntry {
} }
} }
void checkReference() throws IOException, ConstantPoolException { void checkReference() throws IOException {
File file = new File("A.class"); File file = new File("A.class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
ConstantPool constantPool = classFile.constantPool();
for (int i = 1; for (int i = 1;
i < classFile.constant_pool.size() - 1; i < constantPool.entryCount() - 1;
i += classFile.constant_pool.get(i).size()) { i += constantPool.entryByIndex(i).width()) {
for (int j = i + classFile.constant_pool.get(i).size(); for (int j = i + constantPool.entryByIndex(i).width();
j < classFile.constant_pool.size(); j < constantPool.entryCount();
j += classFile.constant_pool.get(j).size()) { j += constantPool.entryByIndex(j).width()) {
if (classFile.constant_pool.get(i).toString(). if (constantPool.entryByIndex(i).toString().
equals(classFile.constant_pool.get(j).toString())) { equals(constantPool.entryByIndex(j).toString())) {
throw new AssertionError( throw new AssertionError(
"Duplicate entries in the constant pool at positions " + "Duplicate entries in the constant pool at positions " +
i + " and " + j); i + " and " + j);

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8005931 * @bug 8005931
* @summary javac doesn't set ACC_STRICT for classes with package access * @summary javac doesn't set ACC_STRICT for classes with package access
* @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.components
* java.base/jdk.internal.classfile.instruction
* java.base/jdk.internal.classfile.impl
* @run main CheckACC_STRICTFlagOnPkgAccessClassTest * @run main CheckACC_STRICTFlagOnPkgAccessClassTest
*/ */
@ -40,13 +45,7 @@ import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Method;
import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
public class CheckACC_STRICTFlagOnPkgAccessClassTest { public class CheckACC_STRICTFlagOnPkgAccessClassTest {
@ -62,14 +61,12 @@ public class CheckACC_STRICTFlagOnPkgAccessClassTest {
private List<String> errors = new ArrayList<>(); private List<String> errors = new ArrayList<>();
public static void main(String[] args) public static void main(String[] args) throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
new CheckACC_STRICTFlagOnPkgAccessClassTest().run(comp); new CheckACC_STRICTFlagOnPkgAccessClassTest().run(comp);
} }
private void run(JavaCompiler comp) private void run(JavaCompiler comp) throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
compile(comp); compile(comp);
check(); check();
if (errors.size() > 0) { if (errors.size() > 0) {
@ -95,18 +92,14 @@ public class CheckACC_STRICTFlagOnPkgAccessClassTest {
} }
} }
void check() void check() throws IOException {
throws ClassModel classFileToCheck = Classfile.of().parse(new File("Test.class").toPath());
IOException,
ConstantPoolException,
Descriptor.InvalidDescriptor {
ClassFile classFileToCheck = ClassFile.read(new File("Test.class"));
for (Method method : classFileToCheck.methods) { for (MethodModel method : classFileToCheck.methods()) {
if ((method.access_flags.flags & ACC_STRICT) == 0) { if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) {
errors.add(String.format(offendingMethodErrorMessage, errors.add(String.format(offendingMethodErrorMessage,
method.getName(classFileToCheck.constant_pool), method.methodName().stringValue(),
classFileToCheck.getName())); classFileToCheck.thisClass().asInternalName()));
} }
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8161013 * @bug 8161013
* @summary Verify that anonymous class binaries have the correct flags set * @summary Verify that anonymous class binaries have the correct flags set
* @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 AnonymousClassFlags * @run main AnonymousClassFlags
*/ */
@ -33,8 +38,9 @@ import java.util.*;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import static com.sun.tools.classfile.AccessFlags.*; import jdk.internal.classfile.attribute.InnerClassInfo;
import jdk.internal.classfile.attribute.InnerClassesAttribute;
public class AnonymousClassFlags { public class AnonymousClassFlags {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -89,10 +95,10 @@ public class AnonymousClassFlags {
instanceMethod(); instanceMethod();
Path outerFile = Paths.get(classesDir, getClass().getName() + ".class"); Path outerFile = Paths.get(classesDir, getClass().getName() + ".class");
ClassFile outerClass = ClassFile.read(outerFile); ClassModel outerClass = Classfile.of().parse(outerFile);
for (Map.Entry<String,Integer> entry : anonClasses.entrySet()) { for (Map.Entry<String,Integer> entry : anonClasses.entrySet()) {
Path innerFile = Paths.get(classesDir, entry.getKey() + ".class"); Path innerFile = Paths.get(classesDir, entry.getKey() + ".class");
ClassFile innerClass = ClassFile.read(innerFile); ClassModel innerClass = Classfile.of().parse(innerFile);
String name = entry.getKey(); String name = entry.getKey();
int expected = entry.getValue(); int expected = entry.getValue();
assertInnerFlags(outerClass, name, expected); assertInnerFlags(outerClass, name, expected);
@ -101,11 +107,11 @@ public class AnonymousClassFlags {
} }
} }
static void assertClassFlags(ClassFile classFile, String name, int expected) { static void assertClassFlags(ClassModel classFile, String name, int expected) {
int mask = ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT | int mask = Classfile.ACC_PUBLIC | Classfile.ACC_FINAL | Classfile.ACC_INTERFACE | Classfile.ACC_ABSTRACT |
ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM; Classfile.ACC_SYNTHETIC | Classfile.ACC_ANNOTATION | Classfile.ACC_ENUM;
int classExpected = (expected & mask) | ACC_SUPER; int classExpected = (expected & mask) | Classfile.ACC_SUPER;
int classActual = classFile.access_flags.flags; int classActual = classFile.flags().flagsMask();
if (classActual != classExpected) { if (classActual != classExpected) {
throw new AssertionError("Incorrect access_flags for class " + name + throw new AssertionError("Incorrect access_flags for class " + name +
": expected=" + classExpected + ", actual=" + classActual); ": expected=" + classExpected + ", actual=" + classActual);
@ -113,27 +119,27 @@ public class AnonymousClassFlags {
} }
static void assertInnerFlags(ClassFile classFile, String name, int expected) throws ConstantPoolException { static void assertInnerFlags(ClassModel classFile, String name, int expected) {
int innerActual = lookupInnerFlags(classFile, name).flags; int innerActual = lookupInnerFlags(classFile, name);
if (innerActual != expected) { if (innerActual != expected) {
throw new AssertionError("Incorrect inner_class_access_flags for class " + name + throw new AssertionError("Incorrect inner_class_access_flags for class " + name +
" in class " + classFile.getName() + " in class " + classFile.thisClass().asInternalName() +
": expected=" + expected + ", actual=" + innerActual); ": expected=" + expected + ", actual=" + innerActual);
} }
} }
private static AccessFlags lookupInnerFlags(ClassFile classFile, String innerName) throws ConstantPoolException { private static int lookupInnerFlags(ClassModel classFile, String innerName) {
InnerClasses_attribute inners = (InnerClasses_attribute) classFile.getAttribute("InnerClasses"); InnerClassesAttribute inners = classFile.findAttribute(Attributes.INNER_CLASSES).orElse(null);
if (inners == null) { if (inners == null) {
throw new AssertionError("InnerClasses attribute missing in class " + classFile.getName()); throw new AssertionError("InnerClasses attribute missing in class " + classFile.thisClass().asInternalName());
} }
for (InnerClasses_attribute.Info info : inners.classes) { for (InnerClassInfo info: inners.classes()) {
String entryName = info.getInnerClassInfo(classFile.constant_pool).getName(); String entryName = info.innerClass().asInternalName();
if (innerName.equals(entryName)) { if (innerName.equals(entryName)) {
return info.inner_class_access_flags; return info.flagsMask();
} }
} }
throw new AssertionError("No InnerClasses entry in class " + classFile.getName() + " for class " + innerName); throw new AssertionError("No InnerClasses entry in class " + classFile.thisClass().asInternalName() + " for class " + innerName);
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters AnnotationTest.java * @compile -parameters AnnotationTest.java
* @run main MethodParametersTester AnnotationTest AnnotationTest.out * @run main MethodParametersTester AnnotationTest AnnotationTest.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters AnonymousClass.java * @compile -parameters AnonymousClass.java
* @run main MethodParametersTester AnonymousClass AnonymousClass.out * @run main MethodParametersTester AnonymousClass AnonymousClass.out

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import com.sun.tools.classfile.*;
/**
* Trivial {@code Attribute.Visitor} implementation, to make it easy to
* write visitors for specific attributes.
*/
class AttributeVisitor<R, P> implements Attribute.Visitor<R, P> {
public R visitBootstrapMethods(BootstrapMethods_attribute attr, P p) { return null; }
public R visitDefault(DefaultAttribute attr, P p) { return null; }
public R visitAnnotationDefault(AnnotationDefault_attribute attr, P p) { return null; }
public R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p) { return null; }
public R visitCode(Code_attribute attr, P p) { return null; }
public R visitCompilationID(CompilationID_attribute attr, P p) { return null; }
public R visitConstantValue(ConstantValue_attribute attr, P p) { return null; }
public R visitDeprecated(Deprecated_attribute attr, P p) { return null; }
public R visitEnclosingMethod(EnclosingMethod_attribute attr, P p) { return null; }
public R visitExceptions(Exceptions_attribute attr, P p) { return null; }
public R visitInnerClasses(InnerClasses_attribute attr, P p) { return null; }
public R visitLineNumberTable(LineNumberTable_attribute attr, P p) { return null; }
public R visitLocalVariableTable(LocalVariableTable_attribute attr, P p) { return null; }
public R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p) { return null; }
public R visitNestHost(NestHost_attribute attr, P p) { return null; }
public R visitMethodParameters(MethodParameters_attribute attr, P p) { return null; }
public R visitModule(Module_attribute attr, P p) { return null; }
public R visitModuleHashes(ModuleHashes_attribute attr, P p) { return null; }
public R visitModuleMainClass(ModuleMainClass_attribute attr, P p) { return null; }
public R visitModulePackages(ModulePackages_attribute attr, P p) { return null; }
public R visitModuleResolution(ModuleResolution_attribute attr, P p) { return null; }
public R visitModuleTarget(ModuleTarget_attribute attr, P p) { return null; }
public R visitNestMembers(NestMembers_attribute attr, P p) { return null; }
public R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p) { return null; }
public R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p) { return null; }
public R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p) { return null; }
public R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p) { return null; }
public R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p) { return null; }
public R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p) { return null; }
public R visitSignature(Signature_attribute attr, P p) { return null; }
public R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p) { return null; }
public R visitSourceFile(SourceFile_attribute attr, P p) { return null; }
public R visitSourceID(SourceID_attribute attr, P p) { return null; }
public R visitStackMap(StackMap_attribute attr, P p) { return null; }
public R visitStackMapTable(StackMapTable_attribute attr, P p) { return null; }
public R visitSynthetic(Synthetic_attribute attr, P p) { return null; }
public R visitPermittedSubclasses(PermittedSubclasses_attribute attr, P p) { return null; }
public R visitRecord(Record_attribute attr, P p) { return null; }
}

View File

@ -21,12 +21,15 @@
* questions. * questions.
*/ */
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import jdk.internal.classfile.constantpool.Utf8Entry;
import java.io.*; import java.io.*;
import com.sun.tools.classfile.*; import java.lang.constant.MethodTypeDesc;
/** /**
* The {@code ClassFileVisitor} reads a class file using the * The {@code ClassFileVisitor} reads a class file using the
* {@code com.sun.tools.classfile} library. It iterates over the methods * {@code jdk.internal.classfile} library. It iterates over the methods
* in a class, and checks MethodParameters attributes against JLS * in a class, and checks MethodParameters attributes against JLS
* requirements, as well as assumptions about the javac implementations. * requirements, as well as assumptions about the javac implementations.
* <p> * <p>
@ -63,7 +66,7 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
public boolean isPublic; public boolean isPublic;
public boolean isStatic; public boolean isStatic;
public boolean isAnon; public boolean isAnon;
public ClassFile classFile; public ClassModel classFile;
public ClassFileVisitor(MethodParametersTester tester) { public ClassFileVisitor(MethodParametersTester tester) {
@ -84,16 +87,15 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
*/ */
void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception { void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception {
this.cname = cname; this.cname = cname;
classFile = ClassFile.read(cfile); classFile = Classfile.of().parse(cfile.toPath());
isEnum = classFile.access_flags.is(AccessFlags.ACC_ENUM); isEnum = (classFile.flags().flagsMask() & Classfile.ACC_ENUM) != 0;
isInterface = classFile.access_flags.is(AccessFlags.ACC_INTERFACE); isInterface = (classFile.flags().flagsMask() & Classfile.ACC_INTERFACE) != 0;
isPublic = classFile.access_flags.is(AccessFlags.ACC_PUBLIC); isPublic = (classFile.flags().flagsMask() & Classfile.ACC_PUBLIC) != 0;
isInner = false; isInner = false;
isStatic = false; isStatic = false;
isAnon = false; isAnon = false;
Attribute attr = classFile.getAttribute("InnerClasses"); classFile.findAttribute(Attributes.INNER_CLASSES).ifPresent(this::visitInnerClasses);
if (attr != null) attr.accept(new InnerClassVisitor(), null);
isAnon = isInner & isAnon; isAnon = isInner & isAnon;
sb.append(isStatic ? "static " : "") sb.append(isStatic ? "static " : "")
@ -105,44 +107,41 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
} }
sb.append("\n"); sb.append("\n");
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
new MethodVisitor().visitMethod(method, sb); new MethodVisitor().visitMethod(method, sb);
} }
} }
/** /**
* Used to visit InnerClasses_attribute of a class, * Used to visit InnerClassesAttribute of a class,
* to determne if this class is an local class, and anonymous * to determne if this class is an local class, and anonymous
* inner class or a none-static member class. These types of * inner class or a none-static member class. These types of
* classes all have an containing class instances field that * classes all have an containing class instances field that
* requires an implicit or synthetic constructor argument. * requires an implicit or synthetic constructor argument.
*/ */
class InnerClassVisitor extends AttributeVisitor<Void, Void> { void visitInnerClasses(InnerClassesAttribute iattr) {
public Void visitInnerClasses(InnerClasses_attribute iattr, Void v) {
try{ try{
for (InnerClasses_attribute.Info info : iattr.classes) { for (InnerClassInfo info : iattr.classes()) {
if (info.getInnerClassInfo(classFile.constant_pool) == null) continue; if (info.innerClass() == null) continue;
String in = info.getInnerClassInfo(classFile.constant_pool).getName(); String in = info.innerClass().name().stringValue();
if (in == null || !cname.equals(in)) continue; if (!cname.equals(in)) continue;
isInner = true; isInner = true;
isAnon = null == info.getInnerName(classFile.constant_pool); isAnon = null == info.innerName().orElse(null);
isStatic = info.inner_class_access_flags.is(AccessFlags.ACC_STATIC); isStatic = (info.flagsMask() & Classfile.ACC_STATIC) != 0;
break; break;
} }
} catch(Exception e) { } catch(Exception e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
return null;
}
} }
/** /**
* Check the MethodParameters attribute of a method. * Check the MethodParameters attribute of a method.
*/ */
class MethodVisitor extends AttributeVisitor<Void, StringBuilder> { class MethodVisitor {
public String mName; public String mName;
public Descriptor mDesc; public MethodTypeDesc mDesc;
public int mParams; public int mParams;
public int mAttrs; public int mAttrs;
public int mNumParams; public int mNumParams;
@ -153,26 +152,27 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
public boolean isFinal; public boolean isFinal;
public String prefix; public String prefix;
void visitMethod(Method method, StringBuilder sb) throws Exception { void visitMethod(MethodModel method, StringBuilder sb) {
mName = method.getName(classFile.constant_pool); mName = method.methodName().stringValue();
mDesc = method.descriptor; mDesc = method.methodTypeSymbol();
mParams = mDesc.getParameterCount(classFile.constant_pool); mParams = mDesc.parameterCount();
mAttrs = method.attributes.attrs.length; mAttrs = method.attributes().size();
mNumParams = -1; // no MethodParameters attribute found mNumParams = -1; // no MethodParameters attribute found
mSynthetic = method.access_flags.is(AccessFlags.ACC_SYNTHETIC); mSynthetic = (method.flags().flagsMask() & Classfile.ACC_SYNTHETIC) != 0;
mIsConstructor = mName.equals("<init>"); mIsConstructor = mName.equals("<init>");
mIsClinit = mName.equals("<clinit>"); mIsClinit = mName.equals("<clinit>");
prefix = cname + "." + mName + "() - "; prefix = cname + "." + mName + "() - ";
mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE); mIsBridge = (method.flags().flagsMask() & Classfile.ACC_BRIDGE) != 0;
if (mIsClinit) { if (mIsClinit) {
sb = new StringBuilder(); // Discard output sb = new StringBuilder(); // Discard output
} }
sb.append(cname).append(".").append(mName).append("("); sb.append(cname).append(".").append(mName).append("(");
for (Attribute a : method.attributes) { for (Attribute<?> a : method.attributes()) {
a.accept(this, sb); if (a instanceof MethodParametersAttribute pa)
visitMethodParameters(pa, sb);
} }
if (mNumParams == -1) { if (mNumParams == -1) {
if (mSynthetic) { if (mSynthetic) {
@ -199,28 +199,28 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
} }
} }
public Void visitMethodParameters(MethodParameters_attribute mp, public void visitMethodParameters(MethodParametersAttribute mp,
StringBuilder sb) { StringBuilder sb) {
// SPEC: At most one MethodParameters attribute allowed // SPEC: At most one MethodParameters attribute allowed
if (mNumParams != -1) { if (mNumParams != -1) {
error(prefix + "Multiple MethodParameters attributes"); error(prefix + "Multiple MethodParameters attributes");
return null; return;
} }
mNumParams = mp.method_parameter_table_length; mNumParams = mp.parameters().size();
// SPEC: An empty attribute is not allowed! // SPEC: An empty attribute is not allowed!
if (mNumParams == 0) { if (mNumParams == 0) {
error(prefix + "0 length MethodParameters attribute"); error(prefix + "0 length MethodParameters attribute");
return null; return;
} }
// SPEC: one name per parameter. // SPEC: one name per parameter.
if (mNumParams != mParams) { if (mNumParams != mParams) {
error(prefix + "found " + mNumParams + error(prefix + "found " + mNumParams +
" parameters, expected " + mParams); " parameters, expected " + mParams);
return null; return;
} }
// IMPL: Whether MethodParameters attributes will be generated // IMPL: Whether MethodParameters attributes will be generated
@ -232,33 +232,23 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
String sep = ""; String sep = "";
String userParam = null; String userParam = null;
for (int x = 0; x < mNumParams; x++) { for (int x = 0; x < mNumParams; x++) {
isFinal = (mp.method_parameter_table[x].flags & AccessFlags.ACC_FINAL) != 0; isFinal = (mp.parameters().get(x).flagsMask() & Classfile.ACC_FINAL) != 0;
// IMPL: Assume all parameters are named, something. // IMPL: Assume all parameters are named, something.
int cpi = mp.method_parameter_table[x].name_index; Utf8Entry paramEntry = mp.parameters().get(x).name().orElse(null);
if (cpi == 0) { if (paramEntry == null) {
error(prefix + "name expected, param[" + x + "]"); error(prefix + "name expected, param[" + x + "]");
return null; return;
} }
String param = paramEntry.stringValue();
// SPEC: a non 0 index, must be valid!
String param = null;
try {
param = classFile.constant_pool.getUTF8Value(cpi);
if (isFinal) if (isFinal)
param = "final " + param; param = "final " + paramEntry.stringValue();
sb.append(sep).append(param); sb.append(sep).append(param);
sep = ", "; sep = ", ";
} catch(ConstantPoolException e) {
error(prefix + "invalid index " + cpi + " for param["
+ x + "]");
return null;
}
// Check availability, flags and special names // Check availability, flags and special names
int check = checkParam(mp, param, x, sb, isFinal); int check = checkParam(mp, param, x, sb, isFinal);
if (check < 0) { if (check < 0) {
return null; return;
} }
// TEST: check test assumptions about parameter name. // TEST: check test assumptions about parameter name.
@ -282,7 +272,7 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
if (check > 0 && expect != null && !param.equals(expect)) { if (check > 0 && expect != null && !param.equals(expect)) {
error(prefix + "param[" + x + "]='" error(prefix + "param[" + x + "]='"
+ param + "' expected '" + expect + "'"); + param + "' expected '" + expect + "'");
return null; return;
} }
} }
if (mSynthetic) { if (mSynthetic) {
@ -290,7 +280,6 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
} else { } else {
sb.append(")"); sb.append(")");
} }
return null;
} }
/* /*
@ -300,13 +289,13 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
* the parameter is compiler generated, or 1 for an (presumably) * the parameter is compiler generated, or 1 for an (presumably)
* explicitly declared parameter. * explicitly declared parameter.
*/ */
int checkParam(MethodParameters_attribute mp, String param, int index, int checkParam(MethodParametersAttribute mp, String param, int index,
StringBuilder sb, boolean isFinal) { StringBuilder sb, boolean isFinal) {
boolean synthetic = (mp.method_parameter_table[index].flags boolean synthetic = (mp.parameters().get(index).flagsMask()
& AccessFlags.ACC_SYNTHETIC) != 0; & Classfile.ACC_SYNTHETIC) != 0;
boolean mandated = (mp.method_parameter_table[index].flags boolean mandated = (mp.parameters().get(index).flagsMask()
& AccessFlags.ACC_MANDATED) != 0; & Classfile.ACC_MANDATED) != 0;
// Setup expectations for flags and special names // Setup expectations for flags and special names
String expect = null; String expect = null;
@ -362,7 +351,7 @@ class ClassFileVisitor extends MethodParametersTester.Visitor {
allowMandated = true; allowMandated = true;
} else if (mIsBridge) { } else if (mIsBridge) {
allowSynthetic = true; allowSynthetic = true;
/* you can't expect an special name for bridges' parameters. /* you can't expect a special name for bridges' parameters.
* The name of the original parameters are now copied. * The name of the original parameters are now copied.
*/ */
expect = null; expect = null;

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters Constructors.java * @compile -parameters Constructors.java
* @run main MethodParametersTester Constructors Constructors.out * @run main MethodParametersTester Constructors Constructors.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 8008658 * @bug 8006582 8008658
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters EnumTest.java * @compile -parameters EnumTest.java
* @run main MethodParametersTester EnumTest EnumTest.out * @run main MethodParametersTester EnumTest EnumTest.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters InstanceMethods.java * @compile -parameters InstanceMethods.java
* @run main MethodParametersTester InstanceMethods InstanceMethods.out * @run main MethodParametersTester InstanceMethods InstanceMethods.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 8037546 8138729 * @bug 8006582 8037546 8138729
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters LambdaTest.java * @compile -parameters LambdaTest.java
* @run main MethodParametersTester LambdaTest LambdaTest.out * @run main MethodParametersTester LambdaTest LambdaTest.out

View File

@ -25,21 +25,26 @@
* @test * @test
* @bug 8190452 * @bug 8190452
* @summary javac should not add MethodParameters attributes to v51 and earlier class files * @summary javac should not add MethodParameters attributes to v51 and earlier class files
* @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 LegacyOutputTest * @build LegacyOutputTest
* @run main LegacyOutputTest * @run main LegacyOutputTest
*/ */
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Method; import jdk.internal.classfile.attribute.MethodParameterInfo;
import com.sun.tools.classfile.MethodParameters_attribute; import jdk.internal.classfile.attribute.MethodParametersAttribute;
import com.sun.tools.classfile.MethodParameters_attribute.Entry;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -90,23 +95,22 @@ public class LegacyOutputTest {
if (!task.call()) { if (!task.call()) {
throw new AssertionError("compilation failed"); throw new AssertionError("compilation failed");
} }
ClassFile classFile = ClassFile.read(Paths.get("Test.class")); ClassModel classFile = Classfile.of().parse(Paths.get("Test.class"));
Method method = getMethod(classFile, "f"); MethodModel method = getMethod(classFile, "f");
MethodParameters_attribute attribute = MethodParametersAttribute attribute = method.findAttribute(Attributes.METHOD_PARAMETERS).orElse(null);
(MethodParameters_attribute) method.attributes.get("MethodParameters");
if (attribute == null) { if (attribute == null) {
return null; return null;
} }
List<String> parameterNames = new ArrayList<>(); List<String> parameterNames = new ArrayList<>();
for (Entry e : attribute.method_parameter_table) { for (MethodParameterInfo e : attribute.parameters()) {
parameterNames.add(classFile.constant_pool.getUTF8Value(e.name_index)); parameterNames.add(e.name().orElseThrow().stringValue());
} }
return parameterNames; return parameterNames;
} }
private static Method getMethod(ClassFile classFile, String name) throws Exception { private static MethodModel getMethod(ClassModel classFile, String name) throws Exception {
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (classFile.constant_pool.getUTF8Value(method.name_index).equals(name)) { if (method.methodName().equalsString(name)) {
return method; return method;
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 8008658 * @bug 8006582 8008658
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters LocalClassTest.java * @compile -parameters LocalClassTest.java
* @run main MethodParametersTester LocalClassTest LocalClassTest.out * @run main MethodParametersTester LocalClassTest LocalClassTest.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 8008658 * @bug 8006582 8008658
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters MemberClassTest.java * @compile -parameters MemberClassTest.java
* @run main MethodParametersTester MemberClassTest MemberClassTest.out * @run main MethodParametersTester MemberClassTest MemberClassTest.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters StaticMethods.java * @compile -parameters StaticMethods.java
* @run main MethodParametersTester StaticMethods StaticMethods.out * @run main MethodParametersTester StaticMethods StaticMethods.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8006582 * @bug 8006582
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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 MethodParametersTester ClassFileVisitor ReflectionVisitor * @build MethodParametersTester ClassFileVisitor ReflectionVisitor
* @compile -parameters UncommonParamNames.java * @compile -parameters UncommonParamNames.java
* @run main MethodParametersTester UncommonParamNames UncommonParamNames.out * @run main MethodParametersTester UncommonParamNames UncommonParamNames.out

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8004727 * @bug 8004727
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @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.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.comp
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
@ -34,7 +39,8 @@
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
*/ */
// key: opt.arg.parameters // key: opt.arg.parameters
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.Main; import com.sun.tools.javac.main.Main;
@ -43,6 +49,7 @@ import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import java.io.*; import java.io.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import java.nio.file.Files;
import java.util.*; import java.util.*;
public class MethodParametersTest { public class MethodParametersTest {
@ -147,8 +154,7 @@ public class MethodParametersTest {
// parameter. // parameter.
final Element baz = cf.loadClass(syms.unnamedModule, name); final Element baz = cf.loadClass(syms.unnamedModule, name);
for (Element e : baz.getEnclosedElements()) { for (Element e : baz.getEnclosedElements()) {
if (e instanceof ExecutableElement) { if (e instanceof ExecutableElement ee) {
final ExecutableElement ee = (ExecutableElement) e;
final List<? extends VariableElement> params = final List<? extends VariableElement> params =
ee.getParameters(); ee.getParameters();
if (1 != params.size()) if (1 != params.size())
@ -165,156 +171,117 @@ public class MethodParametersTest {
void modifyBaz(boolean flip) throws Exception { void modifyBaz(boolean flip) throws Exception {
final File Baz_class = new File(classesdir, Baz_name + ".class"); final File Baz_class = new File(classesdir, Baz_name + ".class");
final ClassFile baz = ClassFile.read(Baz_class); final ClassModel baz = Classfile.of().parse(Baz_class.toPath());
final int ind = baz.constant_pool.getUTF8Index("baz");
MethodParameters_attribute mpattr = null;
int mpind = 0;
Code_attribute cattr = null;
int cind = 0;
// Find the indexes of the MethodParameters and the Code attributes // Find MethodParameters and the Code attributes
if (baz.methods.length != 1) if (baz.methods().size() != 1)
throw new Exception("Classfile Baz badly formed: wrong number of methods"); throw new Exception("Classfile Baz badly formed: wrong number of methods");
if (!baz.methods[0].getName(baz.constant_pool).equals("<init>")) if (!baz.methods().get(0).methodName().equalsString("<init>"))
throw new Exception("Classfile Baz badly formed: method has name " + throw new Exception("Classfile Baz badly formed: method has name " +
baz.methods[0].getName(baz.constant_pool)); baz.methods().get(0).methodName().stringValue());
for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) { MethodParametersAttribute mpattr = baz.methods().get(0).findAttribute(Attributes.METHOD_PARAMETERS).orElse(null);
if (baz.methods[0].attributes.attrs[i] instanceof CodeAttribute cattr = baz.methods().get(0).findAttribute(Attributes.CODE).orElse(null);;
MethodParameters_attribute) {
mpattr = (MethodParameters_attribute)
baz.methods[0].attributes.attrs[i];
mpind = i;
} else if (baz.methods[0].attributes.attrs[i] instanceof
Code_attribute) {
cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
cind = i;
}
}
if (null == mpattr) if (null == mpattr)
throw new Exception("Classfile Baz badly formed: no method parameters info"); throw new Exception("Classfile Baz badly formed: no method parameters info");
if (null == cattr) if (null == cattr)
throw new Exception("Classfile Baz badly formed: no local variable table"); throw new Exception("Classfile Baz badly formed: no local variable table");
int flags = mpattr.method_parameter_table[0].flags;
// Alter the MethodParameters attribute, changing the name of // Alter the MethodParameters attribute, changing the name of
// the parameter from i to baz. This requires Black Magic... // the parameter from i to baz.
// byte[] bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> {
// The (well-designed) classfile library (correctly) does not if (methodElement instanceof MethodParametersAttribute a) {
// allow us to mess around with the attribute data structures, List<MethodParameterInfo> newParameterInfos = new ArrayList<>();
// or arbitrarily generate new ones. for (MethodParameterInfo info : a.parameters()) {
// newParameterInfos.add(MethodParameterInfo.ofParameter("baz".describeConstable(), info.flagsMask()));
// Instead, we install a new subclass of Attribute that
// hijacks the Visitor pattern and outputs the sequence of
// bytes that we want. This only works in this particular
// instance, because we know we'll only every see one kind of
// visitor.
//
// If anyone ever changes the makeup of the Baz class, or
// tries to install some kind of visitor that gets run prior
// to serialization, this will break.
baz.methods[0].attributes.attrs[mpind] =
new Attribute(mpattr.attribute_name_index,
mpattr.attribute_length) {
public <R, D> R accept(Visitor<R, D> visitor, D data) {
if (data instanceof ByteArrayOutputStream) {
ByteArrayOutputStream out =
(ByteArrayOutputStream) data;
out.write(1);
out.write((ind >> 8) & 0xff);
out.write(ind & 0xff);
out.write((flags >> 24) & 0xff);
out.write((flags >> 16) & 0xff);
out.write((flags >> 8) & 0xff);
out.write(flags & 0xff);
} else
throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test. Update the test and it should work.");
return null;
} }
}; a = MethodParametersAttribute.of(newParameterInfos);
methodBuilder.with(a);
} else {
methodBuilder.with(methodElement);
}
}));
// Flip the code and method attributes. This is for checking // Flip the code and method attributes(). This is for checking
// that order doesn't matter. // that order doesn't matter.
if (flip) { if (flip) {
baz.methods[0].attributes.attrs[mpind] = cattr; bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> {
baz.methods[0].attributes.attrs[cind] = mpattr; if (methodElement instanceof MethodParametersAttribute) {
methodBuilder.with(cattr);
} else if (methodElement instanceof CodeAttribute){
methodBuilder.with(mpattr);
} else {
methodBuilder.with(methodElement);
} }
}));
new ClassWriter().write(baz, Baz_class); }
Files.write(Baz_class.toPath(), bazBytes);
} }
// Run a bunch of structural tests on foo to make sure it looks right. // Run a bunch of structural tests on foo to make sure it looks right.
void checkFoo() throws Exception { void checkFoo() throws Exception {
final File Foo_class = new File(classesdir, Foo_name + ".class"); final File Foo_class = new File(classesdir, Foo_name + ".class");
final ClassFile foo = ClassFile.read(Foo_class); final ClassModel foo = Classfile.of().parse(Foo_class.toPath());
for (int i = 0; i < foo.methods.length; i++) { for (int i = 0; i < foo.methods().size(); i++) {
System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool)); System.err.println("Examine method Foo." + foo.methods().get(i).methodName());
if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) { if (foo.methods().get(i).methodName().equalsString("foo2")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) for (int j = 0; j < foo.methods().get(i).attributes().size(); j++)
if (foo.methods[i].attributes.attrs[j] instanceof if (foo.methods().get(i).attributes().get(j) instanceof MethodParametersAttribute mp) {
MethodParameters_attribute) {
MethodParameters_attribute mp =
(MethodParameters_attribute)
foo.methods[i].attributes.attrs[j];
System.err.println("Foo.foo2 should have 2 parameters: j and k"); System.err.println("Foo.foo2 should have 2 parameters: j and k");
if (2 != mp.method_parameter_table_length) if (2 != mp.parameters().size())
error("expected 2 method parameter entries in foo2, got " + error("expected 2 method parameter entries in foo2, got " +
mp.method_parameter_table_length); mp.parameters().size());
else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j")) else if (!mp.parameters().get(0).name().orElseThrow().equalsString("j"))
error("expected first parameter to foo2 to be \"j\", got \"" + error("expected first parameter to foo2 to be \"j\", got \"" +
foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) + mp.parameters().get(0).name().orElseThrow().stringValue() +
"\" instead"); "\" instead");
else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k")) else if (!mp.parameters().get(1).name().orElseThrow().equalsString("k"))
error("expected first parameter to foo2 to be \"k\", got \"" + error("expected first parameter to foo2 to be \"k\", got \"" +
foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) + mp.parameters().get(1).name().orElseThrow() +
"\" instead"); "\" instead");
} }
} }
else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) { else if (foo.methods().get(i).methodName().equalsString("<init>")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) { for (int j = 0; j < foo.methods().get(i).attributes().size(); j++) {
if (foo.methods[i].attributes.attrs[j] instanceof if (foo.methods().get(i).attributes().get(j) instanceof
MethodParameters_attribute) MethodParametersAttribute)
error("Zero-argument constructor shouldn't have MethodParameters"); error("Zero-argument constructor shouldn't have MethodParameters");
} }
} }
else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) { else if (foo.methods().get(i).methodName().equalsString("foo0")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) for (int j = 0; j < foo.methods().get(i).attributes().size(); j++)
if (foo.methods[i].attributes.attrs[j] instanceof if (foo.methods().get(i).attributes().get(j) instanceof
MethodParameters_attribute) MethodParametersAttribute)
error("Zero-argument method shouldn't have MethodParameters"); error("Zero-argument method shouldn't have MethodParameters");
} }
else else
error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo"); error("Unknown method " + foo.methods().get(i).methodName() + " showed up in class Foo");
} }
} }
// Run a bunch of structural tests on Bar to make sure it looks right. // Run a bunch of structural tests on Bar to make sure it looks right.
void checkBar() throws Exception { void checkBar() throws Exception {
final File Bar_class = new File(classesdir, Bar_name + ".class"); final File Bar_class = new File(classesdir, Bar_name + ".class");
final ClassFile bar = ClassFile.read(Bar_class); final ClassModel bar = Classfile.of().parse(Bar_class.toPath());
for (int i = 0; i < bar.methods.length; i++) { for (int i = 0; i < bar.methods().size(); i++) {
System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool)); System.err.println("Examine method Bar." + bar.methods().get(i).methodName());
if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) { if (bar.methods().get(i).methodName().equalsString("<init>")) {
for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) for (int j = 0; j < bar.methods().get(i).attributes().size(); j++)
if (bar.methods[i].attributes.attrs[j] instanceof if (bar.methods().get(i).attributes().get(j) instanceof
MethodParameters_attribute) { MethodParametersAttribute mp) {
MethodParameters_attribute mp =
(MethodParameters_attribute)
bar.methods[i].attributes.attrs[j];
System.err.println("Bar constructor should have 1 parameter: i"); System.err.println("Bar constructor should have 1 parameter: i");
if (1 != mp.method_parameter_table_length) if (1 != mp.parameters().size())
error("expected 1 method parameter entries in constructor, got " + error("expected 1 method parameter entries in constructor, got " +
mp.method_parameter_table_length); mp.parameters().size());
else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i")) else if (!mp.parameters().get(0).name().orElseThrow().equalsString("i"))
error("expected first parameter to foo2 to be \"i\", got \"" + error("expected first parameter to foo2 to be \"i\", got \"" +
bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) + mp.parameters().get(0).name().orElseThrow() +
"\" instead"); "\" instead");
} }
} }
else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) { else if (bar.methods().get(i).methodName().equalsString("foo")) {
for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) { for (int j = 0; j < bar.methods().get(i).attributes().size(); j++) {
if (bar.methods[i].attributes.attrs[j] instanceof if (bar.methods().get(i).attributes().get(j) instanceof
MethodParameters_attribute) MethodParametersAttribute)
error("Zero-argument constructor shouldn't have MethodParameters"); error("Zero-argument constructor shouldn't have MethodParameters");
} }
} }

View File

@ -25,14 +25,19 @@
* @test * @test
* @bug 8029800 * @bug 8029800
* @summary String.toLowerCase()/toUpperCase is generally dangerous, check it is not used in langtools * @summary String.toLowerCase()/toUpperCase is generally dangerous, check it is not used in langtools
* @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.io.*; import java.io.*;
import java.util.*; import java.util.*;
import javax.tools.*; import javax.tools.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info; import jdk.internal.classfile.constantpool.*;
public class NoStringToLower { public class NoStringToLower {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
@ -62,7 +67,7 @@ public class NoStringToLower {
"javax.lang.model", "javax.lang.model",
"javax.tools", "javax.tools",
"com.sun.source", "com.sun.source",
"com.sun.tools.classfile", "jdk.internal.classfile",
"com.sun.tools.doclint", "com.sun.tools.doclint",
"com.sun.tools.javac", "com.sun.tools.javac",
"com.sun.tools.javah", "com.sun.tools.javah",
@ -103,11 +108,11 @@ public class NoStringToLower {
*/ */
void scan(JavaFileObject fo) throws IOException { void scan(JavaFileObject fo) throws IOException {
try (InputStream in = fo.openInputStream()) { try (InputStream in = fo.openInputStream()) {
ClassFile cf = ClassFile.read(in); ClassModel cf = Classfile.of().parse(in.readAllBytes());
for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) { ConstantPool cp = cf.constantPool();
if (cpinfo.getTag() == ConstantPool.CONSTANT_Methodref) { for (int i = 1; i < cp.entryCount(); i += cp.entryByIndex(i).width()) {
CONSTANT_Methodref_info ref = (CONSTANT_Methodref_info) cpinfo; if (cp.entryByIndex(i) instanceof MethodRefEntry ref) {
String methodDesc = ref.getClassInfo().getName() + "." + ref.getNameAndTypeInfo().getName() + ":" + ref.getNameAndTypeInfo().getType(); String methodDesc = ref.owner().name().stringValue() + "." + ref.name().stringValue() + ":" + ref.type().stringValue();
if ("java/lang/String.toLowerCase:()Ljava/lang/String;".equals(methodDesc)) { if ("java/lang/String.toLowerCase:()Ljava/lang/String;".equals(methodDesc)) {
error("found reference to String.toLowerCase() in: " + fo.getName()); error("found reference to String.toLowerCase() in: " + fo.getName());

View File

@ -29,13 +29,18 @@
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* 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 ImplicitParameters * @run main ImplicitParameters
*/ */
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPoolException; import jdk.internal.classfile.attribute.MethodParameterInfo;
import com.sun.tools.classfile.MethodParameters_attribute; import jdk.internal.classfile.attribute.MethodParametersAttribute;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Flags;
import toolbox.Assert; import toolbox.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -50,9 +55,10 @@ import java.lang.constant.ConstantDescs;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List;
public class ImplicitParameters extends TestRunner { public class ImplicitParameters extends TestRunner {
private static final int CHECKED_FLAGS = Flags.MANDATED | Flags.SYNTHETIC; private static final int CHECKED_FLAGS = Classfile.ACC_MANDATED | Classfile.ACC_SYNTHETIC;
private static final int NO_FLAGS = 0; private static final int NO_FLAGS = 0;
public ImplicitParameters() { public ImplicitParameters() {
@ -121,11 +127,11 @@ public class ImplicitParameters extends TestRunner {
.writeAll(); .writeAll();
} }
private ClassFile readClassFile(Path classes, Method method) { private ClassModel readClassFile(Path classes, Method method) {
String className = method.getAnnotation(ClassName.class).value(); String className = method.getAnnotation(ClassName.class).value();
try { try {
return ClassFile.read(classes.resolve("Outer$" + className + ".class")); return Classfile.of().parse(classes.resolve("Outer$" + className + ".class"));
} catch (IOException | ConstantPoolException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -137,16 +143,16 @@ public class ImplicitParameters extends TestRunner {
@Test @Test
@ClassName("Inner") @ClassName("Inner")
public void testInnerClassConstructor(ClassFile classFile) { public void testInnerClassConstructor(ClassModel classFile) {
checkParameters(classFile.methods[0], Flags.MANDATED, 0); checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, 0);
} }
@Test @Test
@ClassName("1Task") @ClassName("1Task")
public void testLocalClassConstructor(ClassFile classFile) throws ConstantPoolException { public void testLocalClassConstructor(ClassModel classFile) {
for (com.sun.tools.classfile.Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(ConstantDescs.INIT_NAME)) { if (method.methodName().equalsString(ConstantDescs.INIT_NAME)) {
checkParameters(method, Flags.MANDATED, NO_FLAGS, Flags.SYNTHETIC); checkParameters(method, Classfile.ACC_MANDATED, NO_FLAGS, Classfile.ACC_SYNTHETIC);
break; break;
} }
} }
@ -154,22 +160,22 @@ public class ImplicitParameters extends TestRunner {
@Test @Test
@ClassName("1") @ClassName("1")
public void testAnonymousClassExtendingInnerClassConstructor(ClassFile classFile) { public void testAnonymousClassExtendingInnerClassConstructor(ClassModel classFile) {
checkParameters(classFile.methods[0], Flags.MANDATED, NO_FLAGS, NO_FLAGS); checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, NO_FLAGS, NO_FLAGS);
} }
@Test @Test
@ClassName("2") @ClassName("2")
public void testAnonymousClassConstructor(ClassFile classFile) { public void testAnonymousClassConstructor(ClassModel classFile) {
checkParameters(classFile.methods[0], Flags.MANDATED); checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED);
} }
@Test @Test
@ClassName("MyEnum") @ClassName("MyEnum")
public void testValueOfInEnum(ClassFile classFile) throws ConstantPoolException { public void testValueOfInEnum(ClassModel classFile) {
for (com.sun.tools.classfile.Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals("valueOf")) { if (method.methodName().equalsString("valueOf")) {
checkParameters(method, Flags.MANDATED); checkParameters(method, Classfile.ACC_MANDATED);
break; break;
} }
} }
@ -177,10 +183,10 @@ public class ImplicitParameters extends TestRunner {
@Test @Test
@ClassName("MyEnum") @ClassName("MyEnum")
public void testEnumClassConstructor(ClassFile classFile) throws ConstantPoolException { public void testEnumClassConstructor(ClassModel classFile) {
for (com.sun.tools.classfile.Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(ConstantDescs.INIT_NAME)) { if (method.methodName().equalsString(ConstantDescs.INIT_NAME)) {
checkParameters(method, Flags.SYNTHETIC, Flags.SYNTHETIC, NO_FLAGS, NO_FLAGS); checkParameters(method, Classfile.ACC_SYNTHETIC, Classfile.ACC_SYNTHETIC, NO_FLAGS, NO_FLAGS);
break; break;
} }
} }
@ -188,18 +194,18 @@ public class ImplicitParameters extends TestRunner {
@Test @Test
@ClassName("MyRecord") @ClassName("MyRecord")
public void testCompactConstructor(ClassFile classFile) { public void testCompactConstructor(ClassModel classFile) {
checkParameters(classFile.methods[0], Flags.MANDATED, Flags.MANDATED); checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, Classfile.ACC_MANDATED);
} }
private void checkParameters(com.sun.tools.classfile.Method method, int... parametersFlags) { private void checkParameters(MethodModel method, int... parametersFlags) {
MethodParameters_attribute methodParameters = (MethodParameters_attribute) method.attributes.get("MethodParameters"); MethodParametersAttribute methodParameters = method.findAttribute(Attributes.METHOD_PARAMETERS).orElseThrow();
Assert.checkNonNull(methodParameters, "MethodParameters attribute must be present"); Assert.checkNonNull(methodParameters, "MethodParameters attribute must be present");
MethodParameters_attribute.Entry[] table = methodParameters.method_parameter_table; List<MethodParameterInfo> table = methodParameters.parameters();
Assert.check(table.length == parametersFlags.length, () -> "Expected " + parametersFlags.length Assert.check(table.size() == parametersFlags.length, () -> "Expected " + parametersFlags.length
+ " MethodParameters entries, found " + table.length); + " MethodParameters entries, found " + table.size());
for (int i = 0; i < methodParameters.method_parameter_table_length; i++) { for (int i = 0; i < methodParameters.parameters().size(); i++) {
int foundFlags = table[i].flags & CHECKED_FLAGS; int foundFlags = table.get(i).flagsMask() & CHECKED_FLAGS;
int desiredFlags = parametersFlags[i] & CHECKED_FLAGS; int desiredFlags = parametersFlags[i] & CHECKED_FLAGS;
Assert.check(foundFlags == desiredFlags, () -> "Expected mandated and synthethic flags to be " Assert.check(foundFlags == desiredFlags, () -> "Expected mandated and synthethic flags to be "
+ convertFlags(desiredFlags) + ", found " + convertFlags(foundFlags)); + convertFlags(desiredFlags) + ", found " + convertFlags(foundFlags));
@ -207,6 +213,6 @@ public class ImplicitParameters extends TestRunner {
} }
private static String convertFlags(int flags) { private static String convertFlags(int flags) {
return ((flags & Flags.MANDATED) == Flags.MANDATED) + " and " + ((flags & Flags.SYNTHETIC) == Flags.SYNTHETIC); return ((flags & Classfile.ACC_MANDATED) == Classfile.ACC_MANDATED) + " and " + ((flags & Classfile.ACC_SYNTHETIC) == Classfile.ACC_SYNTHETIC);
} }
} }

View File

@ -21,10 +21,11 @@
* questions. * questions.
*/ */
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.BootstrapMethods_attribute.BootstrapMethodSpecifier; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info; import jdk.internal.classfile.constantpool.InvokeDynamicEntry;
import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info; import jdk.internal.classfile.constantpool.MethodHandleEntry;
import jdk.internal.classfile.instruction.InvokeDynamicInstruction;
import java.io.File; import java.io.File;
@ -32,7 +33,12 @@ import java.io.File;
* @test * @test
* @bug 8148483 8151516 8151223 * @bug 8148483 8151516 8151223
* @summary Test that StringConcat is working for JDK >= 9 * @summary Test that StringConcat is working for JDK >= 9
* @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
* *
* @clean * * @clean *
* @compile -source 8 -target 8 TestIndyStringConcat.java * @compile -source 8 -target 8 TestIndyStringConcat.java
@ -59,7 +65,7 @@ public class TestIndyStringConcat {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
boolean expected = Boolean.valueOf(args[0]); boolean expected = Boolean.parseBoolean(args[0]);
boolean actual = hasStringConcatFactoryCall("test"); boolean actual = hasStringConcatFactoryCall("test");
if (expected != actual) { if (expected != actual) {
throw new AssertionError("expected = " + expected + ", actual = " + actual); throw new AssertionError("expected = " + expected + ", actual = " + actual);
@ -67,30 +73,18 @@ public class TestIndyStringConcat {
} }
public static boolean hasStringConcatFactoryCall(String methodName) throws Exception { public static boolean hasStringConcatFactoryCall(String methodName) throws Exception {
ClassFile classFile = ClassFile.read(new File(System.getProperty("test.classes", "."), ClassModel classFile = Classfile.of().parse(new File(System.getProperty("test.classes", "."),
TestIndyStringConcat.class.getName() + ".class")); TestIndyStringConcat.class.getName() + ".class").toPath());
ConstantPool constantPool = classFile.constant_pool;
BootstrapMethods_attribute bsm_attr = for (MethodModel method : classFile.methods()) {
(BootstrapMethods_attribute)classFile if (method.methodName().equalsString(methodName)) {
.getAttribute(Attribute.BootstrapMethods); CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
for (CodeElement i : code.elementList()) {
for (Method method : classFile.methods) { if (i instanceof InvokeDynamicInstruction) {
if (method.getName(constantPool).equals(methodName)) { InvokeDynamicInstruction indy = (InvokeDynamicInstruction) i;
Code_attribute code = (Code_attribute) method.attributes BootstrapMethodEntry bsmSpec = indy.invokedynamic().bootstrap();
.get(Attribute.Code); MethodHandleEntry bsmInfo = bsmSpec.bootstrapMethod();
for (Instruction i : code.getInstructions()) { if (bsmInfo.reference().owner().asInternalName().equals("java/lang/invoke/StringConcatFactory")) {
if (i.getOpcode() == Opcode.INVOKEDYNAMIC) {
CONSTANT_InvokeDynamic_info indyInfo =
(CONSTANT_InvokeDynamic_info) constantPool.get(i.getUnsignedShort(1));
BootstrapMethodSpecifier bsmSpec =
bsm_attr.bootstrap_method_specifiers[indyInfo.bootstrap_method_attr_index];
CONSTANT_MethodHandle_info bsmInfo =
(CONSTANT_MethodHandle_info) constantPool.get(bsmSpec.bootstrap_method_ref);
if (bsmInfo.getCPRefInfo().getClassName().equals("java/lang/invoke/StringConcatFactory")) {
return true; return true;
} }
} }

View File

@ -21,8 +21,10 @@
* questions. * questions.
*/ */
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.*; import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.constantpool.NameAndTypeEntry;
import jdk.internal.classfile.instruction.InvokeDynamicInstruction;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -32,7 +34,12 @@ import java.util.List;
* @test * @test
* @bug 8273914 * @bug 8273914
* @summary Indy string concat changes order of operations * @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
* java.base/jdk.internal.classfile.impl
* *
* @clean * * @clean *
* @compile -XDstringConcat=indy WellKnownTypeSignatures.java * @compile -XDstringConcat=indy WellKnownTypeSignatures.java
@ -94,23 +101,19 @@ public class WellKnownTypeSignatures {
public static void readIndyTypes() throws Exception { public static void readIndyTypes() throws Exception {
actualTypes = new ArrayList<String>(); actualTypes = new ArrayList<String>();
ClassFile classFile = ClassModel classFile = Classfile.of().parse(
ClassFile.read(
new File( new File(
System.getProperty("test.classes", "."), System.getProperty("test.classes", "."),
WellKnownTypeSignatures.class.getName() + ".class")); WellKnownTypeSignatures.class.getName() + ".class").toPath());
ConstantPool constantPool = classFile.constant_pool;
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(constantPool).equals("main")) { if (method.methodName().equalsString("main")) {
Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction i : code.getInstructions()) { for (CodeElement i : code.elementList()) {
if (i.getOpcode() == Opcode.INVOKEDYNAMIC) { if (i instanceof InvokeDynamicInstruction) {
CONSTANT_InvokeDynamic_info indyInfo = InvokeDynamicInstruction indy = (InvokeDynamicInstruction) i;
(CONSTANT_InvokeDynamic_info) NameAndTypeEntry natInfo = indy.invokedynamic().nameAndType();
constantPool.get(i.getUnsignedShort(1)); actualTypes.add(natInfo.type().stringValue());
CONSTANT_NameAndType_info natInfo = indyInfo.getNameAndTypeInfo();
actualTypes.add(natInfo.getType());
} }
} }
} }

View File

@ -21,8 +21,10 @@
* questions. * questions.
*/ */
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.*; import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.constantpool.*;
import jdk.internal.classfile.instruction.InvokeDynamicInstruction;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -32,7 +34,11 @@ import java.util.List;
* @test * @test
* @bug 8151223 * @bug 8151223
* @summary String concatenation fails with implicit toString() on package-private class * @summary String concatenation fails with implicit toString() on package-private 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
* *
* @clean * * @clean *
* @compile -XDstringConcat=indy Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java * @compile -XDstringConcat=indy Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java
@ -175,19 +181,17 @@ public class Test {
public static void readIndyTypes() throws Exception { public static void readIndyTypes() throws Exception {
actualTypes = new ArrayList<String>(); actualTypes = new ArrayList<String>();
ClassFile classFile = ClassFile.read(new File(System.getProperty("test.classes", "."), ClassModel classFile = Classfile.of().parse(new File(System.getProperty("test.classes", "."),
Test.class.getName() + ".class")); Test.class.getName() + ".class").toPath());
ConstantPool constantPool = classFile.constant_pool;
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(constantPool).equals("main")) { if (method.methodName().equalsString("main")) {
Code_attribute code = (Code_attribute) method.attributes CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
.get(Attribute.Code); for (CodeElement i : code.elementList()) {
for (Instruction i : code.getInstructions()) { if (i instanceof InvokeDynamicInstruction) {
if (i.getOpcode() == Opcode.INVOKEDYNAMIC) { InvokeDynamicEntry indyInfo = ((InvokeDynamicInstruction) i).invokedynamic();
CONSTANT_InvokeDynamic_info indyInfo = (CONSTANT_InvokeDynamic_info) constantPool.get(i.getUnsignedShort(1)); NameAndTypeEntry natInfo = indyInfo.nameAndType();
CONSTANT_NameAndType_info natInfo = indyInfo.getNameAndTypeInfo(); actualTypes.add(natInfo.type().stringValue());
actualTypes.add(natInfo.getType());
} }
} }
} }

View File

@ -26,7 +26,12 @@
* @bug 6695379 * @bug 6695379
* @summary Copy method annotations and parameter annotations to synthetic * @summary Copy method annotations and parameter annotations to synthetic
* bridge methods * bridge methods
* @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.util * jdk.compiler/com.sun.tools.javac.util
* @run main AnnotationsAreNotCopiedToBridgeMethodsTest * @run main AnnotationsAreNotCopiedToBridgeMethodsTest
*/ */
@ -40,11 +45,8 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.AccessFlags; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
public class AnnotationsAreNotCopiedToBridgeMethodsTest { public class AnnotationsAreNotCopiedToBridgeMethodsTest {
@ -61,25 +63,18 @@ public class AnnotationsAreNotCopiedToBridgeMethodsTest {
"$CovariantReturnType$VisibilityChange.class")); "$CovariantReturnType$VisibilityChange.class"));
} }
void checkClassFile(final Path cfilePath) throws Exception { <A extends Attribute<A>> void checkClassFile(final Path cfilePath) throws Exception {
ClassFile classFile = ClassFile.read( ClassModel classFile = Classfile.of().parse(cfilePath);
new BufferedInputStream(Files.newInputStream(cfilePath))); for (MethodModel method : classFile.methods()) {
for (Method method : classFile.methods) { if ((method.flags().flagsMask() & Classfile.ACC_BRIDGE) != 0) {
if (method.access_flags.is(AccessFlags.ACC_BRIDGE)) { Assert.checkNonNull(method.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS),
checkForAttr(method.attributes, "Annotations hasn't been copied to bridge method");
"Annotations hasn't been copied to bridge method", Assert.checkNonNull(method.findAttribute(Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS),
Attribute.RuntimeVisibleAnnotations, "Annotations hasn't been copied to bridge method");
Attribute.RuntimeVisibleParameterAnnotations);
} }
} }
} }
void checkForAttr(Attributes attrs, String errorMsg, String... attrNames) {
for (String attrName : attrNames) {
Assert.checkNonNull(attrs.get(attrName), errorMsg);
}
}
@Target(value = {ElementType.PARAMETER}) @Target(value = {ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@interface ParamAnnotation {} @interface ParamAnnotation {}

View File

@ -26,7 +26,12 @@
* @bug 6970173 * @bug 6970173
* @summary Debug pointer at bad position * @summary Debug pointer at bad position
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
@ -38,10 +43,8 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -90,22 +93,21 @@ public class DebugPointerAtBadPositionTest {
} }
void checkClassFile(final File cfile, String methodToFind) throws Exception { void checkClassFile(final File cfile, String methodToFind) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
boolean methodFound = false; boolean methodFound = false;
for (Method method : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(methodToFind)) { if (m.methodName().equalsString(methodToFind)) {
methodFound = true; methodFound = true;
Code_attribute code = (Code_attribute) method.attributes.get("Code"); CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTable_attribute lnt = LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
(LineNumberTable_attribute) code.attributes.get("LineNumberTable"); Assert.check(lnt.lineNumbers().size() == expectedLNT.length,
Assert.check(lnt.line_number_table_length == expectedLNT.length,
foundLNTLengthDifferentThanExpMsg); foundLNTLengthDifferentThanExpMsg);
int i = 0; int i = 0;
for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) { for (LineNumberInfo entry: lnt.lineNumbers()) {
Assert.check(entry.line_number == expectedLNT[i][0] && Assert.check(entry.lineNumber() == expectedLNT[i][0] &&
entry.start_pc == expectedLNT[i][1], entry.startPc() == expectedLNT[i][1],
"LNT entry at pos " + i + " differ from expected." + "LNT entry at pos " + i + " differ from expected." +
"Found " + entry.line_number + ":" + entry.start_pc + "Found " + entry.lineNumber() + ":" + entry.startPc() +
". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]); ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
i++; i++;
} }

View File

@ -26,7 +26,12 @@
* @bug 7008643 * @bug 7008643
* @summary inlined finally clauses confuse debuggers * @summary inlined finally clauses confuse debuggers
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
@ -38,10 +43,8 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -97,22 +100,21 @@ public class InlinedFinallyConfuseDebuggersTest {
} }
void checkClassFile(final File cfile, String methodToFind) throws Exception { void checkClassFile(final File cfile, String methodToFind) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
boolean methodFound = false; boolean methodFound = false;
for (Method method : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(methodToFind)) { if (m.methodName().equalsString(methodToFind)) {
methodFound = true; methodFound = true;
Code_attribute code = (Code_attribute) method.attributes.get("Code"); CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTable_attribute lnt = LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
(LineNumberTable_attribute) code.attributes.get("LineNumberTable"); Assert.check(lnt.lineNumbers().size() == expectedLNT.length,
Assert.check(lnt.line_number_table_length == expectedLNT.length,
"The LineNumberTable found has a length different to the expected one"); "The LineNumberTable found has a length different to the expected one");
int i = 0; int i = 0;
for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) { for (LineNumberInfo entry: lnt.lineNumbers()) {
Assert.check(entry.line_number == expectedLNT[i][0] && Assert.check(entry.lineNumber() == expectedLNT[i][0] &&
entry.start_pc == expectedLNT[i][1], entry.startPc() == expectedLNT[i][1],
"LNT entry at pos " + i + " differ from expected." + "LNT entry at pos " + i + " differ from expected." +
"Found " + entry.line_number + ":" + entry.start_pc + "Found " + entry.lineNumber() + ":" + entry.startPc() +
". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]); ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
i++; i++;
} }

View File

@ -25,14 +25,23 @@
* @test * @test
* @bug 8015499 * @bug 8015499
* @summary javac, Gen is generating extra checkcast instructions in some corner cases * @summary javac, Gen is generating extra checkcast instructions in some corner cases
* @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.util * jdk.compiler/com.sun.tools.javac.util
* @run main DoubleCastTest * @run main DoubleCastTest
*/ */
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import com.sun.tools.classfile.*; import java.util.Objects;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.instruction.TypeCheckInstruction;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
public class DoubleCastTest { public class DoubleCastTest {
@ -55,22 +64,23 @@ public class DoubleCastTest {
public static void main(String... cmdline) throws Exception { public static void main(String... cmdline) throws Exception {
ClassFile cls = ClassFile.read(DoubleCastTest.class.getResourceAsStream("DoubleCastTest$C.class")); ClassModel cls = Classfile.of().parse(Objects.requireNonNull(DoubleCastTest.class.getResourceAsStream("DoubleCastTest$C.class")).readAllBytes());
for (Method m: cls.methods) for (MethodModel m: cls.methods())
check(m); check(m);
} }
static void check(Method m) throws Exception { static void check(MethodModel m) throws Exception {
boolean last_is_cast = false; boolean last_is_cast = false;
int last_ref = 0; ClassEntry last_ref = null;
Code_attribute ea = (Code_attribute)m.attributes.get(Attribute.Code); CodeAttribute ea = m.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction i : ea.getInstructions()) { for (int i = 0; i < ea.elementList().size(); ++i) {
if (i.getOpcode() == Opcode.CHECKCAST) { CodeElement ce = ea.elementList().get(i);
if (ce instanceof TypeCheckInstruction ins && ins.opcode() == Opcode.CHECKCAST) {
Assert.check Assert.check
(!(last_is_cast && last_ref == i.getUnsignedShort(1)), (!(last_is_cast && last_ref == ins.type()),
"Double cast found - Test failed"); "Double cast found - Test failed");
last_is_cast = true; last_is_cast = true;
last_ref = i.getUnsignedShort(1); last_ref = ins.type();
} else { } else {
last_is_cast = false; last_is_cast = false;
} }

View File

@ -27,7 +27,12 @@
* @summary Redundant entry in bytecode exception table * @summary Redundant entry in bytecode exception table
* temporarily workaround combo tests are causing time out in several platforms * temporarily workaround combo tests are causing time out in several platforms
* @library /tools/javac/lib * @library /tools/javac/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.api
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
@ -38,11 +43,9 @@
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.constantpool.ClassEntry;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -149,15 +152,15 @@ public class T7093325 extends ComboInstance<T7093325> {
} }
try (InputStream is = result.get().iterator().next().openInputStream()) { try (InputStream is = result.get().iterator().next().openInputStream()) {
ClassFile cf = ClassFile.read(is); ClassModel cf = Classfile.of().parse(is.readAllBytes());
if (cf == null) { if (cf == null) {
fail("Classfile not found: " + result.compilationInfo()); fail("Classfile not found: " + result.compilationInfo());
return; return;
} }
Method test_method = null; MethodModel test_method = null;
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
if (m.getName(cf.constant_pool).equals("test")) { if (m.methodName().equalsString("test")) {
test_method = m; test_method = m;
break; break;
} }
@ -168,13 +171,7 @@ public class T7093325 extends ComboInstance<T7093325> {
return; return;
} }
Code_attribute code = null; CodeAttribute code = test_method.findAttribute(Attributes.CODE).orElse(null);
for (Attribute a : test_method.attributes) {
if (a.getName(cf.constant_pool).equals(Attribute.Code)) {
code = (Code_attribute)a;
break;
}
}
if (code == null) { if (code == null) {
fail("Code attribute not found in method test()"); fail("Code attribute not found in method test()");
@ -182,9 +179,9 @@ public class T7093325 extends ComboInstance<T7093325> {
} }
int actualGapsCount = 0; int actualGapsCount = 0;
for (int i = 0; i < code.exception_table_length ; i++) { for (int i = 0; i < code.exceptionHandlers().size() ; i++) {
int catchType = code.exception_table[i].catch_type; ClassEntry catchType = code.exceptionHandlers().get(i).catchType().orElse(null);
if (catchType == 0) { //any if (catchType == null) { //any
actualGapsCount++; actualGapsCount++;
} }
} }
@ -194,9 +191,8 @@ public class T7093325 extends ComboInstance<T7093325> {
"expected gaps: " + gapsCount + "\n" + "expected gaps: " + gapsCount + "\n" +
"found gaps: " + actualGapsCount + "\n" + "found gaps: " + actualGapsCount + "\n" +
result.compilationInfo()); result.compilationInfo());
return;
} }
} catch (IOException | ConstantPoolException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
fail("error reading classfile: " + e); fail("error reading classfile: " + e);
} }

View File

@ -25,11 +25,17 @@
* @test * @test
* @bug 8003967 * @bug 8003967
* @summary detect and remove all mutable implicit static enum fields in langtools * @summary detect and remove all mutable implicit static enum fields in langtools
* @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.util * jdk.compiler/com.sun.tools.javac.util
* @run main DetectMutableStaticFields * @run main DetectMutableStaticFields
*/ */
import jdk.internal.classfile.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -50,17 +56,9 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Field;
import static javax.tools.JavaFileObject.Kind.CLASS; import static javax.tools.JavaFileObject.Kind.CLASS;
import static com.sun.tools.classfile.AccessFlags.ACC_ENUM;
import static com.sun.tools.classfile.AccessFlags.ACC_FINAL;
import static com.sun.tools.classfile.AccessFlags.ACC_STATIC;
public class DetectMutableStaticFields { public class DetectMutableStaticFields {
@ -75,7 +73,12 @@ public class DetectMutableStaticFields {
"javax.tools", "javax.tools",
"javax.lang.model", "javax.lang.model",
"com.sun.source", "com.sun.source",
"com.sun.tools.classfile", "jdk.internal.classfile",
"jdk.internal.classfile.attribute",
"jdk.internal.classfile.constantpool",
"jdk.internal.classfile.instruction",
"jdk.internal.classfile.components",
"jdk.internal.classfile.impl",
"com.sun.tools.javac", "com.sun.tools.javac",
"com.sun.tools.javah", "com.sun.tools.javah",
"com.sun.tools.javap", "com.sun.tools.javap",
@ -90,7 +93,6 @@ public class DetectMutableStaticFields {
static { static {
ignore("javax/tools/ToolProvider", "instance"); ignore("javax/tools/ToolProvider", "instance");
ignore("com/sun/tools/javah/JavahTask", "versionRB"); ignore("com/sun/tools/javah/JavahTask", "versionRB");
ignore("com/sun/tools/classfile/Dependencies$DefaultFilter", "instance");
ignore("com/sun/tools/javap/JavapTask", "versionRB"); ignore("com/sun/tools/javap/JavapTask", "versionRB");
ignore("com/sun/tools/doclets/formats/html/HtmlDoclet", "docletToStart"); ignore("com/sun/tools/doclets/formats/html/HtmlDoclet", "docletToStart");
ignore("com/sun/tools/javac/util/JCDiagnostic", "fragmentFormatter"); ignore("com/sun/tools/javac/util/JCDiagnostic", "fragmentFormatter");
@ -132,12 +134,7 @@ public class DetectMutableStaticFields {
} }
} }
private void run() private void run() throws IOException {
throws
IOException,
ConstantPoolException,
InvalidDescriptor,
URISyntaxException {
JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) { try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
@ -164,11 +161,7 @@ public class DetectMutableStaticFields {
return false; return false;
} }
void analyzeModule(StandardJavaFileManager fm, String moduleName) void analyzeModule(StandardJavaFileManager fm, String moduleName) throws IOException {
throws
IOException,
ConstantPoolException,
InvalidDescriptor {
JavaFileManager.Location location = JavaFileManager.Location location =
fm.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName); fm.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName);
if (location == null) if (location == null)
@ -179,9 +172,9 @@ public class DetectMutableStaticFields {
int index = className.lastIndexOf('.'); int index = className.lastIndexOf('.');
String pckName = index == -1 ? "" : className.substring(0, index); String pckName = index == -1 ? "" : className.substring(0, index);
if (shouldAnalyzePackage(pckName)) { if (shouldAnalyzePackage(pckName)) {
ClassFile classFile; ClassModel classFile;
try (InputStream input = file.openInputStream()) { try (InputStream input = file.openInputStream()) {
classFile = ClassFile.read(input); classFile = Classfile.of().parse(input.readAllBytes());
} }
analyzeClassFile(classFile); analyzeClassFile(classFile);
} }
@ -201,33 +194,29 @@ public class DetectMutableStaticFields {
return false; return false;
} }
void analyzeClassFile(ClassFile classFileToCheck) void analyzeClassFile(ClassModel classFileToCheck) {
throws
IOException,
ConstantPoolException,
Descriptor.InvalidDescriptor {
boolean enumClass = boolean enumClass =
(classFileToCheck.access_flags.flags & ACC_ENUM) != 0; (classFileToCheck.flags().flagsMask() & Classfile.ACC_ENUM) != 0;
boolean nonFinalStaticEnumField; boolean nonFinalStaticEnumField;
boolean nonFinalStaticField; boolean nonFinalStaticField;
currentFieldsToIgnore = currentFieldsToIgnore =
classFieldsToIgnoreMap.get(classFileToCheck.getName()); classFieldsToIgnoreMap.get(classFileToCheck.thisClass().asInternalName());
for (Field field : classFileToCheck.fields) { for (FieldModel field : classFileToCheck.fields()) {
if (ignoreField(field.getName(classFileToCheck.constant_pool))) { if (ignoreField(field.fieldName().stringValue())) {
continue; continue;
} }
nonFinalStaticEnumField = nonFinalStaticEnumField =
(field.access_flags.flags & (ACC_ENUM | ACC_FINAL)) == 0; (field.flags().flagsMask() & (Classfile.ACC_ENUM | Classfile.ACC_FINAL)) == 0;
nonFinalStaticField = nonFinalStaticField =
(field.access_flags.flags & ACC_STATIC) != 0 && (field.flags().flagsMask() & Classfile.ACC_STATIC) != 0 &&
(field.access_flags.flags & ACC_FINAL) == 0; (field.flags().flagsMask() & Classfile.ACC_FINAL) == 0;
if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) { if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
errors.add("There is a mutable field named " + errors.add("There is a mutable field named " +
field.getName(classFileToCheck.constant_pool) + field.fieldName().stringValue() +
", at class " + ", at class " +
classFileToCheck.getName()); classFileToCheck.thisClass().asInternalName());
} }
} }
} }

View File

@ -26,7 +26,12 @@
* @bug 8010737 * @bug 8010737
* @summary javac, known parameter's names should be copied to automatically * @summary javac, known parameter's names should be copied to automatically
* generated constructors for inner classes * generated constructors for 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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.tree
@ -51,8 +56,6 @@ import com.sun.source.tree.Tree;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener; import com.sun.source.util.TaskListener;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
@ -63,6 +66,7 @@ import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import jdk.internal.classfile.*;
public class ParameterNamesAreNotCopiedToAnonymousInitTest { public class ParameterNamesAreNotCopiedToAnonymousInitTest {
@ -112,10 +116,10 @@ public class ParameterNamesAreNotCopiedToAnonymousInitTest {
} }
void checkClassFile(final File cfile, int numberOfParams) throws Exception { void checkClassFile(final File cfile, int numberOfParams) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
boolean methodFound = false; boolean methodFound = false;
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals("<init>")) { if (method.methodName().equalsString("<init>")) {
methodFound = true; methodFound = true;
} }
} }
@ -143,8 +147,12 @@ public class ParameterNamesAreNotCopiedToAnonymousInitTest {
Arrays.asList(new File(System.getProperty("test.src"), Arrays.asList(new File(System.getProperty("test.src"),
this.getClass().getName() + ".java"))); this.getClass().getName() + ".java")));
java.util.List<String> options = Arrays.asList( java.util.List<String> options = Arrays.asList(
"--add-modules", "jdk.jdeps", "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED",
"--add-exports", "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED",
"--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED",
"--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED",
"--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED",
"--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",

View File

@ -29,7 +29,12 @@
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * 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 * @build toolbox.ToolBox toolbox.JavacTask
* @run main WrongLNTForLambdaTest * @run main WrongLNTForLambdaTest
*/ */
@ -37,12 +42,10 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.ToolBox; import toolbox.ToolBox;
@ -159,22 +162,21 @@ public class WrongLNTForLambdaTest {
} }
void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception { void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
boolean methodFound = false; boolean methodFound = false;
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(methodToFind)) { if (method.methodName().equalsString(methodToFind)) {
methodFound = true; methodFound = true;
Code_attribute code = (Code_attribute) method.attributes.get("Code"); CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTable_attribute lnt = LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
(LineNumberTable_attribute) code.attributes.get("LineNumberTable"); Assert.check(lnt.lineNumbers().size() == expectedLNT.length,
Assert.check(lnt.line_number_table_length == expectedLNT.length,
"The LineNumberTable found has a length different to the expected one"); "The LineNumberTable found has a length different to the expected one");
int i = 0; int i = 0;
for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) { for (LineNumberInfo entry: lnt.lineNumbers()) {
Assert.check(entry.line_number == expectedLNT[i][0] && Assert.check(entry.lineNumber() == expectedLNT[i][0] &&
entry.start_pc == expectedLNT[i][1], entry.startPc() == expectedLNT[i][1],
"LNT entry at pos " + i + " differ from expected." + "LNT entry at pos " + i + " differ from expected." +
"Found " + entry.line_number + ":" + entry.start_pc + "Found " + entry.lineNumber() + ":" + entry.startPc() +
". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]); ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
i++; i++;
} }

View File

@ -25,21 +25,19 @@
* @test * @test
* @bug 8022186 8271254 * @bug 8022186 8271254
* @summary javac generates dead code if a try with an empty body has a finalizer * @summary javac generates dead code if a try with an empty body has a finalizer
* @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.util * jdk.compiler/com.sun.tools.javac.util
*/ */
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.ConstantPool; import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
import com.sun.tools.classfile.ConstantPool.InvalidIndex;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Instruction.KindVisitor;
import com.sun.tools.classfile.Instruction.TypeKind;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.nio.file.Files; import java.nio.file.Files;
@ -65,97 +63,27 @@ public class DeadCodeGeneratedForEmptyTryTest {
void checkClassFile(final Path path) throws Exception { void checkClassFile(final Path path) throws Exception {
numberOfRefToStr = 0; numberOfRefToStr = 0;
ClassFile classFile = ClassFile.read( ClassModel classFile = Classfile.of().parse(
new BufferedInputStream(Files.newInputStream(path))); new BufferedInputStream(Files.newInputStream(path)).readAllBytes());
constantPool = classFile.constant_pool; constantPool = classFile.constantPool();
utf8Index = constantPool.getUTF8Index("STR_TO_LOOK_FOR"); for (MethodModel method: classFile.methods()) {
for (Method method: classFile.methods) { if (method.methodName().equalsString("methodToLookFor")) {
if (method.getName(constantPool).equals("methodToLookFor")) { CodeAttribute codeAtt = method.findAttribute(Attributes.CODE).orElseThrow();
Code_attribute codeAtt = (Code_attribute)method.attributes.get(Attribute.Code); codeAtt.elementList().stream()
for (Instruction inst: codeAtt.getInstructions()) { .filter(ce -> ce instanceof Instruction)
inst.accept(codeVisitor, null); .forEach(ins -> checkIndirectRefToString((Instruction) ins));
}
} }
} }
Assert.check(numberOfRefToStr == 1, Assert.check(numberOfRefToStr == 1,
"There should only be one reference to a CONSTANT_String_info structure in the generated code"); "There should only be one reference to a CONSTANT_String_info structure in the generated code");
} }
void checkIndirectRefToString(Instruction instruction) {
CodeVisitor codeVisitor = new CodeVisitor(); if (instruction instanceof InvokeInstruction invokeInstruction) {
MemberRefEntry refEntry = invokeInstruction.method();
class CodeVisitor implements KindVisitor<Void, Void> { if (constantPool.entryByIndex(refEntry.type().index()) instanceof Utf8Entry) {
void checkIndirectRefToString(int cp_index) {
try {
CPInfo cInfo = constantPool.get(cp_index);
if (cInfo instanceof CONSTANT_String_info) {
CONSTANT_String_info strInfo = (CONSTANT_String_info)cInfo;
if (strInfo.string_index == utf8Index) {
numberOfRefToStr++; numberOfRefToStr++;
} }
} }
} catch (InvalidIndex ex) {
throw new AssertionError("invalid constant pool index at " + cp_index);
}
}
@Override
public Void visitNoOperands(Instruction instr, Void p) {
return null;
}
@Override
public Void visitArrayType(Instruction instr, TypeKind kind, Void p) {
return null;
}
@Override
public Void visitBranch(Instruction instr, int offset, Void p) {
return null;
}
@Override
public Void visitConstantPoolRef(Instruction instr, int index, Void p) {
checkIndirectRefToString(index);
return null;
}
@Override
public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) {
checkIndirectRefToString(index);
return null;
}
@Override
public Void visitLocal(Instruction instr, int index, Void p) {
return null;
}
@Override
public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) {
return null;
}
@Override
public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Void p) {
return null;
}
@Override
public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Void p) {
return null;
}
@Override
public Void visitValue(Instruction instr, int value, Void p) {
return null;
}
@Override
public Void visitUnknown(Instruction instr, Void p) {
return null;
}
} }
public class Test1 { public class Test1 {

View File

@ -29,7 +29,12 @@
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * 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 * @build toolbox.ToolBox toolbox.JavacTask
* @run main NoDeadCodeGenerationOnTrySmtTest * @run main NoDeadCodeGenerationOnTrySmtTest
*/ */
@ -37,12 +42,11 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.Code_attribute.Exception_data;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.instruction.ExceptionCatch;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.ToolBox; import toolbox.ToolBox;
@ -100,21 +104,21 @@ public class NoDeadCodeGenerationOnTrySmtTest {
} }
void checkClassFile(final File cfile, String[] methodsToFind) throws Exception { void checkClassFile(final File cfile, String[] methodsToFind) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
int numberOfmethodsFound = 0; int numberOfmethodsFound = 0;
for (String methodToFind : methodsToFind) { for (String methodToFind : methodsToFind) {
for (Method method : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (method.getName(classFile.constant_pool).equals(methodToFind)) { if (m.methodName().equalsString(methodToFind)) {
numberOfmethodsFound++; numberOfmethodsFound++;
Code_attribute code = (Code_attribute) method.attributes.get("Code"); CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow();
Assert.check(code.exception_table_length == expectedExceptionTable.length, Assert.check(code.exceptionHandlers().size() == expectedExceptionTable.length,
"The ExceptionTable found has a length different to the expected one"); "The ExceptionTable found has a length different to the expected one");
int i = 0; int i = 0;
for (Exception_data entry: code.exception_table) { for (ExceptionCatch entry: code.exceptionHandlers()) {
Assert.check(entry.start_pc == expectedExceptionTable[i][0] && Assert.check(code.labelToBci(entry.tryStart()) == expectedExceptionTable[i][0] &&
entry.end_pc == expectedExceptionTable[i][1] && code.labelToBci(entry.tryEnd()) == expectedExceptionTable[i][1] &&
entry.handler_pc == expectedExceptionTable[i][2] && code.labelToBci(entry.handler()) == expectedExceptionTable[i][2] &&
entry.catch_type == expectedExceptionTable[i][3], (entry.catchType().isPresent()? entry.catchType().get().index(): 0)== expectedExceptionTable[i][3],
"Exception table entry at pos " + i + " differ from expected."); "Exception table entry at pos " + i + " differ from expected.");
i++; i++;
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8180141 * @bug 8180141
* @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally * @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally
* @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.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.comp
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
@ -42,7 +47,6 @@ import java.net.URI;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import com.sun.tools.classfile.*;
import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
@ -52,6 +56,8 @@ import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import static com.sun.tools.javac.util.List.of; import static com.sun.tools.javac.util.List.of;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
@ -87,19 +93,19 @@ public class MissingLNTEntryForBreakContinueTest {
} }
File testClasses = new File("."); File testClasses = new File(".");
File file = new File(testClasses, "Test" + id + ".class"); File file = new File(testClasses, "Test" + id + ".class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
for (Method m : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (classFile.constant_pool.getUTF8Value(m.name_index).equals("foo")) { if (m.methodName().equalsString("foo")) {
Code_attribute code = (Code_attribute)m.attributes.get(Attribute.Code); CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTable_attribute lnt = (LineNumberTable_attribute)code.attributes.get(Attribute.LineNumberTable); LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
checkLNT(lnt, MyAttr.lineNumber); checkLNT(lnt, MyAttr.lineNumber);
} }
} }
} }
void checkLNT(LineNumberTable_attribute lnt, int lineToCheckFor) { void checkLNT(LineNumberTableAttribute lnt, int lineToCheckFor) {
for (LineNumberTable_attribute.Entry e: lnt.line_number_table) { for (LineNumberInfo e: lnt.lineNumbers()) {
if (e.line_number == lineToCheckFor) { if (e.lineNumber() == lineToCheckFor) {
return; return;
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8180141 * @bug 8180141
* @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally * @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally
* @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.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.comp
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
@ -42,7 +47,6 @@ import java.net.URI;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import com.sun.tools.classfile.*;
import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
@ -53,6 +57,8 @@ import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import static com.sun.tools.javac.util.List.of; import static com.sun.tools.javac.util.List.of;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
@ -83,19 +89,19 @@ public class MissingLNTEntryForFinalizerTest {
} }
File testClasses = new File("."); File testClasses = new File(".");
File file = new File(testClasses, "Test1.class"); File file = new File(testClasses, "Test1.class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
for (Method m : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (classFile.constant_pool.getUTF8Value(m.name_index).equals("foo")) { if (m.methodName().equalsString("foo")) {
Code_attribute code = (Code_attribute)m.attributes.get(Attribute.Code); CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTable_attribute lnt = (LineNumberTable_attribute)code.attributes.get(Attribute.LineNumberTable); LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
checkLNT(lnt, MyAttr.lineNumber); checkLNT(lnt, MyAttr.lineNumber);
} }
} }
} }
void checkLNT(LineNumberTable_attribute lnt, int lineToCheckFor) { void checkLNT(LineNumberTableAttribute lnt, int lineToCheckFor) {
for (LineNumberTable_attribute.Entry e: lnt.line_number_table) { for (LineNumberInfo e: lnt.lineNumbers()) {
if (e.line_number == lineToCheckFor) { if (e.lineNumber() == lineToCheckFor) {
return; return;
} }
} }

View File

@ -24,23 +24,25 @@
/* /*
* @test 8187805 * @test 8187805
* @summary bogus RuntimeVisibleTypeAnnotations for unused local in a block * @summary bogus RuntimeVisibleTypeAnnotations for unused local in a block
* @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.util * jdk.compiler/com.sun.tools.javac.util
* @run main BogusRTTAForUnusedVarTest * @run main BogusRTTAForUnusedVarTest
*/ */
import com.sun.tools.classfile.*;
import java.io.File; import java.io.File;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.TypeAnnotation; import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import com.sun.tools.classfile.TypeAnnotation.Position;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
public class BogusRTTAForUnusedVarTest { public class BogusRTTAForUnusedVarTest {
@ -69,14 +71,13 @@ public class BogusRTTAForUnusedVarTest {
File testClasses = new File(System.getProperty("test.classes")); File testClasses = new File(System.getProperty("test.classes"));
File file = new File(testClasses, File file = new File(testClasses,
BogusRTTAForUnusedVarTest.class.getName() + "$Foo.class"); BogusRTTAForUnusedVarTest.class.getName() + "$Foo.class");
ClassFile classFile = ClassFile.read(file); ClassModel classFile = Classfile.of().parse(file.toPath());
for (Method m : classFile.methods) { for (MethodModel m : classFile.methods()) {
if (m.getName(classFile.constant_pool).equals("something")) { if (m.methodName().equalsString("something")) {
for (Attribute a : m.attributes) { for (Attribute<?> a : m.attributes()) {
if (a.getName(classFile.constant_pool).equals("Code")) { if (a instanceof CodeAttribute code) {
Code_attribute code = (Code_attribute)a; for (Attribute<?> codeAttrs : code.attributes()) {
for (Attribute codeAttrs : code.attributes) { if (codeAttrs instanceof RuntimeVisibleTypeAnnotationsAttribute) {
if (codeAttrs.getName(classFile.constant_pool).equals("RuntimeVisibleTypeAnnotations")) {
throw new AssertionError("no RuntimeVisibleTypeAnnotations attribute should have been generated in this case"); throw new AssertionError("no RuntimeVisibleTypeAnnotations attribute should have been generated in this case");
} }
} }

View File

@ -25,7 +25,12 @@
* @test 8203892 * @test 8203892
* @summary Target interface added as marker interface in calls to altMetafactory * @summary Target interface added as marker interface in calls to altMetafactory
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
@ -37,11 +42,9 @@
import java.io.File; import java.io.File;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.BootstrapMethods_attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.BootstrapMethods_attribute.BootstrapMethodSpecifier; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool.*;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -80,16 +83,15 @@ public class CheckTargetIsNotAddedAsMarkerInterfaceTest {
} }
void checkClassFile(final File cfile) throws Exception { void checkClassFile(final File cfile) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
for (Attribute attr : classFile.attributes) { for (Attribute<?> attr : classFile.attributes()) {
if (attr.getName(classFile.constant_pool).equals("BootstrapMethods")) { if (attr instanceof BootstrapMethodsAttribute bsmAttr) {
BootstrapMethods_attribute bsmAttr = (BootstrapMethods_attribute)attr; BootstrapMethodEntry bsmSpecifier = bsmAttr.bootstrapMethods().getFirst();
BootstrapMethodSpecifier bsmSpecifier = bsmAttr.bootstrap_method_specifiers[0]; Assert.check(bsmSpecifier.arguments().get(0) instanceof MethodTypeEntry);
Assert.check(classFile.constant_pool.get(bsmSpecifier.bootstrap_arguments[0]) instanceof CONSTANT_MethodType_info); Assert.check(bsmSpecifier.arguments().get(1) instanceof MethodHandleEntry);
Assert.check(classFile.constant_pool.get(bsmSpecifier.bootstrap_arguments[1]) instanceof CONSTANT_MethodHandle_info); Assert.check(bsmSpecifier.arguments().get(2) instanceof MethodTypeEntry);
Assert.check(classFile.constant_pool.get(bsmSpecifier.bootstrap_arguments[2]) instanceof CONSTANT_MethodType_info); Assert.check(bsmSpecifier.arguments().get(3) instanceof IntegerEntry);
Assert.check(classFile.constant_pool.get(bsmSpecifier.bootstrap_arguments[3]) instanceof CONSTANT_Integer_info); Assert.check(bsmSpecifier.arguments().get(4) instanceof IntegerEntry);
Assert.check(classFile.constant_pool.get(bsmSpecifier.bootstrap_arguments[4]) instanceof CONSTANT_Integer_info);
break; break;
} }
} }

View File

@ -26,7 +26,12 @@
* @bug 8209173 * @bug 8209173
* @summary javac fails with completion exception while reporting an error * @summary javac fails with completion exception while reporting an error
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util

View File

@ -26,7 +26,12 @@
* @bug 8222949 * @bug 8222949
* @summary add condy support to javac's pool API * @summary add condy support to javac's pool API
* @library /tools/javac/lib * @library /tools/javac/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.api
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.file
@ -40,6 +45,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import javax.lang.model.type.TypeKind;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.source.tree.*; import com.sun.source.tree.*;
@ -47,14 +53,10 @@ import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener; import com.sun.source.util.TaskListener;
import com.sun.source.util.TreeScanner; import com.sun.source.util.TreeScanner;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.BootstrapMethods_attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.instruction.ConstantInstruction;
import com.sun.tools.classfile.ConstantPool.*;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
@ -74,6 +76,8 @@ import combo.ComboTestHelper;
import combo.ComboInstance; import combo.ComboInstance;
import combo.ComboTask.Result; import combo.ComboTask.Result;
import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> { public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> {
enum ConstantType implements ComboParameter { enum ConstantType implements ComboParameter {
@ -172,10 +176,10 @@ public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> {
return; return;
} }
try (InputStream is = res.get().iterator().next().openInputStream()){ try (InputStream is = res.get().iterator().next().openInputStream()){
ClassFile cf = ClassFile.read(is); ClassModel cf = Classfile.of().parse(is.readAllBytes());
Method testMethod = null; MethodModel testMethod = null;
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
if (m.getName(cf.constant_pool).equals("test")) { if (m.methodName().equalsString("test")) {
testMethod = m; testMethod = m;
break; break;
} }
@ -184,90 +188,79 @@ public class TestConstantDynamic extends ComboInstance<TestConstantDynamic> {
fail("Test method not found"); fail("Test method not found");
return; return;
} }
Code_attribute ea = CodeAttribute ea = testMethod.findAttribute(Attributes.CODE).orElse(null);
(Code_attribute)testMethod.attributes.get(Attribute.Code); if (ea == null) {
if (testMethod == null) {
fail("Code attribute for test() method not found"); fail("Code attribute for test() method not found");
return; return;
} }
int bsmIdx = -1; BootstrapMethodEntry bootstrapMethodEntry = null;
for (Instruction i : ea.getInstructions()) { for (CodeElement i : ea.elementList()) {
if (i.getMnemonic().equals("ldc")) { if (i instanceof ConstantInstruction.LoadConstantInstruction lci) {
CONSTANT_Dynamic_info condyInfo = (CONSTANT_Dynamic_info)cf.constant_pool.get(i.getByte(1)); ConstantDynamicEntry condyInfo = (ConstantDynamicEntry)lci.constantEntry();
bsmIdx = condyInfo.bootstrap_method_attr_index; bootstrapMethodEntry = condyInfo.bootstrap();
System.out.println("condyInfo.getNameAndTypeInfo().getType() " + condyInfo.getNameAndTypeInfo().getType()); System.out.println("condyInfo.getNameAndTypeInfo().getType() " + condyInfo.type().stringValue());
if (!condyInfo.getNameAndTypeInfo().getType().equals(type.bytecodeTypeStr)) { if (!condyInfo.type().equalsString(type.bytecodeTypeStr)) {
fail("type mismatch for CONSTANT_Dynamic_info"); fail("type mismatch for ConstantDynamicEntry");
return; return;
} }
} }
} }
if (bsmIdx == -1) { if (bootstrapMethodEntry == null) {
fail("Missing constantdynamic in generated code"); fail("Missing constantdynamic in generated code");
return; return;
} }
BootstrapMethods_attribute bsm_attr = BootstrapMethodsAttribute bsm_attr = cf.findAttribute(Attributes.BOOTSTRAP_METHODS).orElseThrow();
(BootstrapMethods_attribute)cf if (bsm_attr.bootstrapMethods().size() != 1) {
.getAttribute(Attribute.BootstrapMethods);
if (bsm_attr.bootstrap_method_specifiers.length != 1) {
fail("Bad number of method specifiers " + fail("Bad number of method specifiers " +
"in BootstrapMethods attribute"); "in BootstrapMethods attribute");
return; return;
} }
BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec = BootstrapMethodEntry bsm_spec =
bsm_attr.bootstrap_method_specifiers[0]; bsm_attr.bootstrapMethods().getFirst();
CONSTANT_MethodHandle_info bsm_handle = MethodHandleEntry bsm_handle = bsm_spec.bootstrapMethod();
(CONSTANT_MethodHandle_info)cf.constant_pool
.get(bsm_spec.bootstrap_method_ref);
if (bsm_handle.reference_kind != RefKind.REF_invokeStatic) { if (bsm_handle.kind() != REF_invokeStatic) {
fail("Bad kind on boostrap method handle"); fail("Bad kind on boostrap method handle");
return; return;
} }
CONSTANT_Methodref_info bsm_ref = MemberRefEntry bsm_ref = bsm_handle.reference();
(CONSTANT_Methodref_info)cf.constant_pool
.get(bsm_handle.reference_index);
if (!bsm_ref.getClassInfo().getName().equals("Test")) { if (!bsm_ref.owner().name().equalsString("Test")) {
fail("Bad owner of boostrap method"); fail("Bad owner of boostrap method");
return; return;
} }
if (!bsm_ref.getNameAndTypeInfo().getName().equals("bsm")) { if (!bsm_ref.name().equalsString("bsm")) {
fail("Bad boostrap method name"); fail("Bad boostrap method name");
return; return;
} }
if (!bsm_ref.getNameAndTypeInfo() if (!bsm_ref.type().equalsString(asBSMSignatureString())) {
.getType().equals(asBSMSignatureString())) {
fail("Bad boostrap method type" + fail("Bad boostrap method type" +
bsm_ref.getNameAndTypeInfo().getType() + " " + bsm_ref.type() + " " +
asBSMSignatureString()); asBSMSignatureString());
return; return;
} }
LineNumberTable_attribute lnt = LineNumberTableAttribute lnt = ea.findAttribute(Attributes.LINE_NUMBER_TABLE).orElse(null);
(LineNumberTable_attribute)ea.attributes.get(Attribute.LineNumberTable);
if (lnt == null) { if (lnt == null) {
fail("No LineNumberTable attribute"); fail("No LineNumberTable attribute");
return; return;
} }
if (lnt.line_number_table_length != 2) { if (lnt.lineNumbers().size() != 2) {
fail("Wrong number of entries in LineNumberTable"); fail("Wrong number of entries in LineNumberTable");
return;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
fail("error reading classfile: " + res.compilationInfo()); fail("error reading classfile: " + res.compilationInfo());
return;
} }
} }

View File

@ -26,7 +26,12 @@
* @bug 8194978 * @bug 8194978
* @summary Verify than an appropriate number of close method invocations is generated. * @summary Verify than an appropriate number of close method invocations is generated.
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* @build toolbox.ToolBox TwrSimpleClose * @build toolbox.ToolBox TwrSimpleClose
* @run main TwrSimpleClose * @run main TwrSimpleClose
*/ */
@ -52,14 +57,10 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.constantpool.MemberRefEntry;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info; import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Opcode;
import toolbox.ToolBox; import toolbox.ToolBox;
@ -101,17 +102,14 @@ public class TwrSimpleClose {
} }
byte[] data = fm.classBytes.values().iterator().next(); byte[] data = fm.classBytes.values().iterator().next();
ClassFile cf = ClassFile.read(new ByteArrayInputStream(data)); ClassModel cf = Classfile.of().parse(new ByteArrayInputStream(data).readAllBytes());
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
Code_attribute codeAttr = (Code_attribute) m.attributes.map.get(Attribute.Code); CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction i : codeAttr.getInstructions()) { for (CodeElement ce : codeAttr.elementList()) {
if (i.getOpcode() == Opcode.INVOKEVIRTUAL) { if (ce instanceof InvokeInstruction ins && ins.opcode() == Opcode.INVOKEVIRTUAL) {
CONSTANT_Methodref_info method = MemberRefEntry method = ins.method();
(CONSTANT_Methodref_info) cf.constant_pool.get(i.getShort(1)); if (method.name().equalsString("close")) {
CONSTANT_NameAndType_info nameAndType =
cf.constant_pool.getNameAndTypeInfo(method.name_and_type_index);
if ("close".equals(nameAndType.getName())) {
closeCount++; closeCount++;
} }
} }

View File

@ -27,13 +27,19 @@
* @bug 8241312 8246774 * @bug 8241312 8246774
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.util * @modules 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
* @run main ApplicableAnnotationsOnRecords * @run main ApplicableAnnotationsOnRecords
*/ */
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.io.InputStream; import java.io.InputStream;
import java.util.Objects;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD}) @Target({ElementType.FIELD})
@ -54,30 +60,30 @@ public record ApplicableAnnotationsOnRecords(@FieldAnnotation @MethodAnnotation
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
try ( InputStream in = ApplicableAnnotationsOnRecords.class.getResourceAsStream("ApplicableAnnotationsOnRecords.class")) { try ( InputStream in = ApplicableAnnotationsOnRecords.class.getResourceAsStream("ApplicableAnnotationsOnRecords.class")) {
ClassFile cf = ClassFile.read(in); ClassModel cm = Classfile.of().parse(Objects.requireNonNull(in).readAllBytes());
Assert.check(cf.methods.length > 5); Assert.check(cm.methods().size() > 5);
for (Method m : cf.methods) { for (MethodModel mm : cm.methods()) {
String methodName = m.getName(cf.constant_pool); String methodName = mm.methodName().stringValue();
if (methodName.equals("toString") || methodName.equals("hashCode") || methodName.equals("equals") || methodName.equals("main")) { if (methodName.equals("toString") || methodName.equals("hashCode") || methodName.equals("equals") || methodName.equals("main")) {
// ignore // ignore
} else if (methodName.equals("<init>")) { } else if (methodName.equals("<init>")) {
var paAnnos = ((RuntimeVisibleParameterAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleParameterAnnotations)).parameter_annotations; var paAnnos = mm.findAttribute(Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS).orElseThrow().parameterAnnotations();
Assert.check(paAnnos.length > 0); Assert.check(paAnnos.size() > 0);
for (var pa : paAnnos) { for (var pa : paAnnos) {
Assert.check(pa.length == 1); Assert.check(pa.size() == 1);
Assert.check(cf.constant_pool.getUTF8Value(pa[0].type_index).equals("LParameterAnnotation;")); Assert.check(Objects.equals(pa.get(0).classSymbol().descriptorString(), "LParameterAnnotation;"));
} }
} else { } else {
var annos = ((RuntimeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleAnnotations)).annotations; var annos = mm.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElseThrow().annotations();
Assert.check(annos.length == 1); Assert.check(annos.size() == 1);
Assert.check(cf.constant_pool.getUTF8Value(annos[0].type_index).equals("LMethodAnnotation;")); Assert.check(Objects.equals(annos.get(0).classSymbol().descriptorString(), "LMethodAnnotation;"));
} }
} }
Assert.check(cf.fields.length > 0); Assert.check(cm.fields().size() > 0);
for (Field field : cf.fields) { for (FieldModel fm : cm.fields()) {
var annos = ((RuntimeAnnotations_attribute) field.attributes.get(Attribute.RuntimeVisibleAnnotations)).annotations; var annos = fm.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElseThrow().annotations();
Assert.check(annos.length == 1); Assert.check(annos.size() == 1);
Assert.check(cf.constant_pool.getUTF8Value(annos[0].type_index).equals("LFieldAnnotation;")); Assert.check(Objects.equals(annos.getFirst().classSymbol().descriptorString(), "LFieldAnnotation;"));
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,12 @@
* @summary Verify location of type annotations on records * @summary Verify location of type annotations on records
* @library /tools/lib * @library /tools/lib
* @modules * @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
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
@ -45,7 +50,8 @@ import java.nio.file.Paths;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.util.Arrays; import java.util.Arrays;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -109,11 +115,11 @@ public class TypeAnnotationsPositionsOnRecords {
} }
void checkClassFile(final File cfile, int... taPositions) throws Exception { void checkClassFile(final File cfile, int... taPositions) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
int accessorPos = 0; int accessorPos = 0;
int checkedAccessors = 0; int checkedAccessors = 0;
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
String methodName = method.getName(classFile.constant_pool); String methodName = method.methodName().stringValue();
if (methodName.equals("toString") || methodName.equals("hashCode") || methodName.equals("equals")) { if (methodName.equals("toString") || methodName.equals("hashCode") || methodName.equals("equals")) {
// ignore // ignore
continue; continue;
@ -138,15 +144,16 @@ public class TypeAnnotationsPositionsOnRecords {
* there can be several parameters annotated we have to check that the ones annotated are the * there can be several parameters annotated we have to check that the ones annotated are the
* expected ones * expected ones
*/ */
void checkConstructor(ClassFile classFile, Method method, int... positions) throws Exception { void checkConstructor(ClassModel classFile, MethodModel method, int... positions) throws Exception {
List<TypeAnnotation> annos = new ArrayList<>(); List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(classFile, method, annos); findAnnotations(classFile, method, annos);
Assert.check(annos.size() == positions.length); Assert.check(annos.size() == positions.length);
int i = 0; int i = 0;
for (int pos : positions) { for (int pos : positions) {
TypeAnnotation ta = annos.get(i); TypeAnnotation ta = annos.get(i);
Assert.check(ta.position.type.toString().equals("METHOD_FORMAL_PARAMETER")); Assert.check(ta.targetInfo().targetType().name().equals("METHOD_FORMAL_PARAMETER"));
Assert.check(ta.position.parameter_index == pos); assert ta.targetInfo() instanceof TypeAnnotation.FormalParameterTarget;
Assert.check(((TypeAnnotation.FormalParameterTarget)ta.targetInfo()).formalParameterIndex() == pos);
i++; i++;
} }
} }
@ -155,25 +162,25 @@ public class TypeAnnotationsPositionsOnRecords {
* this case is simpler as there can only be one annotation at the accessor and it has to be applied * this case is simpler as there can only be one annotation at the accessor and it has to be applied
* at the return type * at the return type
*/ */
void checkAccessor(ClassFile classFile, Method method) { void checkAccessor(ClassModel classFile, MethodModel method) {
List<TypeAnnotation> annos = new ArrayList<>(); List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(classFile, method, annos); findAnnotations(classFile, method, annos);
Assert.check(annos.size() == 1); Assert.check(annos.size() == 1);
TypeAnnotation ta = annos.get(0); TypeAnnotation ta = annos.get(0);
Assert.check(ta.position.type.toString().equals("METHOD_RETURN")); Assert.check(ta.targetInfo().targetType().name().equals("METHOD_RETURN"));
} }
/* /*
* here we have to check that only the fields for which its position matches with the one of the * here we have to check that only the fields for which its position matches with the one of the
* original annotated record component are annotated * original annotated record component are annotated
*/ */
void checkFields(ClassFile classFile, int... positions) { void checkFields(ClassModel classFile, int... positions) {
if (positions != null && positions.length > 0) { if (positions != null && positions.length > 0) {
int fieldPos = 0; int fieldPos = 0;
int annotationPos = 0; int annotationPos = 0;
int currentAnnoPosition = positions[annotationPos]; int currentAnnoPosition = positions[annotationPos];
int annotatedFields = 0; int annotatedFields = 0;
for (Field field : classFile.fields) { for (FieldModel field : classFile.fields()) {
List<TypeAnnotation> annos = new ArrayList<>(); List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(classFile, field, annos); findAnnotations(classFile, field, annos);
if (fieldPos != currentAnnoPosition) { if (fieldPos != currentAnnoPosition) {
@ -181,7 +188,7 @@ public class TypeAnnotationsPositionsOnRecords {
} else { } else {
Assert.check(annos.size() == 1); Assert.check(annos.size() == 1);
TypeAnnotation ta = annos.get(0); TypeAnnotation ta = annos.get(0);
Assert.check(ta.position.type.toString().equals("FIELD")); Assert.check(ta.targetInfo().targetType().name().equals("FIELD"));
annotationPos++; annotationPos++;
currentAnnoPosition = annotationPos < positions.length ? positions[annotationPos] : -1; currentAnnoPosition = annotationPos < positions.length ? positions[annotationPos] : -1;
annotatedFields++; annotatedFields++;
@ -193,47 +200,36 @@ public class TypeAnnotationsPositionsOnRecords {
} }
// utility methods // utility methods
void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) { void findAnnotations(ClassModel cm, AttributedElement m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); findAnnotations(cm, m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); findAnnotations(cm, m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
} }
void findAnnotations(ClassFile cf, Field m, List<TypeAnnotation> annos) { <T extends Attribute<T>> void findAnnotations(ClassModel cf, AttributedElement m, AttributeMapper<T> attrName, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); Attribute<T> attr = m.findAttribute(attrName).orElse(null);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); addAnnos(annos, attr);
} if (m instanceof MethodModel) {
CodeAttribute cattr = m.findAttribute(Attributes.CODE).orElse(null);
void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) { if (cattr != null) {
int index = m.attributes.getIndex(cf.constant_pool, name); attr = cattr.findAttribute(attrName).orElse(null);
if (index != -1) { addAnnos(annos, attr);
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
}
int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
if (cindex != -1) {
Attribute cattr = m.attributes.get(cindex);
assert cattr instanceof Code_attribute;
Code_attribute cAttr = (Code_attribute)cattr;
index = cAttr.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = cAttr.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
} }
} }
} }
void findAnnotations(ClassFile cf, Field m, String name, List<TypeAnnotation> annos) { private <T extends Attribute<T>> void addAnnos(List<TypeAnnotation> annos, Attribute<T> attr) {
int index = m.attributes.getIndex(cf.constant_pool, name); if (attr != null) {
if (index != -1) { switch (attr) {
Attribute attr = m.attributes.get(index); case RuntimeVisibleTypeAnnotationsAttribute vanno -> {
assert attr instanceof RuntimeTypeAnnotations_attribute; annos.addAll(vanno.annotations());
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; }
annos.addAll(Arrays.asList(tAttr.annotations)); case RuntimeInvisibleTypeAnnotationsAttribute ivanno -> {
annos.addAll(ivanno.annotations());
}
default -> {
throw new AssertionError();
}
}
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,12 @@
* @summary check that potentially applicable type annotations are skip if the variable or parameter was declared with var * @summary check that potentially applicable type annotations are skip if the variable or parameter was declared with var
* @library /tools/lib * @library /tools/lib
* @modules * @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
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
@ -45,7 +50,8 @@ import java.nio.file.Paths;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.util.Arrays; import java.util.Arrays;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import toolbox.JavacTask; import toolbox.JavacTask;
@ -97,41 +103,45 @@ public class VariablesDeclaredWithVarTest {
} }
void checkClassFile(final File cfile, int... taPositions) throws Exception { void checkClassFile(final File cfile, int... taPositions) throws Exception {
ClassFile classFile = ClassFile.read(cfile); ClassModel classFile = Classfile.of().parse(cfile.toPath());
List<TypeAnnotation> annos = new ArrayList<>(); List<TypeAnnotation> annos = new ArrayList<>();
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
findAnnotations(classFile, method, annos); findAnnotations(classFile, method, annos);
String methodName = method.getName(classFile.constant_pool); String methodName = method.methodName().stringValue();
Assert.check(annos.size() == 0, "there shouldn't be any type annotations in any method, found " + annos.size() + Assert.check(annos.size() == 0, "there shouldn't be any type annotations in any method, found " + annos.size() +
" type annotations at method " + methodName); " type annotations at method " + methodName);
} }
} }
void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) { void findAnnotations(ClassModel cf, MethodModel m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); findAnnotations(cf, m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); findAnnotations(cf, m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
} }
void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) { <T extends Attribute<T>> void findAnnotations(ClassModel cf, AttributedElement m, AttributeMapper<T> attrName, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name); Attribute<T> attr = m.findAttribute(attrName).orElse(null);
if (index != -1) { addAnnos(annos, attr);
Attribute attr = m.attributes.get(index); if (m instanceof MethodModel) {
assert attr instanceof RuntimeTypeAnnotations_attribute; CodeAttribute cattr = m.findAttribute(Attributes.CODE).orElse(null);
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; if (cattr != null) {
annos.addAll(Arrays.asList(tAttr.annotations)); attr = cattr.findAttribute(attrName).orElse(null);
addAnnos(annos, attr);
}
}
} }
int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code); private <T extends Attribute<T>> void addAnnos(List<TypeAnnotation> annos, Attribute<T> attr) {
if (cindex != -1) { if (attr != null) {
Attribute cattr = m.attributes.get(cindex); switch (attr) {
assert cattr instanceof Code_attribute; case RuntimeVisibleTypeAnnotationsAttribute vanno -> {
Code_attribute cAttr = (Code_attribute)cattr; annos.addAll(vanno.annotations());
index = cAttr.attributes.getIndex(cf.constant_pool, name); }
if (index != -1) { case RuntimeInvisibleTypeAnnotationsAttribute ivanno -> {
Attribute attr = cAttr.attributes.get(index); annos.addAll(ivanno.annotations());
assert attr instanceof RuntimeTypeAnnotations_attribute; }
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; default -> {
annos.addAll(Arrays.asList(tAttr.annotations)); throw new AssertionError();
}
} }
} }
} }

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 8164519 * @bug 8042451 8164519
* @summary Test population of reference info for class extends clauses * @summary Test population of reference info for class extends clauses
* @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 Driver.java ReferenceInfoUtil.java ClassExtends.java * @compile -g Driver.java ReferenceInfoUtil.java ClassExtends.java
* @run main Driver ClassExtends * @run main Driver ClassExtends
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for class type parameters * @summary Test population of reference info for class type parameters
* @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 Driver.java ReferenceInfoUtil.java ClassTypeParam.java * @compile -g Driver.java ReferenceInfoUtil.java ClassTypeParam.java
* @run main Driver ClassTypeParam * @run main Driver ClassTypeParam
*/ */

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for constructor invocation type argument * @summary Test population of reference info for constructor invocation type argument
* @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 Driver.java ReferenceInfoUtil.java ConstructorInvocationTypeArgument.java * @compile -g Driver.java ReferenceInfoUtil.java ConstructorInvocationTypeArgument.java
* @run main Driver ConstructorInvocationTypeArgument * @run main Driver ConstructorInvocationTypeArgument
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; import static jdk.internal.classfile.TypeAnnotation.TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
public class ConstructorInvocationTypeArgument { public class ConstructorInvocationTypeArgument {

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 8026791 8042451 * @bug 8026791 8042451
* @summary Test population of reference info for constructor results * @summary Test population of reference info for constructor results
* @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 Driver.java ReferenceInfoUtil.java Constructors.java * @compile -g Driver.java ReferenceInfoUtil.java Constructors.java
* @run main Driver Constructors * @run main Driver Constructors
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Constructors { public class Constructors {

View File

@ -21,6 +21,7 @@
* questions. * questions.
*/ */
import jdk.internal.classfile.*;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -29,16 +30,8 @@ import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.classfile.TypeAnnotation.TargetType;
import static java.lang.String.format; import static java.lang.String.format;
@ -53,7 +46,7 @@ public class Driver {
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length == 0 || args.length > 1) if (args.length != 1)
throw new IllegalArgumentException("Usage: java Driver <test-name>"); throw new IllegalArgumentException("Usage: java Driver <test-name>");
String name = args[0]; String name = args[0];
new Driver(Class.forName(name)).runDriver(); new Driver(Class.forName(name)).runDriver();
@ -74,7 +67,7 @@ public class Driver {
// Find methods // Find methods
for (Method method : clazz.getMethods()) { for (Method method : clazz.getMethods()) {
try { try {
Map<String, TypeAnnotation.Position> expected = expectedOf(method); Map<String, ReferenceInfoUtil.TAD> expected = expectedOf(method);
if (expected == null) if (expected == null)
continue; continue;
if (method.getReturnType() != String.class) if (method.getReturnType() != String.class)
@ -84,15 +77,15 @@ public class Driver {
for (String retentionPolicy : retentionPolicies) { for (String retentionPolicy : retentionPolicies) {
String testClassName = getTestClassName(method, retentionPolicy); String testClassName = getTestClassName(method, retentionPolicy);
String testClass = testClassOf(method, testClassName); String testClass = testClassOf(method, testClassName);
String fullFile = wrap(compact, new HashMap<String, String>() {{ String fullFile = wrap(compact, new HashMap<>() {{
put("%RETENTION_POLICY%", retentionPolicy); put("%RETENTION_POLICY%", retentionPolicy);
put("%TEST_CLASS_NAME%", testClassName); put("%TEST_CLASS_NAME%", testClassName);
}}); }});
for (String[] extraParams : extraParamsCombinations) { for (String[] extraParams : extraParamsCombinations) {
try { try {
ClassFile cf = compileAndReturn(fullFile, testClass, extraParams); ClassModel cm = compileAndReturn(fullFile, testClass, extraParams);
List<TypeAnnotation> actual = ReferenceInfoUtil.extendedAnnotationsOf(cf); List<ReferenceInfoUtil.TAD> actual = ReferenceInfoUtil.extendedAnnotationsOf(cm);
ReferenceInfoUtil.compare(expected, actual, cf); ReferenceInfoUtil.compare(expected, actual);
out.format("PASSED: %s %s%n", testClassName, Arrays.toString(extraParams)); out.format("PASSED: %s %s%n", testClassName, Arrays.toString(extraParams));
++passed; ++passed;
} catch (Throwable e) { } catch (Throwable e) {
@ -106,7 +99,7 @@ public class Driver {
} }
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
out.println("FAILED: " + method.getName()); out.println("FAILED: " + method.getName());
out.println(" " + e.toString()); out.println(" " + e);
e.printStackTrace(out); e.printStackTrace(out);
++failed; ++failed;
} }
@ -122,61 +115,35 @@ public class Driver {
throw new RuntimeException(failed + " tests failed"); throw new RuntimeException(failed + " tests failed");
} }
private Map<String, TypeAnnotation.Position> expectedOf(Method m) { private Map<String, ReferenceInfoUtil.TAD> expectedOf(Method m) {
TADescription ta = m.getAnnotation(TADescription.class); TADescription ta = m.getAnnotation(TADescription.class);
TADescriptions tas = m.getAnnotation(TADescriptions.class); TADescriptions tas = m.getAnnotation(TADescriptions.class);
if (ta == null && tas == null) if (ta == null && tas == null)
return null; return null;
Map<String, TypeAnnotation.Position> result = Map<String, ReferenceInfoUtil.TAD> result =
new HashMap<>(); new HashMap<>();
if (ta != null) if (ta != null)
result.putAll(expectedOf(ta)); result.put(ta.annotation(), wrapTADescription(ta));
if (tas != null) { if (tas != null) {
for (TADescription a : tas.value()) { for (TADescription a : tas.value()) {
result.putAll(expectedOf(a)); result.put(a.annotation(), wrapTADescription(a));
} }
} }
return result; return result;
} }
private ReferenceInfoUtil.TAD wrapTADescription(TADescription taD) {
private Map<String, TypeAnnotation.Position> expectedOf(TADescription d) { List<Integer> genericLocation = Arrays.stream(taD.genericLocation()).boxed().collect(Collectors.toList());
String annoName = d.annotation(); List<Integer> lvarIndex = Arrays.stream(taD.lvarIndex()).boxed().collect(Collectors.toList());
List<Integer> lvarLength = Arrays.stream(taD.lvarLength()).boxed().collect(Collectors.toList());
TypeAnnotation.Position p = new TypeAnnotation.Position(); List<Integer> lvarOffset = Arrays.stream(taD.lvarOffset()).boxed().collect(Collectors.toList());
p.type = d.type(); return new ReferenceInfoUtil.TAD(taD.annotation(), taD.type(), taD.typeIndex(),
if (d.offset() != NOT_SET) taD.paramIndex(), taD.boundIndex(), taD.exceptionIndex(), taD.offset(),
p.offset = d.offset(); lvarOffset, lvarLength, lvarIndex, genericLocation);
if (d.lvarOffset().length != 0)
p.lvarOffset = d.lvarOffset();
if (d.lvarLength().length != 0)
p.lvarLength = d.lvarLength();
if (d.lvarIndex().length != 0)
p.lvarIndex = d.lvarIndex();
if (d.boundIndex() != NOT_SET)
p.bound_index = d.boundIndex();
if (d.paramIndex() != NOT_SET)
p.parameter_index = d.paramIndex();
if (d.typeIndex() != NOT_SET)
p.type_index = d.typeIndex();
if (d.exceptionIndex() != NOT_SET)
p.exception_index = d.exceptionIndex();
if (d.genericLocation().length != 0) {
p.location = TypeAnnotation.Position.getTypePathFromBinary(wrapIntArray(d.genericLocation()));
}
return Collections.singletonMap(annoName, p);
}
private List<Integer> wrapIntArray(int[] ints) {
List<Integer> list = new ArrayList<>(ints.length);
for (int i : ints)
list.add(i);
return list;
} }
private String getTestClassName(Method m, String retentionPolicy) { private String getTestClassName(Method m, String retentionPolicy) {
@ -193,10 +160,10 @@ public class Driver {
} }
} }
private ClassFile compileAndReturn(String fullFile, String testClass, String... extraParams) throws Exception { private ClassModel compileAndReturn(String fullFile, String testClass, String... extraParams) throws Exception {
File source = writeTestFile(fullFile, testClass); File source = writeTestFile(fullFile, testClass);
File clazzFile = compileTestFile(source, testClass, extraParams); File clazzFile = compileTestFile(source, testClass, extraParams);
return ClassFile.read(clazzFile); return Classfile.of().parse(clazzFile.toPath());
} }
protected File writeTestFile(String fullFile, String testClass) throws IOException { protected File writeTestFile(String fullFile, String testClass) throws IOException {
@ -208,14 +175,13 @@ public class Driver {
} }
private String getClassDir() { private String getClassDir() {
return System.getProperty("test.classes", Driver.class.getResource(".").getPath()); return System.getProperty("test.classes", Objects.requireNonNull(Driver.class.getResource(".")).getPath());
} }
protected File compileTestFile(File f, String testClass, String... extraParams) { protected File compileTestFile(File f, String testClass, String... extraParams) {
List<String> options = new ArrayList<>(); List<String> options = new ArrayList<>(Arrays.asList(extraParams));
options.addAll(Arrays.asList(extraParams));
options.add(f.getPath()); options.add(f.getPath());
int rc = com.sun.tools.javac.Main.compile(options.toArray(new String[options.size()])); int rc = com.sun.tools.javac.Main.compile(options.toArray(new String[0]));
if (rc != 0) if (rc != 0)
throw new Error("compilation failed. rc=" + rc); throw new Error("compilation failed. rc=" + rc);
String path = f.getParent() != null ? f.getParent() : ""; String path = f.getParent() != null ? f.getParent() : "";
@ -352,7 +318,7 @@ public class Driver {
return src; return src;
} }
public static final int NOT_SET = -888; public static final int NOT_SET = Integer.MIN_VALUE;
} }
@ -362,7 +328,7 @@ public class Driver {
@interface TADescription { @interface TADescription {
String annotation(); String annotation();
TargetType type(); TypeAnnotation.TargetType type();
int offset() default Driver.NOT_SET; int offset() default Driver.NOT_SET;
int[] lvarOffset() default { }; int[] lvarOffset() default { };
int[] lvarLength() default { }; int[] lvarLength() default { };

View File

@ -21,14 +21,19 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8028576 8042451 * @bug 8028576 8042451
* @summary Test population of reference info for exception parameters * @summary Test population of reference info for exception parameters
* @author Werner Dietl * @author Werner Dietl
* @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 Driver.java ReferenceInfoUtil.java ExceptionParameters.java * @compile -g Driver.java ReferenceInfoUtil.java ExceptionParameters.java
* @run main Driver ExceptionParameters * @run main Driver ExceptionParameters
*/ */

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 8042451 8208470 * @bug 8042451 8208470
* @summary Test population of reference info for field * @summary Test population of reference info for field
* @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 Driver.java ReferenceInfoUtil.java Fields.java * @compile -g Driver.java ReferenceInfoUtil.java Fields.java
* @run main Driver Fields * @run main Driver Fields
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Fields { public class Fields {
// field types // field types

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test that the examples from the manual are stored as expected * @summary Test that the examples from the manual are stored as expected
* @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 Driver.java ReferenceInfoUtil.java FromSpecification.java * @compile -g Driver.java ReferenceInfoUtil.java FromSpecification.java
* @run main Driver FromSpecification * @run main Driver FromSpecification
*/ */

View File

@ -21,14 +21,19 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8013852 8042451 * @bug 8013852 8042451
* @summary Test population of reference info for instance and class initializers * @summary Test population of reference info for instance and class initializers
* @author Werner Dietl * @author Werner Dietl
* @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 Driver.java ReferenceInfoUtil.java Initializers.java * @compile -g Driver.java ReferenceInfoUtil.java Initializers.java
* @run main Driver Initializers * @run main Driver Initializers
*/ */

View File

@ -26,14 +26,19 @@
* @bug 8008077 8029721 8042451 8043974 * @bug 8008077 8029721 8042451 8043974
* @summary Test population of reference info for lambda expressions * @summary Test population of reference info for lambda expressions
* javac crash for annotated parameter type of lambda in a field * javac crash for annotated parameter type of lambda in a field
* @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
* @ignore 8057687 emit correct byte code an attributes for type annotations * @ignore 8057687 emit correct byte code an attributes for type annotations
* @compile -g Driver.java ReferenceInfoUtil.java Lambda.java * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
* @run main Driver Lambda * @run main Driver Lambda
* @author Werner Dietl * @author Werner Dietl
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Lambda { public class Lambda {

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method invocation type arguments * @summary Test population of reference info for method invocation type arguments
* @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 Driver.java ReferenceInfoUtil.java MethodInvocationTypeArgument.java * @compile -g Driver.java ReferenceInfoUtil.java MethodInvocationTypeArgument.java
* @run main Driver MethodInvocationTypeArgument * @run main Driver MethodInvocationTypeArgument
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; import static jdk.internal.classfile.TypeAnnotation.TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
import static java.lang.System.lineSeparator; import static java.lang.System.lineSeparator;
public class MethodInvocationTypeArgument { public class MethodInvocationTypeArgument {

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method parameters * @summary Test population of reference info for method parameters
* @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 Driver.java ReferenceInfoUtil.java MethodParameters.java * @compile -g Driver.java ReferenceInfoUtil.java MethodParameters.java
* @run main Driver MethodParameters * @run main Driver MethodParameters
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method receivers * @summary Test population of reference info for method receivers
* @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 Driver.java ReferenceInfoUtil.java MethodReceivers.java * @compile -g Driver.java ReferenceInfoUtil.java MethodReceivers.java
* @run main Driver MethodReceivers * @run main Driver MethodReceivers
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method return * @summary Test population of reference info for method return
* @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 Driver.java ReferenceInfoUtil.java MethodReturns.java * @compile -g Driver.java ReferenceInfoUtil.java MethodReturns.java
* @run main Driver MethodReturns * @run main Driver MethodReturns
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method exception clauses * @summary Test population of reference info for method exception clauses
* @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 Driver.java ReferenceInfoUtil.java MethodThrows.java * @compile -g Driver.java ReferenceInfoUtil.java MethodThrows.java
* @run main Driver MethodThrows * @run main Driver MethodThrows
*/ */

View File

@ -21,14 +21,19 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
import static java.lang.System.lineSeparator; import static java.lang.System.lineSeparator;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for method type parameters * @summary Test population of reference info for method type parameters
* @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 Driver.java ReferenceInfoUtil.java MethodTypeParam.java * @compile -g Driver.java ReferenceInfoUtil.java MethodTypeParam.java
* @run main Driver MethodTypeParam * @run main Driver MethodTypeParam
*/ */

View File

@ -21,14 +21,19 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8006732 8006775 8042451 * @bug 8006732 8006775 8042451
* @summary Test population of reference info for multicatch exception parameters * @summary Test population of reference info for multicatch exception parameters
* @author Werner Dietl * @author Werner Dietl
* @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 Driver.java ReferenceInfoUtil.java MultiCatch.java * @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java
* @run main Driver MultiCatch * @run main Driver MultiCatch
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 8044009 8044010 * @bug 8042451 8044009 8044010
* @summary Test population of reference info for nested types * @summary Test population of reference info for nested types
* @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
* @ignore 8057687 emit correct byte code an attributes for type annotations * @ignore 8057687 emit correct byte code an attributes for type annotations
* @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java * @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java
* @run main Driver NestedTypes * @run main Driver NestedTypes

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for new object creations * @summary Test population of reference info for new object creations
* @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 Driver.java ReferenceInfoUtil.java NewObjects.java * @compile -g Driver.java ReferenceInfoUtil.java NewObjects.java
* @run main Driver NewObjects * @run main Driver NewObjects
*/ */

View File

@ -21,102 +21,126 @@
* questions. * questions.
*/ */
import java.util.ArrayList; import jdk.internal.classfile.*;
import java.util.Arrays; import jdk.internal.classfile.attribute.*;
import java.util.List; import java.util.*;
import java.util.Map;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute;
import com.sun.tools.classfile.ConstantPool.InvalidIndex;
import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
public class ReferenceInfoUtil { public class ReferenceInfoUtil {
public static final int IGNORE_VALUE = -321; public static final int IGNORE_VALUE = Integer.MIN_VALUE;
public static List<TypeAnnotation> extendedAnnotationsOf(ClassFile cf) { public static List<TAD> extendedAnnotationsOf(ClassModel cm) {
List<TypeAnnotation> annos = new ArrayList<>(); List<TAD> annos = new ArrayList<>();
findAnnotations(cf, annos); findAnnotations(cm, annos);
return annos; return annos;
} }
/////////////////// Extract type annotations ////////////////// /////////////////// Extract type annotations //////////////////
private static void findAnnotations(ClassFile cf, List<TypeAnnotation> annos) { private static void findAnnotations(ClassModel cm, List<TAD> annos) {
findAnnotations(cf, Attribute.RuntimeVisibleTypeAnnotations, annos); findAnnotations(cm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cf, Attribute.RuntimeInvisibleTypeAnnotations, annos); findAnnotations(cm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
for (Field f : cf.fields) { for (FieldModel f : cm.fields()) {
findAnnotations(cf, f, annos); findAnnotations(f, annos);
} }
for (Method m: cf.methods) { for (MethodModel m: cm.methods()) {
findAnnotations(cf, m, annos); findAnnotations(m, annos);
} }
} }
private static void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) { private static void findAnnotations(AttributedElement ae, List<TAD> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); findAnnotations(ae, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); findAnnotations(ae, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
}
private static void findAnnotations(ClassFile cf, Field m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
} }
// test the result of Attributes.getIndex according to expectations // test the result of Attributes.getIndex according to expectations
// encoded in the method's name // encoded in the method's name
private static void findAnnotations(ClassFile cf, String name, List<TypeAnnotation> annos) { private static <T extends Attribute<T>> void findAnnotations(ClassModel cm, AttributeMapper<T> attrName, List<TAD> annos) {
int index = cf.attributes.getIndex(cf.constant_pool, name); Attribute<T> attr = cm.findAttribute(attrName).orElse(null);
if (index != -1) { if (attr != null) {
Attribute attr = cf.attributes.get(index); if (attr instanceof RuntimeVisibleTypeAnnotationsAttribute tAttr) {
assert attr instanceof RuntimeTypeAnnotations_attribute; annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; } else if (attr instanceof RuntimeInvisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Arrays.asList(tAttr.annotations)); annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} else throw new AssertionError();
} }
} }
// test the result of Attributes.getIndex according to expectations // test the result of Attributes.getIndex according to expectations
// encoded in the method's name // encoded in the method's name
private static void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) { private static <T extends Attribute<T>> void findAnnotations(AttributedElement m, AttributeMapper<T> attrName, List<TAD> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name); Attribute<T> attr = m.findAttribute(attrName).orElse(null);
if (index != -1) { if (attr != null) {
Attribute attr = m.attributes.get(index); if (attr instanceof RuntimeVisibleTypeAnnotationsAttribute tAttr) {
assert attr instanceof RuntimeTypeAnnotations_attribute; annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; } else if (attr instanceof RuntimeInvisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Arrays.asList(tAttr.annotations)); annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} else throw new AssertionError();
}
if (m instanceof MethodModel mm) {
CodeAttribute cAttr = mm.findAttribute(Attributes.CODE).orElse(null);
if (cAttr != null) {
Attribute<T> attr2 = cAttr.findAttribute(attrName).orElse(null);;
if (attr2 != null) {
if (attr2 instanceof RuntimeVisibleTypeAnnotationsAttribute tAttr2) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr2.annotations(), cAttr)));
} else if (attr2 instanceof RuntimeInvisibleTypeAnnotationsAttribute tAttr2) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr2.annotations(), cAttr)));
} else throw new AssertionError();
} }
int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code);
if (cindex != -1) {
Attribute cattr = m.attributes.get(cindex);
assert cattr instanceof Code_attribute;
Code_attribute cAttr = (Code_attribute)cattr;
index = cAttr.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = cAttr.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
} }
} }
} }
// test the result of Attributes.getIndex according to expectations // get each target information and wrap with TAD (corresponding with TADescription in driver class)
// encoded in the method's name private static List<TAD> generateTADList(List<TypeAnnotation> annos, CodeAttribute cAttr) {
private static void findAnnotations(ClassFile cf, Field m, String name, List<TypeAnnotation> annos) { List<TAD> result = new ArrayList<>();
int index = m.attributes.getIndex(cf.constant_pool, name); for (TypeAnnotation anno: annos) {
if (index != -1) { TAD tad = new TAD();
Attribute attr = m.attributes.get(index); tad.annotation = anno.className().stringValue();
assert attr instanceof RuntimeTypeAnnotations_attribute; tad.type = anno.targetInfo().targetType();
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; switch (anno.targetInfo().targetType()) {
annos.addAll(Arrays.asList(tAttr.annotations)); case CAST, CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, METHOD_INVOCATION_TYPE_ARGUMENT -> {
if (cAttr == null) throw new AssertionError("Invalid Annotation");
tad.typeIndex = ((TypeAnnotation.TypeArgumentTarget) anno.targetInfo()).typeArgumentIndex();
tad.offset = cAttr.labelToBci(((TypeAnnotation.TypeArgumentTarget) anno.targetInfo()).target());
} }
case CLASS_EXTENDS -> tad.typeIndex = ((TypeAnnotation.SupertypeTarget) anno.targetInfo()).supertypeIndex();
case CLASS_TYPE_PARAMETER, METHOD_TYPE_PARAMETER -> tad.paramIndex = ((TypeAnnotation.TypeParameterTarget) anno.targetInfo()).typeParameterIndex();
case CLASS_TYPE_PARAMETER_BOUND, METHOD_TYPE_PARAMETER_BOUND -> {
tad.paramIndex = ((TypeAnnotation.TypeParameterBoundTarget) anno.targetInfo()).typeParameterIndex();
tad.boundIndex = ((TypeAnnotation.TypeParameterBoundTarget) anno.targetInfo()).boundIndex();
}
case EXCEPTION_PARAMETER -> tad.exceptionIndex = ((TypeAnnotation.CatchTarget) anno.targetInfo()).exceptionTableIndex();
case INSTANCEOF, NEW -> {
if (cAttr == null) throw new AssertionError("Invalid Annotation");
tad.offset = cAttr.labelToBci(((TypeAnnotation.OffsetTarget) anno.targetInfo()).target());
}
case LOCAL_VARIABLE, RESOURCE_VARIABLE -> {
if (cAttr == null) throw new AssertionError("Invalid Annotation");
TypeAnnotation.LocalVarTarget localTarget = (TypeAnnotation.LocalVarTarget) anno.targetInfo();
for (TypeAnnotation.LocalVarTargetInfo localInfo : localTarget.table()) {
tad.lvarIndex.add(localInfo.index());
tad.lvarOffset.add(cAttr.labelToBci(localInfo.startLabel()));
tad.lvarLength.add(cAttr.labelToBci(localInfo.endLabel()) - cAttr.labelToBci(localInfo.startLabel()));
}
}
case METHOD_FORMAL_PARAMETER -> tad.paramIndex = ((TypeAnnotation.FormalParameterTarget) anno.targetInfo()).formalParameterIndex();
case THROWS -> tad.typeIndex = ((TypeAnnotation.ThrowsTarget) anno.targetInfo()).throwsTargetIndex();
default -> {}
}
for (TypeAnnotation.TypePathComponent pathComponent : anno.targetPath()) {
switch (pathComponent.typePathKind()) {
case ARRAY -> tad.genericLocation.add(0);
case INNER_TYPE -> tad.genericLocation.add(1);
case WILDCARD -> tad.genericLocation.add(2);
case TYPE_ARGUMENT -> tad.genericLocation.add(3);
}
tad.genericLocation.add(pathComponent.typeArgumentIndex());
}
result.add(tad);
}
return result;
} }
/////////////////////// Equality testing ///////////////////// /////////////////////// Equality testing /////////////////////
@ -124,84 +148,98 @@ public class ReferenceInfoUtil {
return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE; return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE;
} }
private static boolean areEquals(int[] a, int[] a2) { private static boolean areEquals(List<Integer> a, List<Integer> a2) {
if (a==a2) if (a==a2)
return true; return true;
if (a==null || a2==null) if (a==null || a2==null)
return false; return false;
int length = a.length; int length = a.size();
if (a2.length != length) if (a2.size() != length)
return false; return false;
for (int i=0; i<length; i++) for (int i=0; i<length; i++)
if (a[i] != a2[i] && a[i] != IGNORE_VALUE && a2[i] != IGNORE_VALUE) if (!Objects.equals(a.get(i), a2.get(i)) && a.get(i) != IGNORE_VALUE && a2.get(i) != IGNORE_VALUE)
return false; return false;
return true; return true;
} }
public static boolean areEquals(TypeAnnotation.Position p1, TypeAnnotation.Position p2) { public static boolean areEquals(TAD p1, TAD p2) {
return p1 == p2 || !(p1 == null || p2 == null) && return p1 == p2 || !(p1 == null || p2 == null) &&
p1.type == p2.type && p1.type == p2.type &&
(p1.location.equals(p2.location)) && areEquals(p1.genericLocation, p2.genericLocation) &&
areEquals(p1.offset, p2.offset) && areEquals(p1.offset, p2.offset) &&
areEquals(p1.lvarOffset, p2.lvarOffset) && areEquals(p1.lvarOffset, p2.lvarOffset) &&
areEquals(p1.lvarLength, p2.lvarLength) && areEquals(p1.lvarLength, p2.lvarLength) &&
areEquals(p1.lvarIndex, p2.lvarIndex) && areEquals(p1.lvarIndex, p2.lvarIndex) &&
areEquals(p1.bound_index, p2.bound_index) && areEquals(p1.boundIndex, p2.boundIndex) &&
areEquals(p1.parameter_index, p2.parameter_index) && areEquals(p1.paramIndex, p2.paramIndex) &&
areEquals(p1.type_index, p2.type_index) && areEquals(p1.typeIndex, p2.typeIndex) &&
areEquals(p1.exception_index, p2.exception_index); areEquals(p1.exceptionIndex, p2.exceptionIndex);
} }
private static TypeAnnotation findAnnotation(String name, List<TypeAnnotation> annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { private static TAD findAnnotation(String name, List<TAD> annotations) {
String properName = "L" + name + ";"; String properName = "L" + name + ";";
for (TypeAnnotation anno : annotations) { for (TAD anno : annotations) {
String actualName = cf.constant_pool.getUTF8Value(anno.annotation.type_index); String actualName = anno.annotation;
if (properName.equals(actualName)) if (properName.equals(actualName))
return anno; return anno;
} }
return null; return null;
} }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, public static boolean compare(Map<String, TAD> expectedAnnos,
List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { List<TAD> actualAnnos) {
if (actualAnnos.size() != expectedAnnos.size()) { if (actualAnnos.size() != expectedAnnos.size()) {
throw new ComparisionException("Wrong number of annotations", throw new ComparisionException("Wrong number of annotations",
expectedAnnos, expectedAnnos,
actualAnnos); actualAnnos);
} }
for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { for (Map.Entry<String, TAD> expectedAno : expectedAnnos.entrySet()) {
String aName = e.getKey(); String aName = expectedAno.getKey();
TypeAnnotation.Position expected = e.getValue(); TAD expectedTAD = expectedAno.getValue();
TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); TAD actualTAD = findAnnotation(aName, actualAnnos);
if (actual == null) if (actualTAD == null)
throw new ComparisionException("Expected annotation not found: " + aName); throw new ComparisionException("Expected annotation not found: " + aName);
if (!areEquals(expected, actual.position)) { if (!areEquals(expectedTAD, actualTAD)) {
throw new ComparisionException("Unexpected position for annotation : " + aName + throw new ComparisionException("Unexpected position for annotation : " + aName +
"\n Expected: " + expected.toString() + "\n Expected: " + expectedTAD +
"\n Found: " + actual.position.toString()); "\n Found: " + actualTAD);
} }
} }
return true; return true;
} }
public static class TAD {
String annotation;
TypeAnnotation.TargetType type;
int typeIndex = IGNORE_VALUE, paramIndex = IGNORE_VALUE, boundIndex = IGNORE_VALUE, exceptionIndex = IGNORE_VALUE, offset = IGNORE_VALUE;
List<Integer> lvarOffset = new ArrayList<>(), lvarLength = new ArrayList<>(), lvarIndex = new ArrayList<>(), genericLocation = new ArrayList<>();
public TAD(String a, TypeAnnotation.TargetType t, int tIdx, int pIndx, int bIdx, int eIdx,
int ofs, List<Integer> lvarOfs, List<Integer> lvarLen, List<Integer> lvarIdx, List<Integer> genericLoc) {
annotation = a; type = t; typeIndex = tIdx;
paramIndex = pIndx; boundIndex = bIdx; exceptionIndex = eIdx;
offset = ofs; lvarOffset = lvarOfs; lvarLength = lvarLen; lvarIndex = lvarIdx;
genericLocation = genericLoc;
}
public TAD() {}
}
} }
class ComparisionException extends RuntimeException { class ComparisionException extends RuntimeException {
private static final long serialVersionUID = -3930499712333815821L; private static final long serialVersionUID = -3930499712333815821L;
public final Map<String, TypeAnnotation.Position> expected; public final Map<String, ReferenceInfoUtil.TAD> expected;
public final List<TypeAnnotation> found; public final List<ReferenceInfoUtil.TAD> found;
public ComparisionException(String message) { public ComparisionException(String message) {
this(message, null, null); this(message, null, null);
} }
public ComparisionException(String message, Map<String, TypeAnnotation.Position> expected, List<TypeAnnotation> found) { public ComparisionException(String message, Map<String, ReferenceInfoUtil.TAD> expected, List<ReferenceInfoUtil.TAD> found) {
super(message); super(message);
this.expected = expected; this.expected = expected;
this.found = found; this.found = found;

View File

@ -21,12 +21,17 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @summary Test population of reference info for repeating type annotations * @summary Test population of reference info for repeating 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
* @compile -g Driver.java ReferenceInfoUtil.java RepeatingTypeAnnotations.java * @compile -g Driver.java ReferenceInfoUtil.java RepeatingTypeAnnotations.java
* @run main Driver RepeatingTypeAnnotations * @run main Driver RepeatingTypeAnnotations
* @author Werner Dietl * @author Werner Dietl

View File

@ -25,12 +25,17 @@
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for resource variable * @summary Test population of reference info for resource variable
* @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 Driver.java ReferenceInfoUtil.java ResourceVariable.java * @compile -g Driver.java ReferenceInfoUtil.java ResourceVariable.java
* @run main Driver ResourceVariable * @run main Driver ResourceVariable
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.RESOURCE_VARIABLE; import static jdk.internal.classfile.TypeAnnotation.TargetType.RESOURCE_VARIABLE;
import static java.lang.System.lineSeparator; import static java.lang.System.lineSeparator;
public class ResourceVariable { public class ResourceVariable {

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for type casts * @summary Test population of reference info for type casts
* @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 Driver.java ReferenceInfoUtil.java TypeCasts.java * @compile -g Driver.java ReferenceInfoUtil.java TypeCasts.java
* @run main Driver TypeCasts * @run main Driver TypeCasts
*/ */

View File

@ -21,13 +21,18 @@
* questions. * questions.
*/ */
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/* /*
* @test * @test
* @bug 8042451 * @bug 8042451
* @summary Test population of reference info for class literals * @summary Test population of reference info for class literals
* @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 Driver.java ReferenceInfoUtil.java TypeTests.java * @compile -g Driver.java ReferenceInfoUtil.java TypeTests.java
* @run main Driver TypeTests * @run main Driver TypeTests
*/ */

View File

@ -29,7 +29,12 @@
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile * 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 * @build toolbox.ToolBox toolbox.JavacTask
* @run main DuplicatedCheckcastTest * @run main DuplicatedCheckcastTest
*/ */
@ -37,12 +42,10 @@
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Method; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.constantpool.ClassEntry;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.instruction.*;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.TestRunner; import toolbox.TestRunner;
@ -50,7 +53,7 @@ import toolbox.ToolBox;
public class DuplicatedCheckcastTest extends TestRunner { public class DuplicatedCheckcastTest extends TestRunner {
ToolBox tb; ToolBox tb;
ClassFile cf; ClassModel cf;
public DuplicatedCheckcastTest() { public DuplicatedCheckcastTest() {
super(System.err); super(System.err);
@ -97,13 +100,13 @@ public class DuplicatedCheckcastTest extends TestRunner {
.sources(source) .sources(source)
.outdir(curPath) .outdir(curPath)
.run(); .run();
cf = ClassFile.read(curPath.resolve("IntersectionTypeTest.class")); cf = Classfile.of().parse(curPath.resolve("IntersectionTypeTest.class"));
ArrayList<Instruction> checkCastList = new ArrayList<>(); ArrayList<Instruction> checkCastList = new ArrayList<>();
for (Method method : cf.methods) { for (MethodModel method : cf.methods()) {
if ("test".equals(method.getName(cf.constant_pool))) { if (method.methodName().equalsString("test")) {
Code_attribute code_attribute = (Code_attribute) method.attributes.get(Attribute.Code); CodeAttribute code_attribute = method.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction instruction : code_attribute.getInstructions()) { for (CodeElement ce : code_attribute.elementList()) {
if ("checkcast".equals(instruction.getMnemonic())) { if (ce instanceof Instruction instruction && Opcode.CHECKCAST == instruction.opcode()) {
checkCastList.add(instruction); checkCastList.add(instruction);
} }
} }
@ -117,10 +120,12 @@ public class DuplicatedCheckcastTest extends TestRunner {
checkClassName(checkCastList.get(1), expected2); checkClassName(checkCastList.get(1), expected2);
} }
public void checkClassName(Instruction ins, String expected) throws Exception { public void checkClassName(Instruction ins, String expected) {
int classIndex = ins.getUnsignedShort(1); String className = "";
CONSTANT_Class_info classInfo = cf.constant_pool.getClassInfo(classIndex); if (ins instanceof TypeCheckInstruction typeCheckInstruction) {
String className = classInfo.getName(); ClassEntry classInfo = typeCheckInstruction.type();
className = classInfo.asInternalName();
}
if (!expected.equals(className)) { if (!expected.equals(className)) {
throw new AssertionError("The type of the 'checkcast' is not right. Expected: " + throw new AssertionError("The type of the 'checkcast' is not right. Expected: " +
expected + ", actual: " + className); expected + ", actual: " + className);

View File

@ -25,45 +25,48 @@
* @bug 8034854 * @bug 8034854
* @summary Verify that the InnerClasses attribute has outer_class_info_index zero if it has * @summary Verify that the InnerClasses attribute has outer_class_info_index zero if it has
* inner_name_index zero (for synthetic classes) * inner_name_index zero (for synthetic 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
* java.base/jdk.internal.classfile.impl
* @compile SyntheticClasses.java * @compile SyntheticClasses.java
* @run main SyntheticClasses * @run main SyntheticClasses
*/ */
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
public class SyntheticClasses { public class SyntheticClasses {
public static void main(String[] args) throws IOException, ConstantPoolException { public static void main(String[] args) throws IOException {
new SyntheticClasses().run(); new SyntheticClasses().run();
} }
private void run() throws IOException, ConstantPoolException { private void run() throws IOException {
File testClasses = new File(System.getProperty("test.classes")); File testClasses = new File(System.getProperty("test.classes"));
for (File classFile : testClasses.listFiles(f -> f.getName().endsWith(".class"))) { for (File classFile : Objects.requireNonNull(testClasses.listFiles(f -> f.getName().endsWith(".class")))) {
ClassFile cf = ClassFile.read(classFile); ClassModel cf = Classfile.of().parse(classFile.toPath());
if (cf.getName().matches(".*\\$[0-9]+")) { if (cf.thisClass().asInternalName().matches(".*\\$[0-9]+")) {
EnclosingMethod_attribute encl = EnclosingMethodAttribute encl = cf.findAttribute(Attributes.ENCLOSING_METHOD).orElse(null);
(EnclosingMethod_attribute) cf.getAttribute(Attribute.EnclosingMethod);
if (encl != null) { if (encl != null) {
if (encl.method_index != 0) if (encl.enclosingMethodName().isPresent())
throw new IllegalStateException("Invalid EnclosingMethod.method_index: " + throw new IllegalStateException("Invalid EnclosingMethod.method: " +
encl.method_index + "."); encl.enclosingMethodName().get().stringValue() + ".");
} }
} }
InnerClasses_attribute attr = InnerClassesAttribute attr = cf.findAttribute(Attributes.INNER_CLASSES).orElse(null);
(InnerClasses_attribute) cf.getAttribute(Attribute.InnerClasses);
if (attr != null) { if (attr != null) {
for (InnerClasses_attribute.Info info : attr.classes) { for (InnerClassInfo info : attr.classes()) {
if (cf.major_version < 51) if (cf.majorVersion() < 51)
throw new IllegalStateException(); throw new IllegalStateException();
if (info.inner_name_index == 0 && info.outer_class_info_index != 0) if (info.innerName().isEmpty() && info.outerClass().isPresent() )
throw new IllegalStateException("Invalid outer_class_info_index=" + throw new IllegalStateException("Invalid outer_class_info: " +
info.outer_class_info_index + info.outerClass().get().asInternalName() +
"; inner_name_index=" + "; inner_name is empty");
info.inner_name_index + ".");
} }
} }
} }

View File

@ -28,16 +28,20 @@
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile * 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 * @build toolbox.ToolBox toolbox.JavacTask
* @run main T8255757 * @run main T8255757
*/ */
import java.nio.file.Path; import java.nio.file.Path;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.ConstantPool.*;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.ToolBox; import toolbox.ToolBox;
@ -75,22 +79,17 @@ public class T8255757 extends TestRunner {
.outdir(curPath) .outdir(curPath)
.run(); .run();
ClassFile cf = ClassFile.read(curPath.resolve("Test.class")); ClassModel cf = Classfile.of().parse(curPath.resolve("Test.class"));
ConstantPool cp = cf.constant_pool; ConstantPool cp = cf.constantPool();
int num = 0; int num = 0;
for (CPInfo cpInfo : cp.entries()) { for (int i = 1; i < cp.entryCount(); i += cp.entryByIndex(i).width()) {
if (cpInfo instanceof CONSTANT_Methodref_info) { if (cp.entryByIndex(i) instanceof MethodRefEntry methodRefEntry) {
int class_index = ((CONSTANT_Methodref_info) cpInfo).class_index; String class_name = methodRefEntry.owner().asInternalName();
int name_and_type_index = ((CONSTANT_Methodref_info) cpInfo).name_and_type_index; String method_name = methodRefEntry.name().stringValue();
int class_name_index = ((CONSTANT_Class_info) String method_type = methodRefEntry.type().stringValue();
cp.getClassInfo(class_index)).name_index; if ("[Ljava/lang/Object;".equals(class_name) &&
int method_name_index = ((CONSTANT_NameAndType_info) "clone".equals(method_name) &&
cp.getNameAndTypeInfo(name_and_type_index)).name_index; "()Ljava/lang/Object;".equals(method_type)) {
int method_type_name_index = ((CONSTANT_NameAndType_info)
cp.getNameAndTypeInfo(name_and_type_index)).type_index;
if ("[Ljava/lang/Object;".equals(cp.getUTF8Value(class_name_index)) &&
"clone".equals(cp.getUTF8Value(method_name_index)) &&
"()Ljava/lang/Object;".equals(cp.getUTF8Value(method_type_name_index))) {
++num; ++num;
} }
} }

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8171132 * @bug 8171132
* @summary Improve class reading of invalid or out-of-range ConstantValue attributes * @summary Improve class reading of invalid or out-of-range ConstantValue attributes
* @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.api
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.jvm * jdk.compiler/com.sun.tools.javac.jvm
@ -35,9 +40,7 @@
* @run main BadConstantValue * @run main BadConstantValue
*/ */
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassWriter;
import com.sun.tools.classfile.Field;
import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.ClassFinder.BadClassFile;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
@ -45,11 +48,8 @@ import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import java.io.File; import java.io.*;
import java.io.FileWriter; import java.nio.file.Files;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
@ -185,16 +185,17 @@ public class BadConstantValue {
* B's type and A's ConstantValue attribute. * B's type and A's ConstantValue attribute.
*/ */
private static void swapConstantValues(File file) throws Exception { private static void swapConstantValues(File file) throws Exception {
ClassFile cf = ClassFile.read(file); ClassModel cf = Classfile.of().parse(file.toPath());
Field a = cf.fields[0]; FieldModel a = cf.fields().getFirst();
Field b = cf.fields[1]; FieldModel b = cf.fields().get(1);
Field[] fields = { byte[] Bytes = Classfile.of().transform(cf, ClassTransform
new Field(b.access_flags, b.name_index, b.descriptor, a.attributes), .dropping(ce -> ce instanceof ClassfileVersion || ce instanceof FieldModel)
}; .andThen(ClassTransform.endHandler(classBuilder -> classBuilder
cf = new ClassFile(cf.magic, Target.JDK1_7.minorVersion, Target.JDK1_7.majorVersion, .withField(b.fieldName(), b.fieldType(), fieldBuilder -> {
cf.constant_pool, cf.access_flags, cf.this_class, cf.super_class, cf.interfaces, fieldBuilder.withFlags(b.flags().flagsMask());
fields, cf.methods, cf.attributes); a.attributes().forEach(e -> fieldBuilder.with((FieldElement) e));})
new ClassWriter().write(cf, file); .withVersion(Target.JDK1_7.majorVersion, Target.JDK1_7.minorVersion))));
Files.write(file.toPath(), Bytes);
} }
static String compile(String... args) throws Exception { static String compile(String... args) throws Exception {

View File

@ -34,7 +34,12 @@
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util * 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
* jdk.jdeps/com.sun.tools.javap * jdk.jdeps/com.sun.tools.javap
* @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox
* @run main IndyCorrectInvocationName * @run main IndyCorrectInvocationName
@ -54,13 +59,10 @@ import com.sun.source.util.Plugin;
import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener; import com.sun.source.util.TaskListener;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.BootstrapMethods_attribute; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.instruction.*;
import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
@ -166,32 +168,30 @@ public class IndyCorrectInvocationName implements Plugin {
} }
Path testClass = classes.resolve("Test.class"); Path testClass = classes.resolve("Test.class");
ClassFile cf = ClassFile.read(testClass); ClassModel cf = Classfile.of().parse(testClass);
BootstrapMethods_attribute bootAttr = BootstrapMethodsAttribute bootAttr = cf.findAttribute(Attributes.BOOTSTRAP_METHODS).orElseThrow();
(BootstrapMethods_attribute) cf.attributes.get(Attribute.BootstrapMethods); if (bootAttr.bootstrapMethodsSize() != 1) {
if (bootAttr.bootstrap_method_specifiers.length != 1) {
throw new AssertionError("Incorrect number of bootstrap methods: " + throw new AssertionError("Incorrect number of bootstrap methods: " +
bootAttr.bootstrap_method_specifiers.length); bootAttr.bootstrapMethodsSize());
} }
Code_attribute codeAttr = CodeAttribute codeAttr = cf.methods().get(1).findAttribute(Attributes.CODE).orElseThrow();
(Code_attribute) cf.methods[1].attributes.get(Attribute.Code); Set<BootstrapMethodEntry> seenBootstraps = new HashSet<>();
Set<Integer> seenBootstraps = new HashSet<>(); Set<NameAndTypeEntry> seenNameAndTypes = new HashSet<>();
Set<Integer> seenNameAndTypes = new HashSet<>();
Set<String> seenNames = new HashSet<>(); Set<String> seenNames = new HashSet<>();
for (Instruction i : codeAttr.getInstructions()) { for (CodeElement i : codeAttr.elementList()) {
switch (i.getOpcode()) { if (i instanceof Instruction instruction) {
case INVOKEDYNAMIC -> { switch (instruction ) {
int idx = i.getUnsignedShort(1); case InvokeDynamicInstruction indy -> {
CONSTANT_InvokeDynamic_info dynamicInfo = InvokeDynamicEntry dynamicInfo = indy.invokedynamic();
(CONSTANT_InvokeDynamic_info) cf.constant_pool.get(idx); seenBootstraps.add(dynamicInfo.bootstrap());
seenBootstraps.add(dynamicInfo.bootstrap_method_attr_index); seenNameAndTypes.add(dynamicInfo.nameAndType());
seenNameAndTypes.add(dynamicInfo.name_and_type_index); NameAndTypeEntry nameAndTypeInfo = dynamicInfo.nameAndType();
CONSTANT_NameAndType_info nameAndTypeInfo = seenNames.add(nameAndTypeInfo.name().stringValue());
cf.constant_pool.getNameAndTypeInfo(dynamicInfo.name_and_type_index); }
seenNames.add(nameAndTypeInfo.getName()); case ReturnInstruction returnInstruction -> {
}
default -> throw new AssertionError("Unexpected instruction: " + instruction.opcode());
} }
case RETURN -> {}
default -> throw new AssertionError("Unexpected instruction: " + i.getOpcode());
} }
} }
if (seenBootstraps.size() != 1) { if (seenBootstraps.size() != 1) {

View File

@ -34,7 +34,12 @@
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.tree
* jdk.compiler/com.sun.tools.javac.util * 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
* jdk.jdeps/com.sun.tools.javap * jdk.jdeps/com.sun.tools.javap
* @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox
* @compile CharImmediateValue.java * @compile CharImmediateValue.java
@ -53,11 +58,8 @@ import com.sun.source.util.Plugin;
import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener; import com.sun.source.util.TaskListener;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Opcode;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCIdent;
@ -134,12 +136,11 @@ public class CharImmediateValue implements Plugin {
} }
Path testClass = classes.resolve("Test.class"); Path testClass = classes.resolve("Test.class");
ClassFile cf = ClassFile.read(testClass); ClassModel cf = Classfile.of().parse(testClass);
Code_attribute codeAttr = CodeAttribute codeAttr = cf.methods().get(1).findAttribute(Attributes.CODE).orElseThrow();
(Code_attribute) cf.methods[1].attributes.get(Attribute.Code);
boolean seenCast = false; boolean seenCast = false;
for (Instruction i : codeAttr.getInstructions()) { for (CodeElement i : codeAttr.elementList()) {
if (i.getOpcode() == Opcode.I2C) { if (i instanceof Instruction ins && ins.opcode() == Opcode.I2C) {
seenCast = true; seenCast = true;
} }
} }

View File

@ -26,7 +26,12 @@
* @bug 8025087 * @bug 8025087
* @summary Verify that pre-JDK8 classfiles with default and/or static methods * @summary Verify that pre-JDK8 classfiles with default and/or static methods
* are refused correctly. * are refused correctly.
* @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.api
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.comp
@ -37,7 +42,7 @@
* @run main BadClassfile * @run main BadClassfile
*/ */
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.ClassFinder.BadClassFile;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
@ -59,15 +64,9 @@ public class BadClassfile {
private static void test(String classname, String expected) throws Exception { private static void test(String classname, String expected) throws Exception {
File classfile = new File(System.getProperty("test.classes", "."), classname + ".class"); File classfile = new File(System.getProperty("test.classes", "."), classname + ".class");
ClassFile cf = ClassFile.read(classfile); ClassModel cf = Classfile.of().parse(classfile.toPath());
Classfile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof ClassfileVersion)
cf = new ClassFile(cf.magic, Target.JDK1_7.minorVersion, .andThen(ClassTransform.endHandler(classBuilder -> classBuilder.withVersion(Target.JDK1_7.majorVersion, Target.JDK1_7.minorVersion))));
Target.JDK1_7.majorVersion, cf.constant_pool, cf.access_flags,
cf.this_class, cf.super_class, cf.interfaces, cf.fields,
cf.methods, cf.attributes);
new ClassWriter().write(cf, classfile);
JavaCompiler c = ToolProvider.getSystemJavaCompiler(); JavaCompiler c = ToolProvider.getSystemJavaCompiler();
JavacTaskImpl task = (JavacTaskImpl) c.getTask(null, null, null, Arrays.asList("-classpath", System.getProperty("test.classes", ".")), null, null); JavacTaskImpl task = (JavacTaskImpl) c.getTask(null, null, null, Arrays.asList("-classpath", System.getProperty("test.classes", ".")), null, null);
Symtab syms = Symtab.instance(task.getContext()); Symtab syms = Symtab.instance(task.getContext());

View File

@ -25,23 +25,21 @@
* @test * @test
* @bug 8012723 * @bug 8012723
* @summary strictfp interface misses strictfp modifer on default method * @summary strictfp interface misses strictfp modifer on default 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
* @compile -source 16 -target 16 CheckACC_STRICTFlagOnDefaultMethodTest.java * @compile -source 16 -target 16 CheckACC_STRICTFlagOnDefaultMethodTest.java
* @run main CheckACC_STRICTFlagOnDefaultMethodTest * @run main CheckACC_STRICTFlagOnDefaultMethodTest
*/ */
import java.util.ArrayList; import jdk.internal.classfile.*;
import java.util.List;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import com.sun.tools.classfile.ClassFile; import java.util.List;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Method;
import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
public class CheckACC_STRICTFlagOnDefaultMethodTest { public class CheckACC_STRICTFlagOnDefaultMethodTest {
private static final String AssertionErrorMessage = private static final String AssertionErrorMessage =
@ -52,13 +50,11 @@ public class CheckACC_STRICTFlagOnDefaultMethodTest {
private List<String> errors = new ArrayList<>(); private List<String> errors = new ArrayList<>();
public static void main(String[] args) public static void main(String[] args) throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
new CheckACC_STRICTFlagOnDefaultMethodTest().run(); new CheckACC_STRICTFlagOnDefaultMethodTest().run();
} }
private void run() private void run() throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor {
String testClasses = System.getProperty("test.classes"); String testClasses = System.getProperty("test.classes");
check(testClasses, check(testClasses,
"CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class"); "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class");
@ -70,19 +66,15 @@ public class CheckACC_STRICTFlagOnDefaultMethodTest {
} }
} }
void check(String dir, String... fileNames) void check(String dir, String... fileNames) throws IOException {
throws
IOException,
ConstantPoolException,
Descriptor.InvalidDescriptor {
for (String fileName : fileNames) { for (String fileName : fileNames) {
ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); ClassModel classFileToCheck = Classfile.of().parse(new File(dir, fileName).toPath());
for (Method method : classFileToCheck.methods) { for (MethodModel method : classFileToCheck.methods()) {
if ((method.access_flags.flags & ACC_STRICT) == 0) { if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) {
errors.add(String.format(offendingMethodErrorMessage, errors.add(String.format(offendingMethodErrorMessage,
method.getName(classFileToCheck.constant_pool), method.methodName().stringValue(),
classFileToCheck.getName())); classFileToCheck.thisClass().asInternalName()));
} }
} }
} }

View File

@ -25,18 +25,18 @@
* @test * @test
* @bug 7192246 * @bug 7192246
* @summary check that code attributed for default methods is correctly generated * @summary check that code attributed for default methods is correctly generated
* @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.AccessFlags; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.constantpool.MemberRefEntry;
import com.sun.tools.classfile.ConstantPool.*; import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Opcode;
import java.io.*; import java.io.*;
public class TestDefaultBody { public class TestDefaultBody {
@ -67,12 +67,12 @@ public class TestDefaultBody {
void verifyDefaultBody(File f) { void verifyDefaultBody(File f) {
System.err.println("verify: " + f); System.err.println("verify: " + f);
try { try {
ClassFile cf = ClassFile.read(f); ClassModel cf = Classfile.of().parse(f.toPath());
Method testMethod = null; MethodModel testMethod = null;
Code_attribute codeAttr = null; CodeAttribute codeAttr = null;
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); codeAttr = m.findAttribute(Attributes.CODE).orElse(null);
String mname = m.getName(cf.constant_pool); String mname = m.methodName().stringValue();
if (mname.equals(TEST_METHOD_NAME)) { if (mname.equals(TEST_METHOD_NAME)) {
testMethod = m; testMethod = m;
break; break;
@ -83,7 +83,7 @@ public class TestDefaultBody {
if (testMethod == null) { if (testMethod == null) {
throw new Error("Test method not found"); throw new Error("Test method not found");
} }
if (testMethod.access_flags.is(AccessFlags.ACC_ABSTRACT)) { if ((testMethod.flags().flagsMask() & Classfile.ACC_ABSTRACT) != 0) {
throw new Error("Test method is abstract"); throw new Error("Test method is abstract");
} }
if (codeAttr == null) { if (codeAttr == null) {
@ -91,14 +91,13 @@ public class TestDefaultBody {
} }
boolean found = false; boolean found = false;
for (Instruction instr : codeAttr.getInstructions()) { for (CodeElement instr : codeAttr.elementList()) {
if (instr.getOpcode() == Opcode.INVOKESTATIC) { if (instr instanceof InvokeInstruction ins && ins.opcode() == Opcode.INVOKESTATIC) {
found = true; found = true;
int pc_index = instr.getShort(1); MemberRefEntry mref = ins.method();
CONSTANT_Methodref_info mref = (CONSTANT_Methodref_info)cf.constant_pool.get(pc_index); String className = mref.owner().asInternalName();
String className = mref.getClassName(); String targetName = mref.name().stringValue();
String targetName = mref.getNameAndTypeInfo().getName(); String targetType = mref.type().stringValue();
String targetType = mref.getNameAndTypeInfo().getType();
if (!className.equals(TARGET_CLASS_NAME)) { if (!className.equals(TARGET_CLASS_NAME)) {
throw new Error("unexpected class in default method body " + className); throw new Error("unexpected class in default method body " + className);

View File

@ -25,12 +25,15 @@
* @test * @test
* @bug 7192246 * @bug 7192246
* @summary check that javac does not generate bridge methods for defaults * @summary check that javac does not generate bridge methods for defaults
* @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.ClassFile; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.*;
import com.sun.tools.classfile.Method;
import java.io.*; import java.io.*;
@ -71,9 +74,9 @@ public class TestNoBridgeOnDefaults {
void checkNoBridgeOnDefaults(File f) { void checkNoBridgeOnDefaults(File f) {
System.err.println("check: " + f); System.err.println("check: " + f);
try { try {
ClassFile cf = ClassFile.read(f); ClassModel cf = Classfile.of().parse(f.toPath());
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
String mname = m.getName(cf.constant_pool); String mname = m.methodName().stringValue();
if (mname.equals(TEST_METHOD_NAME)) { if (mname.equals(TEST_METHOD_NAME)) {
throw new Error("unexpected bridge method found " + m); throw new Error("unexpected bridge method found " + m);
} }

View File

@ -25,19 +25,21 @@
* @test * @test
* @bug 8027281 * @bug 8027281
* @summary As per JVMS 4.9.2, invokespecial can only refer to direct superinterfaces * @summary As per JVMS 4.9.2, invokespecial can only refer to direct superinterfaces
* @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 TestDirectSuperInterfaceInvoke.java * @compile TestDirectSuperInterfaceInvoke.java
* @run main TestDirectSuperInterfaceInvoke * @run main TestDirectSuperInterfaceInvoke
*/ */
import java.io.File; import java.io.File;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.constantpool.MemberRefEntry;
import com.sun.tools.classfile.ConstantPool.CPRefInfo; import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Opcode;
interface BaseInterface { interface BaseInterface {
public default int testedMethod(){ return 1; } public default int testedMethod(){ return 1; }
@ -86,14 +88,13 @@ public class TestDirectSuperInterfaceInvoke {
String workDir = System.getProperty("test.classes"); String workDir = System.getProperty("test.classes");
File file = new File(workDir, classFile); File file = new File(workDir, classFile);
try { try {
final ClassFile cf = ClassFile.read(file); final ClassModel cf = Classfile.of().parse(file.toPath());
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction instr : codeAttr.getInstructions()) { for (CodeElement ce : codeAttr.elementList()) {
if (instr.getOpcode() == Opcode.INVOKESPECIAL) { if (ce instanceof InvokeInstruction instr && instr.opcode() == Opcode.INVOKESPECIAL) {
int pc_index = instr.getShort(1); MemberRefEntry ref = instr.method();
CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index); String className = ref.owner().asInternalName();
String className = ref.getClassName();
if (className.equals("BaseInterface")) if (className.equals("BaseInterface"))
throw new IllegalStateException("Must not directly refer to TestedInterface"); throw new IllegalStateException("Must not directly refer to TestedInterface");
} }

View File

@ -27,14 +27,20 @@
* @summary need test program to validate javac resource bundles * @summary need test program to validate javac resource bundles
* @modules jdk.compiler/com.sun.tools.javac.code * @modules jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.resources:open * jdk.compiler/com.sun.tools.javac.resources:open
* 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
*/ */
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.regex.*; import java.util.regex.*;
import javax.tools.*; import javax.tools.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.constantpool.*;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
/** /**
@ -490,10 +496,10 @@ public class CheckResourceKeys {
*/ */
void scan(JavaFileObject fo, Set<String> results) throws IOException { void scan(JavaFileObject fo, Set<String> results) throws IOException {
try (InputStream in = fo.openInputStream()) { try (InputStream in = fo.openInputStream()) {
ClassFile cf = ClassFile.read(in); ClassModel cm = Classfile.of().parse(in.readAllBytes());
for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) { for (int i = 1; i < cm.constantPool().entryCount(); ++i) {
if (cpinfo.getTag() == ConstantPool.CONSTANT_Utf8) { if (cm.constantPool().entryByIndex(i) instanceof Utf8Entry entry) {
String v = ((ConstantPool.CONSTANT_Utf8_info) cpinfo).value; String v = entry.stringValue();
if (v.matches("[A-Za-z0-9-_.]+")) if (v.matches("[A-Za-z0-9-_.]+"))
results.add(v); results.add(v);
} }

View File

@ -297,8 +297,12 @@ class Example implements Comparable<Example> {
// source for import statements or a magic comment // source for import statements or a magic comment
for (File pf: procFiles) { for (File pf: procFiles) {
if (pf.getName().equals("CreateBadClassFile.java")) { if (pf.getName().equals("CreateBadClassFile.java")) {
pOpts.add("--add-modules=jdk.jdeps"); pOpts.add("--add-exports=java.base/jdk.internal.classfile=ALL-UNNAMED");
pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED"); pOpts.add("--add-exports=java.base/jdk.internal.classfile.attribute=ALL-UNNAMED");
pOpts.add("--add-exports=java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED");
pOpts.add("--add-exports=java.base/jdk.internal.classfile.instruction=ALL-UNNAMED");
pOpts.add("--add-exports=java.base/jdk.internal.classfile.components=ALL-UNNAMED");
pOpts.add("--add-exports=java.base/jdk.internal.classfile.impl=ALL-UNNAMED");
} }
} }

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header // key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access // key: compiler.err.cant.access
// options: -processor CreateBadClassFile // options: -processor CreateBadClassFile
// run: exec --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED // run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED
/* The annotation processor will create an invalid classfile with a static /* The annotation processor will create an invalid classfile with a static
* final field of type java.lang.Object having ConstantValue attribute with * final field of type java.lang.Object having ConstantValue attribute with

View File

@ -22,16 +22,19 @@
*/ */
import java.io.*; import java.io.*;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.util.*; import java.util.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.*; import javax.lang.model.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.*; import javax.tools.*;
import java.lang.reflect.AccessFlag;
import com.sun.tools.classfile.*; import jdk.internal.classfile.Classfile;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; import jdk.internal.classfile.attribute.ConstantValueAttribute;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
/* Create an invalid classfile with a static final field of type object with /* Create an invalid classfile with a static final field of type object with
* ConstantValue of type String. * ConstantValue of type String.
@ -40,42 +43,21 @@ import com.sun.tools.classfile.ConstantPool.CPInfo;
public class CreateBadClassFile extends AbstractProcessor { public class CreateBadClassFile extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) { public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
if (++round == 1) { if (++round == 1) {
ConstantPool cp = new ConstantPool(new CPInfo[] { byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), cb -> {
new CONSTANT_Utf8_info(""), //0 cb.withSuperclass(ConstantDescs.CD_Object);
new CONSTANT_Utf8_info("Test"), //1 cb.withVersion(51, 0);
new CONSTANT_Class_info(null, 1), //2 cb.withFlags(AccessFlag.ABSTRACT ,
new CONSTANT_Utf8_info("java/lang/Object"), //3 AccessFlag.INTERFACE ,
new CONSTANT_Class_info(null, 3), //4 AccessFlag.PUBLIC);
new CONSTANT_Utf8_info("test"), //5 cb.withField("test", ConstantDescs.CD_Object, fieldBuilder -> {
new CONSTANT_Utf8_info("Ljava/lang/Object;"), //6 fieldBuilder.withFlags(AccessFlag.PUBLIC, AccessFlag.STATIC, AccessFlag.FINAL);
new CONSTANT_Utf8_info("ConstantValue"), //7 fieldBuilder.with(ConstantValueAttribute.of("ConstantValue"));
});
}); });
ClassFile cf = new ClassFile(0xCAFEBABE,
0,
51,
cp,
new AccessFlags(AccessFlags.ACC_ABSTRACT |
AccessFlags.ACC_INTERFACE |
AccessFlags.ACC_PUBLIC),
2,
4,
new int[0],
new Field[] {
new Field(new AccessFlags(AccessFlags.ACC_PUBLIC |
AccessFlags.ACC_STATIC |
AccessFlags.ACC_FINAL),
5,
new Descriptor(6),
new Attributes(cp, new Attribute[] {
new ConstantValue_attribute(7, 6)
}))
},
new Method[0],
new Attributes(cp, new Attribute[0]));
try { try {
JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test");
try (OutputStream out = clazz.openOutputStream()) { try (OutputStream out = clazz.openOutputStream()) {
new ClassWriter().write(cf, out); out.write(bytes);
} }
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header // key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access // key: compiler.err.cant.access
// options: -processor CreateBadClassFile // options: -processor CreateBadClassFile
// run: exec --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED // run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED
/* The annotation processor will create an invalid classfile with version 51.0 /* The annotation processor will create an invalid classfile with version 51.0
* and a non-abstract method in an interface. Loading the classfile will produce * and a non-abstract method in an interface. Loading the classfile will produce

View File

@ -22,54 +22,35 @@
*/ */
import java.io.*; import java.io.*;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.util.*; import java.util.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.*; import javax.lang.model.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.*; import javax.tools.*;
import java.lang.reflect.AccessFlag;
import com.sun.tools.classfile.*; import jdk.internal.classfile.Classfile;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
/* Create an invalid classfile with version 51.0 and a non-abstract method in an interface.*/ /* Create an invalid classfile with version 51.0 and a non-abstract method in an interface.*/
@SupportedAnnotationTypes("*") @SupportedAnnotationTypes("*")
public class CreateBadClassFile extends AbstractProcessor { public class CreateBadClassFile extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) { public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
if (++round == 1) { if (++round == 1) {
ConstantPool cp = new ConstantPool(new CPInfo[] { byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), classBuilder -> {
new CONSTANT_Utf8_info(""), //0 classBuilder.withVersion(51, 0);
new CONSTANT_Utf8_info("Test"), //1 classBuilder.withFlags(AccessFlag.ABSTRACT ,
new CONSTANT_Class_info(null, 1), //2 AccessFlag.INTERFACE ,
new CONSTANT_Utf8_info("java/lang/Object"), //3 AccessFlag.PUBLIC);
new CONSTANT_Class_info(null, 3), //4 classBuilder.withMethod("test", MethodTypeDesc.of(ConstantDescs.CD_void), Classfile.ACC_PUBLIC, methodBuilder -> {
new CONSTANT_Utf8_info("test"), //5 methodBuilder.withFlags(AccessFlag.PUBLIC);});
new CONSTANT_Utf8_info("()V"), //6
}); });
ClassFile cf = new ClassFile(0xCAFEBABE,
0,
51,
cp,
new AccessFlags(AccessFlags.ACC_ABSTRACT |
AccessFlags.ACC_INTERFACE |
AccessFlags.ACC_PUBLIC),
2,
4,
new int[0],
new Field[0],
new Method[] {
//creating non-abstract method in 51.0 classfile:
new Method(new AccessFlags(AccessFlags.ACC_PUBLIC),
5,
new Descriptor(6),
new Attributes(cp, new Attribute[0]))
},
new Attributes(cp, new Attribute[0]));
try { try {
JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test");
try (OutputStream out = clazz.openOutputStream()) { try (OutputStream out = clazz.openOutputStream()) {
new ClassWriter().write(cf, out); out.write(bytes);
} }
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header // key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access // key: compiler.err.cant.access
// options: -processor CreateBadClassFile // options: -processor CreateBadClassFile
// run: exec --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED // run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED
/* The annotation processor will create an invalid classfile with version 51.0 /* The annotation processor will create an invalid classfile with version 51.0
* and a static method in an interface. Loading the classfile will produce * and a static method in an interface. Loading the classfile will produce

View File

@ -22,55 +22,40 @@
*/ */
import java.io.*; import java.io.*;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc;
import java.util.*; import java.util.*;
import javax.annotation.processing.*; import javax.annotation.processing.*;
import javax.lang.model.*; import javax.lang.model.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.*; import javax.tools.*;
import com.sun.tools.classfile.*; import java.lang.reflect.AccessFlag;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; import jdk.internal.classfile.Classfile;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
/* Create an invalid classfile with version 51.0 and a static method in an interface.*/ /* Create an invalid classfile with version 51.0 and a static method in an interface.*/
@SupportedAnnotationTypes("*") @SupportedAnnotationTypes("*")
public class CreateBadClassFile extends AbstractProcessor { public class CreateBadClassFile extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) { public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
if (++round == 1) { if (++round == 1) {
ConstantPool cp = new ConstantPool(new CPInfo[] { byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), classBuilder -> {
new CONSTANT_Utf8_info(""), //0 classBuilder.withVersion(51, 0);
new CONSTANT_Utf8_info("Test"), //1 classBuilder.withFlags(AccessFlag.ABSTRACT,
new CONSTANT_Class_info(null, 1), //2 AccessFlag.INTERFACE,
new CONSTANT_Utf8_info("java/lang/Object"), //3 AccessFlag.PUBLIC);
new CONSTANT_Class_info(null, 3), //4 classBuilder.withSuperclass(ConstantDescs.CD_Object);
new CONSTANT_Utf8_info("test"), //5 classBuilder.withMethod("test", ConstantDescs.MTD_void,
new CONSTANT_Utf8_info("()V"), //6 Classfile.ACC_PUBLIC | Classfile.ACC_STATIC, methodBuilder -> {
methodBuilder.withCode(xb -> {
xb.return_();
});
});
}); });
ClassFile cf = new ClassFile(0xCAFEBABE,
0,
51,
cp,
new AccessFlags(AccessFlags.ACC_ABSTRACT |
AccessFlags.ACC_INTERFACE |
AccessFlags.ACC_PUBLIC),
2,
4,
new int[0],
new Field[0],
new Method[] {
//creating static method in 51.0 classfile:
new Method(new AccessFlags(AccessFlags.ACC_PUBLIC |
AccessFlags.ACC_STATIC),
5,
new Descriptor(6),
new Attributes(cp, new Attribute[0]))
},
new Attributes(cp, new Attribute[0]));
try { try {
JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test");
try (OutputStream out = clazz.openOutputStream()) { try (OutputStream out = clazz.openOutputStream()) {
new ClassWriter().write(cf, out); out.write(bytes);
} }
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();

View File

@ -26,7 +26,12 @@
* @bug 8027789 * @bug 8027789
* @summary check that the direct superclass is used as the site when calling * @summary check that the direct superclass is used as the site when calling
* a superclass' method * a superclass' 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
* @compile Base.java NonDirectSuper.java * @compile Base.java NonDirectSuper.java
* @run main test.NonDirectSuper * @run main test.NonDirectSuper
*/ */
@ -35,13 +40,11 @@ package test;
import java.io.File; import java.io.File;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.CodeAttribute;
import com.sun.tools.classfile.Code_attribute; import jdk.internal.classfile.constantpool.MemberRefEntry;
import com.sun.tools.classfile.ConstantPool.CPRefInfo; import jdk.internal.classfile.instruction.FieldInstruction;
import com.sun.tools.classfile.Instruction; import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Opcode;
public class NonDirectSuper { public class NonDirectSuper {
public static void main(String... args) { public static void main(String... args) {
@ -60,16 +63,15 @@ public class NonDirectSuper {
void verifyInvokeSpecialRefToObject(File clazz) { void verifyInvokeSpecialRefToObject(File clazz) {
try { try {
final ClassFile cf = ClassFile.read(clazz); final ClassModel cf = Classfile.of().parse(clazz.toPath());
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow();
for (Instruction instr : codeAttr.getInstructions()) { for (CodeElement ce : codeAttr.elementList()) {
if (instr.getOpcode() == Opcode.INVOKESPECIAL || if (ce instanceof InvokeInstruction instr && (instr.opcode() == Opcode.INVOKESPECIAL ||
instr.getOpcode() == Opcode.INVOKEVIRTUAL) { instr.opcode() == Opcode.INVOKEVIRTUAL)) {
int pc_index = instr.getShort(1); MemberRefEntry ref = instr.method();
CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index); String className = ref.owner().asInternalName();
String className = ref.getClassName(); String methodName = ref.name().stringValue();
String methodName = ref.getNameAndTypeInfo().getName();
if (methodName.equals("toString")) { if (methodName.equals("toString")) {
if (!className.equals("java/lang/Object")) if (!className.equals("java/lang/Object"))
throw new IllegalStateException("Must directly refer to j.l.Object"); throw new IllegalStateException("Must directly refer to j.l.Object");
@ -81,12 +83,10 @@ public class NonDirectSuper {
} }
} }
} }
if (instr.getOpcode() == Opcode.GETFIELD || if (ce instanceof FieldInstruction instr && (instr.opcode() == Opcode.GETFIELD ||
instr.getOpcode() == Opcode.PUTFIELD) { instr.opcode() == Opcode.PUTFIELD)) {
int pc_index = instr.getShort(1); String className = instr.owner().asInternalName();
CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index); String fieldName = instr.field().name().stringValue();
String className = ref.getClassName();
String fieldName = ref.getNameAndTypeInfo().getName();
if (fieldName.startsWith("refTo")) { if (fieldName.startsWith("refTo")) {
String expectedClass = fieldName.substring("refTo".length()); String expectedClass = fieldName.substring("refTo".length());
if (!className.replace("/", "").equals(expectedClass)) { if (!className.replace("/", "").equals(expectedClass)) {

View File

@ -28,7 +28,12 @@
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile * 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.JavacTask toolbox.TestRunner toolbox.ToolBox * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
* @run main SymLinkArchiveTest * @run main SymLinkArchiveTest
*/ */

View File

@ -28,7 +28,12 @@
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile * 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.JavacTask toolbox.TestRunner toolbox.ToolBox * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
* @run main SymLinkShortNameTest * @run main SymLinkShortNameTest
*/ */

View File

@ -30,7 +30,12 @@
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile * 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.JavacTask toolbox.TestRunner toolbox.ToolBox * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
* @run main SymLinkTest * @run main SymLinkTest
*/ */
@ -40,9 +45,8 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.SourceFileAttribute;
import com.sun.tools.classfile.SourceFile_attribute;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.TestRunner; import toolbox.TestRunner;
import toolbox.TestRunner.Test; import toolbox.TestRunner.Test;
@ -94,9 +98,9 @@ public class SymLinkTest extends TestRunner {
.run() .run()
.writeAll(); .writeAll();
ClassFile cf = ClassFile.read(classes.resolve("HelloWorld.class")); ClassModel cf = Classfile.of().parse(classes.resolve("HelloWorld.class"));
SourceFile_attribute sf = (SourceFile_attribute) cf.attributes.get(Attribute.SourceFile); SourceFileAttribute sf = cf.findAttribute(Attributes.SOURCE_FILE).orElseThrow();
String sourceFile = sf.getSourceFile(cf.constant_pool); String sourceFile = sf.sourceFile().stringValue();
if (!"HelloWorld.java".equals(sourceFile)) { if (!"HelloWorld.java".equals(sourceFile)) {
throw new AssertionError("Unexpected SourceFile attribute value: " + sourceFile); throw new AssertionError("Unexpected SourceFile attribute value: " + sourceFile);

View File

@ -28,7 +28,12 @@
* javac crash while creating LVT entry for a local variable defined in * javac crash while creating LVT entry for a local variable defined in
* an inner block * an inner block
* @library /tools/javac/lib * @library /tools/javac/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
* @build JavacTestingAbstractProcessor LVTHarness * @build JavacTestingAbstractProcessor LVTHarness
* @run main LVTHarness * @run main LVTHarness
*/ */
@ -54,19 +59,10 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.attribute.*;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool.InvalidIndex;
import com.sun.tools.classfile.ConstantPool.UnexpectedEntry;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import com.sun.tools.classfile.Method;
import static javax.tools.StandardLocation.*; import static javax.tools.StandardLocation.*;
import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry;
import static javax.tools.JavaFileObject.Kind.SOURCE; import static javax.tools.JavaFileObject.Kind.SOURCE;
public class LVTHarness { public class LVTHarness {
@ -79,10 +75,10 @@ public class LVTHarness {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
try { try {
String testDir = System.getProperty("test.src"); String testDir = System.getProperty("test.src");
fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests"))); fm.setLocation(SOURCE_PATH, List.of(new File(testDir, "tests")));
// Make sure classes are written to scratch dir. // Make sure classes are written to scratch dir.
fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File("."))); fm.setLocation(CLASS_OUTPUT, List.of(new File(".")));
for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) { for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) {
new LVTHarness(jfo).check(); new LVTHarness(jfo).check();
@ -129,31 +125,27 @@ public class LVTHarness {
} }
} }
void checkClassFile(File file) void checkClassFile(File file) throws IOException {
throws IOException, ConstantPoolException, InvalidDescriptor { ClassModel classFile = Classfile.of().parse(file.toPath());
ClassFile classFile = ClassFile.read(file);
ConstantPool constantPool = classFile.constant_pool;
//lets get all the methods in the class file. //lets get all the methods in the class file.
for (Method method : classFile.methods) { for (MethodModel method : classFile.methods()) {
for (ElementKey elementKey: aliveRangeMap.keySet()) { for (ElementKey elementKey: aliveRangeMap.keySet()) {
String methodDesc = method.getName(constantPool) + String methodDesc = method.methodName().stringValue() +
method.descriptor.getParameterTypes(constantPool).replace(" ", ""); parse(method.methodTypeSymbol().descriptorString()).replace(" ", "");
if (methodDesc.equals(elementKey.elem.toString())) { if (methodDesc.equals(elementKey.elem.toString())) {
checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); checkMethod(method, aliveRangeMap.get(elementKey));
seenAliveRanges.add(elementKey); seenAliveRanges.add(elementKey);
} }
} }
} }
} }
void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges) void checkMethod(MethodModel method, AliveRanges ranges) {
throws InvalidIndex, UnexpectedEntry, ConstantPoolException { CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); LocalVariableTableAttribute lvt = code.findAttribute(Attributes.LOCAL_VARIABLE_TABLE).orElseThrow();
LocalVariableTable_attribute lvt =
(LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable));
List<String> infoFromRanges = convertToStringList(ranges); List<String> infoFromRanges = convertToStringList(ranges);
List<String> infoFromLVT = convertToStringList(constantPool, lvt); List<String> infoFromLVT = convertToStringList(lvt);
// infoFromRanges most be contained in infoFromLVT // infoFromRanges most be contained in infoFromLVT
int i = 0; int i = 0;
@ -170,7 +162,7 @@ public class LVTHarness {
} }
if (i < infoFromRanges.size()) { if (i < infoFromRanges.size()) {
error(infoFromLVT, infoFromRanges, method.getName(constantPool).toString()); error(infoFromLVT, infoFromRanges, method.methodName().stringValue());
} }
} }
@ -186,12 +178,11 @@ public class LVTHarness {
return result; return result;
} }
List<String> convertToStringList(ConstantPool constantPool, List<String> convertToStringList(LocalVariableTableAttribute lvt) {
LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
for (Entry entry : lvt.local_variable_table) { for (LocalVariableInfo entry : lvt.localVariables()) {
String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index), String str = formatLocalVariableData(entry.name().stringValue(),
entry.start_pc, entry.length); entry.startPc(), entry.length());
result.add(str); result.add(str);
} }
Collections.sort(result); Collections.sort(result);
@ -292,4 +283,56 @@ public class LVTHarness {
} }
} }
private String parse(String desc) {
int end = desc.indexOf(")");
if (end == -1)
throw new AssertionError();
end ++;
int p = 0;
StringBuilder sb = new StringBuilder();
int dims = 0;
while (p < end) {
String type;
switch (desc.charAt(p++)) {
case '(' -> {
sb.append('(');
continue;
}
case ')' -> {
sb.append(')');
continue;
}
case '[' -> {
dims++;
continue;
}
case 'B' -> type = "byte";
case 'C' -> type = "char";
case 'D' -> type = "double";
case 'F' -> type = "float";
case 'I' -> type = "int";
case 'J' -> type = "long";
case 'L' -> {
int sep = desc.indexOf(';', p);
if (sep == -1)
throw new AssertionError();
type = desc.substring(p, sep).replace('/', '.');
p = sep + 1;
}
case 'S' -> type = "short";
case 'Z' -> type = "boolean";
case 'V' -> type = "void";
default -> throw new AssertionError();
}
if (sb.length() > 1 && sb.charAt(0) == '(')
sb.append(", ");
sb.append(type);
for ( ; dims > 0; dims-- )
sb.append("[]");
}
return sb.toString();
}
} }

View File

@ -26,7 +26,12 @@
* @bug 8013789 * @bug 8013789
* @summary Compiler should emit bridges in interfaces * @summary Compiler should emit bridges in interfaces
* @library /tools/javac/lib * @library /tools/javac/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.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
* @build JavacTestingAbstractProcessor BridgeHarness * @build JavacTestingAbstractProcessor BridgeHarness
@ -34,11 +39,7 @@
*/ */
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.AccessFlags; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
@ -111,8 +112,8 @@ public class BridgeHarness {
/** /**
* return a string representation of a bytecode method * return a string representation of a bytecode method
*/ */
static String descriptor(Method m, ConstantPool cp) throws ConstantPoolException { static String descriptor(MethodModel m) {
return m.getName(cp) + m.descriptor.getValue(cp); return m.methodName() + m.methodTypeSymbol().descriptorString();
} }
/* test harness */ /* test harness */
@ -146,27 +147,27 @@ public class BridgeHarness {
*/ */
protected void checkBridges(JavaFileObject jfo) { protected void checkBridges(JavaFileObject jfo) {
try (InputStream is = jfo.openInputStream()) { try (InputStream is = jfo.openInputStream()) {
ClassFile cf = ClassFile.read(is); ClassModel cf = Classfile.of().parse(is.readAllBytes());
System.err.println("checking: " + cf.getName()); System.err.println("checking: " + cf.thisClass().asInternalName());
List<Bridge> bridgeList = bridgesMap.get(cf.getName()); List<Bridge> bridgeList = bridgesMap.get(cf.thisClass().asInternalName());
if (bridgeList == null) { if (bridgeList == null) {
//no bridges - nothing to check; //no bridges - nothing to check;
bridgeList = List.nil(); bridgeList = List.nil();
} }
for (Method m : cf.methods) { for (MethodModel m : cf.methods()) {
if (m.access_flags.is(AccessFlags.ACC_SYNTHETIC | AccessFlags.ACC_BRIDGE)) { if ((m.flags().flagsMask() & (Classfile.ACC_SYNTHETIC | Classfile.ACC_BRIDGE)) != 0) {
//this is a bridge - see if there's a match in the bridge list //this is a bridge - see if there's a match in the bridge list
Bridge match = null; Bridge match = null;
for (Bridge b : bridgeList) { for (Bridge b : bridgeList) {
if (b.value().equals(descriptor(m, cf.constant_pool))) { if (b.value().equals(descriptor(m))) {
match = b; match = b;
break; break;
} }
} }
if (match == null) { if (match == null) {
error("No annotation for bridge method: " + descriptor(m, cf.constant_pool)); error("No annotation for bridge method: " + descriptor(m));
} else { } else {
bridgeList = drop(bridgeList, match); bridgeList = drop(bridgeList, match);
} }

View File

@ -26,7 +26,12 @@
* @bug 8193717 * @bug 8193717
* @summary Check that code with a lot named imports can compile. * @summary Check that code with a lot named imports can compile.
* @library /tools/lib * @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
* java.base/jdk.internal.classfile.impl
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap * jdk.jdeps/com.sun.tools.javap
@ -38,6 +43,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.constant.ClassDesc;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -55,17 +61,7 @@ import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import com.sun.tools.classfile.AccessFlags; import jdk.internal.classfile.*;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ClassWriter;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.ToolBox; import toolbox.ToolBox;
@ -106,28 +102,13 @@ public class T8193717 {
} }
private byte[] generateClassFile(String name) throws IOException { private byte[] generateClassFile(String name) throws IOException {
ConstantPool cp = new ConstantPool(new CPInfo[] { byte[] bytes = Classfile.of().build(ClassDesc.of(name), classBuilder -> {
new CONSTANT_Utf8_info(""), //0 classBuilder.withSuperclass(ClassDesc.ofInternalName("java/lang/Object"))
new CONSTANT_Utf8_info(name.replace(".", "/")), //1 .withVersion(51, 0)
new CONSTANT_Class_info(null, 1), //2 .withFlags(Classfile.ACC_ABSTRACT | Classfile.ACC_INTERFACE | Classfile.ACC_PUBLIC);
new CONSTANT_Utf8_info("java/lang/Object"), //3
new CONSTANT_Class_info(null, 3), //4
}); });
ClassFile cf = new ClassFile(0xCAFEBABE,
0,
51,
cp,
new AccessFlags(AccessFlags.ACC_ABSTRACT |
AccessFlags.ACC_INTERFACE |
AccessFlags.ACC_PUBLIC),
2,
4,
new int[0],
new Field[0],
new Method[0],
new Attributes(cp, new Attribute[0]));
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ClassWriter().write(cf, baos); baos.write(bytes);
return baos.toByteArray(); return baos.toByteArray();
} }

View File

@ -25,30 +25,33 @@
* @test * @test
* @bug 8015927 * @bug 8015927
* @summary Class reference duplicates in constant pool * @summary Class reference duplicates in constant pool
* @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
* @clean ClassRefDupInConstantPoolTest$Duplicates * @clean ClassRefDupInConstantPoolTest$Duplicates
* @run main ClassRefDupInConstantPoolTest * @run main ClassRefDupInConstantPoolTest
*/ */
import java.util.TreeSet; import java.util.TreeSet;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import com.sun.tools.classfile.ConstantPool.*; import jdk.internal.classfile.constantpool.*;
public class ClassRefDupInConstantPoolTest { public class ClassRefDupInConstantPoolTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ClassFile cls = ClassFile.read(ClassRefDupInConstantPoolTest.class. ClassModel cls = Classfile.of().parse(ClassRefDupInConstantPoolTest.class.
getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class")); getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class").readAllBytes());
ConstantPool pool = cls.constant_pool; ConstantPool pool = cls.constantPool();
int duplicates = 0; int duplicates = 0;
TreeSet<Integer> set = new TreeSet<>(); TreeSet<String> set = new TreeSet<>();
for (CPInfo i : pool.entries()) { for (int i = 1; i < pool.entryCount(); i += pool.entryByIndex(i).width()) {
if (i.getTag() == ConstantPool.CONSTANT_Class) { if (pool.entryByIndex(i) instanceof ClassEntry ce) {
CONSTANT_Class_info ci = (CONSTANT_Class_info)i; if (!set.add(ce.asInternalName())) {
if (!set.add(ci.name_index)) {
duplicates++; duplicates++;
System.out.println("DUPLICATE CLASS REF " + ci.getName()); System.out.println("DUPLICATE CLASS REF " + ce.asInternalName());
} }
} }
} }

View File

@ -26,22 +26,25 @@
* @bug 8011738 * @bug 8011738
* @author sogoel * @author sogoel
* @summary Code translation test for Lambda expressions, method references * @summary Code translation test for Lambda expressions, method references
* @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 ByteCodeTest * @run main ByteCodeTest
*/ */
import com.sun.tools.classfile.Attribute; import jdk.internal.classfile.*;
import com.sun.tools.classfile.BootstrapMethods_attribute; import jdk.internal.classfile.attribute.BootstrapMethodsAttribute;
import com.sun.tools.classfile.ClassFile; import jdk.internal.classfile.constantpool.*;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantPool.*;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.invoke.MethodHandleInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -73,13 +76,14 @@ public class ByteCodeTest {
} }
private static boolean verifyClassFileAttributes(File classFile, TestCases tc) { private static boolean verifyClassFileAttributes(File classFile, TestCases tc) {
ClassFile c = null; ClassModel c = null;
try { try {
c = ClassFile.read(classFile); c = Classfile.of().parse(classFile.toPath());
} catch (IOException | ConstantPoolException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
ConstantPoolVisitor cpv = new ConstantPoolVisitor(c, c.constant_pool.size()); assert c != null;
ConstantPoolVisitor cpv = new ConstantPoolVisitor(c, c.constantPool().entryCount());
Map<Integer, String> hm = cpv.getBSMMap(); Map<Integer, String> hm = cpv.getBSMMap();
List<String> expectedValList = tc.getExpectedArgValues(); List<String> expectedValList = tc.getExpectedArgValues();
@ -378,20 +382,20 @@ public class ByteCodeTest {
} }
} }
static class ConstantPoolVisitor implements ConstantPool.Visitor<String, Integer> { static class ConstantPoolVisitor {
final List<String> slist; final List<String> slist;
final ClassFile cf; final ClassModel cf;
final ConstantPool cfpool; final ConstantPool cfpool;
final Map<Integer, String> bsmMap; final Map<Integer, String> bsmMap;
public ConstantPoolVisitor(ClassFile cf, int size) { public ConstantPoolVisitor(ClassModel cf, int size) {
slist = new ArrayList<>(size); slist = new ArrayList<>(size);
for (int i = 0 ; i < size; i++) { for (int i = 0 ; i < size; i++) {
slist.add(null); slist.add(null);
} }
this.cf = cf; this.cf = cf;
this.cfpool = cf.constant_pool; this.cfpool = cf.constantPool();
bsmMap = readBSM(); bsmMap = readBSM();
} }
@ -399,39 +403,57 @@ public class ByteCodeTest {
return Collections.unmodifiableMap(bsmMap); return Collections.unmodifiableMap(bsmMap);
} }
public String visit(CPInfo c, int index) { public String visit(PoolEntry c, int index) {
return c.accept(this, index); return switch (c) {
case ClassEntry entry -> visitClass(entry, index);
case DoubleEntry entry -> visitDouble(entry, index);
case FieldRefEntry entry -> visitFieldref(entry, index);
case FloatEntry entry -> visitFloat(entry, index);
case IntegerEntry entry -> visitInteger(entry, index);
case InterfaceMethodRefEntry entry -> visitInterfaceMethodref(entry, index);
case InvokeDynamicEntry entry -> visitInvokeDynamic(entry, index);
case ConstantDynamicEntry entry -> visitDynamicConstant(entry, index);
case LongEntry entry -> visitLong(entry, index);
case NameAndTypeEntry entry -> visitNameAndType(entry, index);
case MethodRefEntry entry -> visitMethodref(entry, index);
case MethodHandleEntry entry -> visitMethodHandle(entry, index);
case MethodTypeEntry entry -> visitMethodType(entry, index);
case ModuleEntry entry -> visitModule(entry, index);
case PackageEntry entry -> visitPackage(entry, index);
case StringEntry entry -> visitString(entry, index);
case Utf8Entry entry -> visitUtf8(entry, index);
default -> throw new AssertionError();
};
} }
private Map<Integer, String> readBSM() { private Map<Integer, String> readBSM() {
BootstrapMethods_attribute bsmAttr = BootstrapMethodsAttribute bsmAttr = cf.findAttribute(Attributes.BOOTSTRAP_METHODS).orElse(null);
(BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods);
if (bsmAttr != null) { if (bsmAttr != null) {
Map<Integer, String> out = Map<Integer, String> out =
new HashMap<>(bsmAttr.bootstrap_method_specifiers.length); new HashMap<>(bsmAttr.bootstrapMethodsSize());
for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms : for (BootstrapMethodEntry bsms : bsmAttr.bootstrapMethods()) {
bsmAttr.bootstrap_method_specifiers) { int index = bsms.bootstrapMethod().index();
int index = bsms.bootstrap_method_ref;
try { try {
String value = slist.get(index); String value = slist.get(index);
if (value == null) { if (value == null) {
value = visit(cfpool.get(index), index); value = visit(cfpool.entryByIndex(index), index);
debugln("[SG]: index " + index); debugln("[SG]: index " + index);
debugln("[SG]: value " + value); debugln("[SG]: value " + value);
slist.set(index, value); slist.set(index, value);
out.put(index, value); out.put(index, value);
} }
for (int idx : bsms.bootstrap_arguments) { for (LoadableConstantEntry ce : bsms.arguments()) {
int idx = ce.index();
value = slist.get(idx); value = slist.get(idx);
if (value == null) { if (value == null) {
value = visit(cfpool.get(idx), idx); value = visit(cfpool.entryByIndex(idx), idx);
debugln("[SG]: idx " + idx); debugln("[SG]: idx " + idx);
debugln("[SG]: value " + value); debugln("[SG]: value " + value);
slist.set(idx, value); slist.set(idx, value);
out.put(idx, value); out.put(idx, value);
} }
} }
} catch (InvalidIndex ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
} }
@ -440,13 +462,12 @@ public class ByteCodeTest {
return new HashMap<>(0); return new HashMap<>(0);
} }
@Override public String visitClass(ClassEntry c, Integer p) {
public String visitClass(CONSTANT_Class_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.name_index), c.name_index); value = visit(cfpool.entryByIndex(c.name().index()), c.index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -455,26 +476,24 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitDouble(DoubleEntry c, Integer p) {
public String visitDouble(CONSTANT_Double_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = Double.toString(c.value); value = Double.toString(c.doubleValue());
slist.set(p, value); slist.set(p, value);
} }
return value; return value;
} }
@Override public String visitFieldref(FieldRefEntry c, Integer p) {
public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.class_index), c.class_index); value = visit(cfpool.entryByIndex(c.owner().index()), c.owner().index());
value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), value = value.concat(" " + visit(cfpool.entryByIndex(c.nameAndType().index()),
c.name_and_type_index)); c.nameAndType().index()));
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -483,39 +502,36 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitFloat(FloatEntry c, Integer p) {
public String visitFloat(CONSTANT_Float_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = Float.toString(c.value); value = Float.toString(c.floatValue());
slist.set(p, value); slist.set(p, value);
} }
return value; return value;
} }
@Override public String visitInteger(IntegerEntry cnstnt, Integer p) {
public String visitInteger(CONSTANT_Integer_info cnstnt, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = Integer.toString(cnstnt.value); value = Integer.toString(cnstnt.intValue());
slist.set(p, value); slist.set(p, value);
} }
return value; return value;
} }
@Override public String visitInterfaceMethodref(InterfaceMethodRefEntry c,
public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c,
Integer p) { Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.class_index), c.class_index); value = visit(cfpool.entryByIndex(c.owner().index()), c.owner().index());
value = value.concat(" " + value = value.concat(" " +
visit(cfpool.get(c.name_and_type_index), visit(cfpool.entryByIndex(c.nameAndType().index()),
c.name_and_type_index)); c.nameAndType().index()));
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -524,14 +540,13 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitInvokeDynamic(InvokeDynamicEntry c, Integer p) {
public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = bsmMap.get(c.bootstrap_method_attr_index) + " " value = bsmMap.get(c.bootstrap().bsmIndex()) + " "
+ visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); + visit(cfpool.entryByIndex(c.nameAndType().index()), c.nameAndType().index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -540,14 +555,13 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitDynamicConstant(ConstantDynamicEntry c, Integer p) {
public String visitDynamicConstant(CONSTANT_Dynamic_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = bsmMap.get(c.bootstrap_method_attr_index) + " " value = bsmMap.get(c.bootstrap().bsmIndex()) + " "
+ visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); + visit(cfpool.entryByIndex(c.nameAndType().index()), c.nameAndType().index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -556,44 +570,24 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitLong(LongEntry c, Integer p) {
public String visitLong(CONSTANT_Long_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = Long.toString(c.value); value = Long.toString(c.longValue());
slist.set(p, value); slist.set(p, value);
} }
return value; return value;
} }
@Override public String visitNameAndType(NameAndTypeEntry c, Integer p) {
public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.name_index), c.name_index); value = visit(cfpool.entryByIndex(c.name().index()), c.name().index());
value = value.concat(" " + value = value.concat(" " +
visit(cfpool.get(c.type_index), c.type_index)); visit(cfpool.entryByIndex(c.type().index()), c.type().index()));
slist.set(p, value);
} catch (InvalidIndex ex) {
ex.printStackTrace();
}
}
return value;
}
@Override
public String visitMethodref(CONSTANT_Methodref_info c, Integer p) {
String value = slist.get(p);
if (value == null) {
try {
value = visit(cfpool.get(c.class_index), c.class_index);
value = value.concat(" " +
visit(cfpool.get(c.name_and_type_index),
c.name_and_type_index));
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -602,15 +596,31 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitMethodref(MethodRefEntry c, Integer p) {
public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = c.reference_kind.name(); value = visit(cfpool.entryByIndex(c.owner().index()), c.owner().index());
value = value.concat(" " +
visit(cfpool.entryByIndex(c.nameAndType().index()),
c.nameAndType().index()));
slist.set(p, value);
} catch (ConstantPoolException ex) {
ex.printStackTrace();
}
}
return value;
}
public String visitMethodHandle(MethodHandleEntry c, Integer p) {
String value = slist.get(p);
if (value == null) {
try {
value = MethodHandleInfo.referenceKindToString(c.kind());
value = value.concat(" " value = value.concat(" "
+ visit(cfpool.get(c.reference_index), c.reference_index)); + visit(cfpool.entryByIndex(c.reference().index()), c.reference().index()));
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -619,13 +629,12 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitMethodType(MethodTypeEntry c, Integer p) {
public String visitMethodType(CONSTANT_MethodType_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.descriptor_index), c.descriptor_index); value = visit(cfpool.entryByIndex(c.descriptor().index()), c.descriptor().index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -634,13 +643,12 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitModule(ModuleEntry c, Integer p) {
public String visitModule(CONSTANT_Module_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.name_index), c.name_index); value = visit(cfpool.entryByIndex(c.name().index()), c.name().index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -649,13 +657,12 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitPackage(PackageEntry c, Integer p) {
public String visitPackage(CONSTANT_Package_info c, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
try { try {
value = visit(cfpool.get(c.name_index), c.name_index); value = visit(cfpool.entryByIndex(c.name().index()), c.name().index());
slist.set(p, value); slist.set(p, value);
} catch (ConstantPoolException ex) { } catch (ConstantPoolException ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -664,13 +671,12 @@ public class ByteCodeTest {
return value; return value;
} }
@Override public String visitString(StringEntry c, Integer p) {
public String visitString(CONSTANT_String_info c, Integer p) {
try { try {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = c.getString(); value = c.stringValue();
slist.set(p, value); slist.set(p, value);
} }
return value; return value;
@ -679,12 +685,11 @@ public class ByteCodeTest {
} }
} }
@Override public String visitUtf8(Utf8Entry cnstnt, Integer p) {
public String visitUtf8(CONSTANT_Utf8_info cnstnt, Integer p) {
String value = slist.get(p); String value = slist.get(p);
if (value == null) { if (value == null) {
value = cnstnt.value; value = cnstnt.stringValue();
slist.set(p, value); slist.set(p, value);
} }
return value; return value;

View File

@ -25,7 +25,12 @@
* @test * @test
* @bug 8025998 8026749 8054220 8058227 * @bug 8025998 8026749 8054220 8058227
* @summary Missing LV table in lambda bodies * @summary Missing LV table in lambda bodies
* @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 LocalVariableTable.java * @compile -g LocalVariableTable.java
* @run main LocalVariableTable * @run main LocalVariableTable
*/ */
@ -33,7 +38,8 @@
import java.io.*; import java.io.*;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.util.*; import java.util.*;
import com.sun.tools.classfile.*; import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
/* /*
* The test checks that a LocalVariableTable attribute is generated for the * The test checks that a LocalVariableTable attribute is generated for the
@ -42,12 +48,12 @@ import com.sun.tools.classfile.*;
* *
* Since the bug was about missing entries in the LVT, not malformed entries, * Since the bug was about missing entries in the LVT, not malformed entries,
* the test is not intended to be a detailed test of the contents of each * the test is not intended to be a detailed test of the contents of each
* LocalVariableTable entry: it is assumed that if a entry is present, it * LocalVariableTable entry: it is assumed that if an entry is present, it
* will have the correct contents. * will have the correct contents.
* *
* The test looks for test cases represented by nested classes whose * The test looks for test cases represented by nested classes whose
* name begins with "Lambda". Each such class contains a lambda expression * name begins with "Lambda". Each such class contains a lambda expression
* that will mapped into a lambda method, and because the test is compiled * that will map into a lambda method, and because the test is compiled
* with -g, these methods should have a LocalVariableTable. The set of * with -g, these methods should have a LocalVariableTable. The set of
* expected names in the LVT is provided in an annotation on the class for * expected names in the LVT is provided in an annotation on the class for
* the test case. * the test case.
@ -81,29 +87,28 @@ public class LocalVariableTable {
return; return;
} }
ClassFile cf = ClassFile.read(getClass().getResource(c.getName() + ".class").openStream()); ClassModel cm = Classfile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")).openStream().readAllBytes());
Method m = getLambdaMethod(cf); MethodModel m = getLambdaMethod(cm);
if (m == null) { if (m == null) {
error("lambda method not found"); error("lambda method not found");
return; return;
} }
Code_attribute code = (Code_attribute) m.attributes.get(Attribute.Code); CodeAttribute code = m.findAttribute(Attributes.CODE).orElse(null);
if (code == null) { if (code == null) {
error("Code attribute not found"); error("Code attribute not found");
return; return;
} }
LocalVariableTable_attribute lvt = LocalVariableTableAttribute lvt = code.findAttribute(Attributes.LOCAL_VARIABLE_TABLE).orElse(null);
(LocalVariableTable_attribute) code.attributes.get(Attribute.LocalVariableTable);
if (lvt == null) { if (lvt == null) {
error("LocalVariableTable attribute not found"); error("LocalVariableTable attribute not found");
return; return;
} }
Set<String> foundNames = new LinkedHashSet<>(); Set<String> foundNames = new LinkedHashSet<>();
for (LocalVariableTable_attribute.Entry e: lvt.local_variable_table) { for (LocalVariableInfo e: lvt.localVariables()) {
foundNames.add(cf.constant_pool.getUTF8Value(e.name_index)); foundNames.add(e.name().stringValue());
} }
Set<String> expectNames = new LinkedHashSet<>(Arrays.asList(expect.value())); Set<String> expectNames = new LinkedHashSet<>(Arrays.asList(expect.value()));
@ -120,9 +125,9 @@ public class LocalVariableTable {
} }
/** Get a method whose name begins "lambda$...". */ /** Get a method whose name begins "lambda$...". */
Method getLambdaMethod(ClassFile cf) throws ConstantPoolException { MethodModel getLambdaMethod(ClassModel cf) {
for (Method m: cf.methods) { for (MethodModel m: cf.methods()) {
if (m.getName(cf.constant_pool).startsWith("lambda$")) if (m.methodName().stringValue().startsWith("lambda$"))
return m; return m;
} }
return null; return null;

Some files were not shown because too many files have changed in this diff Show More