8313422: test/langtools/tools/javac 144 test classes uses com.sun.tools.classfile library
Reviewed-by: asotona
This commit is contained in:
parent
8557205a82
commit
8f7e29b2cd
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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);
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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; }
|
|
||||||
}
|
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {}
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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 { };
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
@ -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 + ".");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user