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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,12 @@
* @test
* @bug 7199823
* @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
*/
@ -37,8 +42,7 @@ import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler;
import com.sun.source.util.JavacTask;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import jdk.internal.classfile.*;
import java.io.File;
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 {
File file = new File("Test$1.class");
ClassFile classFile = ClassFile.read(file);
ClassModel classFile = Classfile.of().parse(file.toPath());
if (ck == CompilationKind.POST_NESTMATES) {
throw new AssertionError("Unexpected constructor tag class!");
}
boolean inheritsFromObject =
classFile.getSuperclassName().equals("java/lang/Object");
boolean implementsNoInterface = classFile.interfaces.length == 0;
boolean noMethods = classFile.methods.length == 0;
classFile.superclass().orElseThrow().asInternalName().equals("java/lang/Object");
boolean implementsNoInterface = classFile.interfaces().size() == 0;
boolean noMethods = classFile.methods().size() == 0;
if (!(inheritsFromObject &&
implementsNoInterface &&
noMethods)) {

View File

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

View File

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

View File

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

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters AnnotationTest.java
* @run main MethodParametersTester AnnotationTest AnnotationTest.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters AnonymousClass.java
* @run main MethodParametersTester AnonymousClass AnonymousClass.out

View File

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

View File

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

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters Constructors.java
* @run main MethodParametersTester Constructors Constructors.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582 8008658
* @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
* @compile -parameters EnumTest.java
* @run main MethodParametersTester EnumTest EnumTest.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters InstanceMethods.java
* @run main MethodParametersTester InstanceMethods InstanceMethods.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582 8037546 8138729
* @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
* @compile -parameters LambdaTest.java
* @run main MethodParametersTester LambdaTest LambdaTest.out

View File

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

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582 8008658
* @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
* @compile -parameters LocalClassTest.java
* @run main MethodParametersTester LocalClassTest LocalClassTest.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582 8008658
* @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
* @compile -parameters MemberClassTest.java
* @run main MethodParametersTester MemberClassTest MemberClassTest.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters StaticMethods.java
* @run main MethodParametersTester StaticMethods StaticMethods.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8006582
* @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
* @compile -parameters UncommonParamNames.java
* @run main MethodParametersTester UncommonParamNames UncommonParamNames.out

View File

@ -25,7 +25,12 @@
* @test
* @bug 8004727
* @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.comp
* jdk.compiler/com.sun.tools.javac.file
@ -34,7 +39,8 @@
* jdk.compiler/com.sun.tools.javac.util
*/
// 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.file.JavacFileManager;
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 java.io.*;
import javax.lang.model.element.*;
import java.nio.file.Files;
import java.util.*;
public class MethodParametersTest {
@ -147,8 +154,7 @@ public class MethodParametersTest {
// parameter.
final Element baz = cf.loadClass(syms.unnamedModule, name);
for (Element e : baz.getEnclosedElements()) {
if (e instanceof ExecutableElement) {
final ExecutableElement ee = (ExecutableElement) e;
if (e instanceof ExecutableElement ee) {
final List<? extends VariableElement> params =
ee.getParameters();
if (1 != params.size())
@ -165,156 +171,117 @@ public class MethodParametersTest {
void modifyBaz(boolean flip) throws Exception {
final File Baz_class = new File(classesdir, Baz_name + ".class");
final ClassFile baz = ClassFile.read(Baz_class);
final int ind = baz.constant_pool.getUTF8Index("baz");
MethodParameters_attribute mpattr = null;
int mpind = 0;
Code_attribute cattr = null;
int cind = 0;
final ClassModel baz = Classfile.of().parse(Baz_class.toPath());
// Find the indexes of the MethodParameters and the Code attributes
if (baz.methods.length != 1)
// Find MethodParameters and the Code attributes
if (baz.methods().size() != 1)
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 " +
baz.methods[0].getName(baz.constant_pool));
for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
if (baz.methods[0].attributes.attrs[i] instanceof
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;
}
}
baz.methods().get(0).methodName().stringValue());
MethodParametersAttribute mpattr = baz.methods().get(0).findAttribute(Attributes.METHOD_PARAMETERS).orElse(null);
CodeAttribute cattr = baz.methods().get(0).findAttribute(Attributes.CODE).orElse(null);;
if (null == mpattr)
throw new Exception("Classfile Baz badly formed: no method parameters info");
if (null == cattr)
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
// the parameter from i to baz. This requires Black Magic...
//
// The (well-designed) classfile library (correctly) does not
// allow us to mess around with the attribute data structures,
// or arbitrarily generate new ones.
//
// 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;
// the parameter from i to baz.
byte[] bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> {
if (methodElement instanceof MethodParametersAttribute a) {
List<MethodParameterInfo> newParameterInfos = new ArrayList<>();
for (MethodParameterInfo info : a.parameters()) {
newParameterInfos.add(MethodParameterInfo.ofParameter("baz".describeConstable(), info.flagsMask()));
}
};
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.
if (flip) {
baz.methods[0].attributes.attrs[mpind] = cattr;
baz.methods[0].attributes.attrs[cind] = mpattr;
bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> {
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.
void checkFoo() throws Exception {
final File Foo_class = new File(classesdir, Foo_name + ".class");
final ClassFile foo = ClassFile.read(Foo_class);
for (int i = 0; i < foo.methods.length; i++) {
System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
if (foo.methods[i].attributes.attrs[j] instanceof
MethodParameters_attribute) {
MethodParameters_attribute mp =
(MethodParameters_attribute)
foo.methods[i].attributes.attrs[j];
final ClassModel foo = Classfile.of().parse(Foo_class.toPath());
for (int i = 0; i < foo.methods().size(); i++) {
System.err.println("Examine method Foo." + foo.methods().get(i).methodName());
if (foo.methods().get(i).methodName().equalsString("foo2")) {
for (int j = 0; j < foo.methods().get(i).attributes().size(); j++)
if (foo.methods().get(i).attributes().get(j) instanceof MethodParametersAttribute mp) {
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 " +
mp.method_parameter_table_length);
else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
mp.parameters().size());
else if (!mp.parameters().get(0).name().orElseThrow().equalsString("j"))
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");
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 \"" +
foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
mp.parameters().get(1).name().orElseThrow() +
"\" instead");
}
}
else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
if (foo.methods[i].attributes.attrs[j] instanceof
MethodParameters_attribute)
else if (foo.methods().get(i).methodName().equalsString("<init>")) {
for (int j = 0; j < foo.methods().get(i).attributes().size(); j++) {
if (foo.methods().get(i).attributes().get(j) instanceof
MethodParametersAttribute)
error("Zero-argument constructor shouldn't have MethodParameters");
}
}
else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
if (foo.methods[i].attributes.attrs[j] instanceof
MethodParameters_attribute)
else if (foo.methods().get(i).methodName().equalsString("foo0")) {
for (int j = 0; j < foo.methods().get(i).attributes().size(); j++)
if (foo.methods().get(i).attributes().get(j) instanceof
MethodParametersAttribute)
error("Zero-argument method shouldn't have MethodParameters");
}
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.
void checkBar() throws Exception {
final File Bar_class = new File(classesdir, Bar_name + ".class");
final ClassFile bar = ClassFile.read(Bar_class);
for (int i = 0; i < bar.methods.length; i++) {
System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
if (bar.methods[i].attributes.attrs[j] instanceof
MethodParameters_attribute) {
MethodParameters_attribute mp =
(MethodParameters_attribute)
bar.methods[i].attributes.attrs[j];
final ClassModel bar = Classfile.of().parse(Bar_class.toPath());
for (int i = 0; i < bar.methods().size(); i++) {
System.err.println("Examine method Bar." + bar.methods().get(i).methodName());
if (bar.methods().get(i).methodName().equalsString("<init>")) {
for (int j = 0; j < bar.methods().get(i).attributes().size(); j++)
if (bar.methods().get(i).attributes().get(j) instanceof
MethodParametersAttribute mp) {
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 " +
mp.method_parameter_table_length);
else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
mp.parameters().size());
else if (!mp.parameters().get(0).name().orElseThrow().equalsString("i"))
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");
}
}
else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
if (bar.methods[i].attributes.attrs[j] instanceof
MethodParameters_attribute)
else if (bar.methods().get(i).methodName().equalsString("foo")) {
for (int j = 0; j < bar.methods().get(i).attributes().size(); j++) {
if (bar.methods().get(i).attributes().get(j) instanceof
MethodParametersAttribute)
error("Zero-argument constructor shouldn't have MethodParameters");
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -21,8 +21,10 @@
* questions.
*/
import com.sun.tools.classfile.*;
import com.sun.tools.classfile.ConstantPool.*;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.constantpool.*;
import jdk.internal.classfile.instruction.InvokeDynamicInstruction;
import java.io.File;
import java.util.ArrayList;
@ -32,7 +34,11 @@ import java.util.List;
* @test
* @bug 8151223
* @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 *
* @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 {
actualTypes = new ArrayList<String>();
ClassFile classFile = ClassFile.read(new File(System.getProperty("test.classes", "."),
Test.class.getName() + ".class"));
ConstantPool constantPool = classFile.constant_pool;
ClassModel classFile = Classfile.of().parse(new File(System.getProperty("test.classes", "."),
Test.class.getName() + ".class").toPath());
for (Method method : classFile.methods) {
if (method.getName(constantPool).equals("main")) {
Code_attribute code = (Code_attribute) method.attributes
.get(Attribute.Code);
for (Instruction i : code.getInstructions()) {
if (i.getOpcode() == Opcode.INVOKEDYNAMIC) {
CONSTANT_InvokeDynamic_info indyInfo = (CONSTANT_InvokeDynamic_info) constantPool.get(i.getUnsignedShort(1));
CONSTANT_NameAndType_info natInfo = indyInfo.getNameAndTypeInfo();
actualTypes.add(natInfo.getType());
for (MethodModel method : classFile.methods()) {
if (method.methodName().equalsString("main")) {
CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
for (CodeElement i : code.elementList()) {
if (i instanceof InvokeDynamicInstruction) {
InvokeDynamicEntry indyInfo = ((InvokeDynamicInstruction) i).invokedynamic();
NameAndTypeEntry natInfo = indyInfo.nameAndType();
actualTypes.add(natInfo.type().stringValue());
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,7 +29,12 @@
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util
* jdk.jdeps/com.sun.tools.classfile
* java.base/jdk.internal.classfile
* java.base/jdk.internal.classfile.attribute
* java.base/jdk.internal.classfile.constantpool
* java.base/jdk.internal.classfile.instruction
* java.base/jdk.internal.classfile.components
* java.base/jdk.internal.classfile.impl
* @build toolbox.ToolBox toolbox.JavacTask
* @run main WrongLNTForLambdaTest
*/
@ -37,12 +42,10 @@
import java.io.File;
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 jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import toolbox.JavacTask;
import toolbox.ToolBox;
@ -159,22 +162,21 @@ public class WrongLNTForLambdaTest {
}
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;
for (Method method : classFile.methods) {
if (method.getName(classFile.constant_pool).equals(methodToFind)) {
for (MethodModel method : classFile.methods()) {
if (method.methodName().equalsString(methodToFind)) {
methodFound = true;
Code_attribute code = (Code_attribute) method.attributes.get("Code");
LineNumberTable_attribute lnt =
(LineNumberTable_attribute) code.attributes.get("LineNumberTable");
Assert.check(lnt.line_number_table_length == expectedLNT.length,
CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow();
LineNumberTableAttribute lnt = code.findAttribute(Attributes.LINE_NUMBER_TABLE).orElseThrow();
Assert.check(lnt.lineNumbers().size() == expectedLNT.length,
"The LineNumberTable found has a length different to the expected one");
int i = 0;
for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) {
Assert.check(entry.line_number == expectedLNT[i][0] &&
entry.start_pc == expectedLNT[i][1],
for (LineNumberInfo entry: lnt.lineNumbers()) {
Assert.check(entry.lineNumber() == expectedLNT[i][0] &&
entry.startPc() == expectedLNT[i][1],
"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]);
i++;
}

View File

@ -25,21 +25,19 @@
* @test
* @bug 8022186 8271254
* @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
*/
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
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 jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.constantpool.*;
import jdk.internal.classfile.instruction.InvokeInstruction;
import com.sun.tools.javac.util.Assert;
import java.io.BufferedInputStream;
import java.nio.file.Files;
@ -65,97 +63,27 @@ public class DeadCodeGeneratedForEmptyTryTest {
void checkClassFile(final Path path) throws Exception {
numberOfRefToStr = 0;
ClassFile classFile = ClassFile.read(
new BufferedInputStream(Files.newInputStream(path)));
constantPool = classFile.constant_pool;
utf8Index = constantPool.getUTF8Index("STR_TO_LOOK_FOR");
for (Method method: classFile.methods) {
if (method.getName(constantPool).equals("methodToLookFor")) {
Code_attribute codeAtt = (Code_attribute)method.attributes.get(Attribute.Code);
for (Instruction inst: codeAtt.getInstructions()) {
inst.accept(codeVisitor, null);
}
ClassModel classFile = Classfile.of().parse(
new BufferedInputStream(Files.newInputStream(path)).readAllBytes());
constantPool = classFile.constantPool();
for (MethodModel method: classFile.methods()) {
if (method.methodName().equalsString("methodToLookFor")) {
CodeAttribute codeAtt = method.findAttribute(Attributes.CODE).orElseThrow();
codeAtt.elementList().stream()
.filter(ce -> ce instanceof Instruction)
.forEach(ins -> checkIndirectRefToString((Instruction) ins));
}
}
Assert.check(numberOfRefToStr == 1,
"There should only be one reference to a CONSTANT_String_info structure in the generated code");
}
CodeVisitor codeVisitor = new CodeVisitor();
class CodeVisitor implements KindVisitor<Void, Void> {
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++;
}
}
} catch (InvalidIndex ex) {
throw new AssertionError("invalid constant pool index at " + cp_index);
void checkIndirectRefToString(Instruction instruction) {
if (instruction instanceof InvokeInstruction invokeInstruction) {
MemberRefEntry refEntry = invokeInstruction.method();
if (constantPool.entryByIndex(refEntry.type().index()) instanceof Utf8Entry) {
numberOfRefToStr++;
}
}
@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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* @library /tools/lib
* @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.main
* jdk.compiler/com.sun.tools.javac.code
@ -45,7 +50,8 @@ import java.nio.file.Paths;
import java.lang.annotation.*;
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 toolbox.JavacTask;
@ -109,11 +115,11 @@ public class TypeAnnotationsPositionsOnRecords {
}
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 checkedAccessors = 0;
for (Method method : classFile.methods) {
String methodName = method.getName(classFile.constant_pool);
for (MethodModel method : classFile.methods()) {
String methodName = method.methodName().stringValue();
if (methodName.equals("toString") || methodName.equals("hashCode") || methodName.equals("equals")) {
// ignore
continue;
@ -138,15 +144,16 @@ public class TypeAnnotationsPositionsOnRecords {
* there can be several parameters annotated we have to check that the ones annotated are the
* 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<>();
findAnnotations(classFile, method, annos);
Assert.check(annos.size() == positions.length);
int i = 0;
for (int pos : positions) {
TypeAnnotation ta = annos.get(i);
Assert.check(ta.position.type.toString().equals("METHOD_FORMAL_PARAMETER"));
Assert.check(ta.position.parameter_index == pos);
Assert.check(ta.targetInfo().targetType().name().equals("METHOD_FORMAL_PARAMETER"));
assert ta.targetInfo() instanceof TypeAnnotation.FormalParameterTarget;
Assert.check(((TypeAnnotation.FormalParameterTarget)ta.targetInfo()).formalParameterIndex() == pos);
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
* at the return type
*/
void checkAccessor(ClassFile classFile, Method method) {
void checkAccessor(ClassModel classFile, MethodModel method) {
List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(classFile, method, annos);
Assert.check(annos.size() == 1);
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
* original annotated record component are annotated
*/
void checkFields(ClassFile classFile, int... positions) {
void checkFields(ClassModel classFile, int... positions) {
if (positions != null && positions.length > 0) {
int fieldPos = 0;
int annotationPos = 0;
int currentAnnoPosition = positions[annotationPos];
int annotatedFields = 0;
for (Field field : classFile.fields) {
for (FieldModel field : classFile.fields()) {
List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(classFile, field, annos);
if (fieldPos != currentAnnoPosition) {
@ -181,7 +188,7 @@ public class TypeAnnotationsPositionsOnRecords {
} else {
Assert.check(annos.size() == 1);
TypeAnnotation ta = annos.get(0);
Assert.check(ta.position.type.toString().equals("FIELD"));
Assert.check(ta.targetInfo().targetType().name().equals("FIELD"));
annotationPos++;
currentAnnoPosition = annotationPos < positions.length ? positions[annotationPos] : -1;
annotatedFields++;
@ -193,47 +200,36 @@ public class TypeAnnotationsPositionsOnRecords {
}
// utility methods
void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
void findAnnotations(ClassModel cm, AttributedElement m, List<TypeAnnotation> annos) {
findAnnotations(cm, m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cm, m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
}
void findAnnotations(ClassFile cf, Field m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
}
void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
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));
<T extends Attribute<T>> void findAnnotations(ClassModel cf, AttributedElement m, AttributeMapper<T> attrName, List<TypeAnnotation> annos) {
Attribute<T> attr = m.findAttribute(attrName).orElse(null);
addAnnos(annos, attr);
if (m instanceof MethodModel) {
CodeAttribute cattr = m.findAttribute(Attributes.CODE).orElse(null);
if (cattr != null) {
attr = cattr.findAttribute(attrName).orElse(null);
addAnnos(annos, attr);
}
}
}
void findAnnotations(ClassFile cf, Field m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
private <T extends Attribute<T>> void addAnnos(List<TypeAnnotation> annos, Attribute<T> attr) {
if (attr != null) {
switch (attr) {
case RuntimeVisibleTypeAnnotationsAttribute vanno -> {
annos.addAll(vanno.annotations());
}
case RuntimeInvisibleTypeAnnotationsAttribute ivanno -> {
annos.addAll(ivanno.annotations());
}
default -> {
throw new AssertionError();
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* @library /tools/lib
* @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.main
* jdk.compiler/com.sun.tools.javac.code
@ -45,7 +50,8 @@ import java.nio.file.Paths;
import java.lang.annotation.*;
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 toolbox.JavacTask;
@ -97,41 +103,45 @@ public class VariablesDeclaredWithVarTest {
}
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<>();
for (Method method : classFile.methods) {
for (MethodModel method : classFile.methods()) {
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() +
" type annotations at method " + methodName);
}
}
void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
void findAnnotations(ClassModel cf, MethodModel m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cf, m, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
}
void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
<T extends Attribute<T>> void findAnnotations(ClassModel cf, AttributedElement m, AttributeMapper<T> attrName, List<TypeAnnotation> annos) {
Attribute<T> attr = m.findAttribute(attrName).orElse(null);
addAnnos(annos, attr);
if (m instanceof MethodModel) {
CodeAttribute cattr = m.findAttribute(Attributes.CODE).orElse(null);
if (cattr != null) {
attr = cattr.findAttribute(attrName).orElse(null);
addAnnos(annos, attr);
}
}
}
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));
private <T extends Attribute<T>> void addAnnos(List<TypeAnnotation> annos, Attribute<T> attr) {
if (attr != null) {
switch (attr) {
case RuntimeVisibleTypeAnnotationsAttribute vanno -> {
annos.addAll(vanno.annotations());
}
case RuntimeInvisibleTypeAnnotationsAttribute ivanno -> {
annos.addAll(ivanno.annotations());
}
default -> {
throw new AssertionError();
}
}
}
}

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451 8164519
* @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
* @run main Driver ClassExtends
*/

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver ClassTypeParam
*/

View File

@ -25,12 +25,17 @@
* @test
* @bug 8042451
* @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
* @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 {

View File

@ -25,12 +25,17 @@
* @test
* @bug 8026791 8042451
* @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
* @run main Driver Constructors
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Constructors {

View File

@ -21,6 +21,7 @@
* questions.
*/
import jdk.internal.classfile.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
@ -29,16 +30,8 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
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 java.util.*;
import java.util.stream.Collectors;
import static java.lang.String.format;
@ -53,7 +46,7 @@ public class Driver {
}
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>");
String name = args[0];
new Driver(Class.forName(name)).runDriver();
@ -74,7 +67,7 @@ public class Driver {
// Find methods
for (Method method : clazz.getMethods()) {
try {
Map<String, TypeAnnotation.Position> expected = expectedOf(method);
Map<String, ReferenceInfoUtil.TAD> expected = expectedOf(method);
if (expected == null)
continue;
if (method.getReturnType() != String.class)
@ -84,15 +77,15 @@ public class Driver {
for (String retentionPolicy : retentionPolicies) {
String testClassName = getTestClassName(method, retentionPolicy);
String testClass = testClassOf(method, testClassName);
String fullFile = wrap(compact, new HashMap<String, String>() {{
String fullFile = wrap(compact, new HashMap<>() {{
put("%RETENTION_POLICY%", retentionPolicy);
put("%TEST_CLASS_NAME%", testClassName);
}});
for (String[] extraParams : extraParamsCombinations) {
try {
ClassFile cf = compileAndReturn(fullFile, testClass, extraParams);
List<TypeAnnotation> actual = ReferenceInfoUtil.extendedAnnotationsOf(cf);
ReferenceInfoUtil.compare(expected, actual, cf);
ClassModel cm = compileAndReturn(fullFile, testClass, extraParams);
List<ReferenceInfoUtil.TAD> actual = ReferenceInfoUtil.extendedAnnotationsOf(cm);
ReferenceInfoUtil.compare(expected, actual);
out.format("PASSED: %s %s%n", testClassName, Arrays.toString(extraParams));
++passed;
} catch (Throwable e) {
@ -106,7 +99,7 @@ public class Driver {
}
} catch (IllegalAccessException | InvocationTargetException e) {
out.println("FAILED: " + method.getName());
out.println(" " + e.toString());
out.println(" " + e);
e.printStackTrace(out);
++failed;
}
@ -122,61 +115,35 @@ public class Driver {
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);
TADescriptions tas = m.getAnnotation(TADescriptions.class);
if (ta == null && tas == null)
return null;
Map<String, TypeAnnotation.Position> result =
Map<String, ReferenceInfoUtil.TAD> result =
new HashMap<>();
if (ta != null)
result.putAll(expectedOf(ta));
result.put(ta.annotation(), wrapTADescription(ta));
if (tas != null) {
for (TADescription a : tas.value()) {
result.putAll(expectedOf(a));
result.put(a.annotation(), wrapTADescription(a));
}
}
return result;
}
private Map<String, TypeAnnotation.Position> expectedOf(TADescription d) {
String annoName = d.annotation();
TypeAnnotation.Position p = new TypeAnnotation.Position();
p.type = d.type();
if (d.offset() != NOT_SET)
p.offset = d.offset();
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 ReferenceInfoUtil.TAD wrapTADescription(TADescription taD) {
List<Integer> genericLocation = Arrays.stream(taD.genericLocation()).boxed().collect(Collectors.toList());
List<Integer> lvarIndex = Arrays.stream(taD.lvarIndex()).boxed().collect(Collectors.toList());
List<Integer> lvarLength = Arrays.stream(taD.lvarLength()).boxed().collect(Collectors.toList());
List<Integer> lvarOffset = Arrays.stream(taD.lvarOffset()).boxed().collect(Collectors.toList());
return new ReferenceInfoUtil.TAD(taD.annotation(), taD.type(), taD.typeIndex(),
taD.paramIndex(), taD.boundIndex(), taD.exceptionIndex(), taD.offset(),
lvarOffset, lvarLength, lvarIndex, genericLocation);
}
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 clazzFile = compileTestFile(source, testClass, extraParams);
return ClassFile.read(clazzFile);
return Classfile.of().parse(clazzFile.toPath());
}
protected File writeTestFile(String fullFile, String testClass) throws IOException {
@ -208,14 +175,13 @@ public class Driver {
}
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) {
List<String> options = new ArrayList<>();
options.addAll(Arrays.asList(extraParams));
List<String> options = new ArrayList<>(Arrays.asList(extraParams));
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)
throw new Error("compilation failed. rc=" + rc);
String path = f.getParent() != null ? f.getParent() : "";
@ -352,7 +318,7 @@ public class Driver {
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 {
String annotation();
TargetType type();
TypeAnnotation.TargetType type();
int offset() default Driver.NOT_SET;
int[] lvarOffset() default { };
int[] lvarLength() default { };

View File

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

View File

@ -25,12 +25,17 @@
* @test
* @bug 8042451 8208470
* @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
* @run main Driver Fields
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Fields {
// field types

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver FromSpecification
*/

View File

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

View File

@ -26,14 +26,19 @@
* @bug 8008077 8029721 8042451 8043974
* @summary Test population of reference info for lambda expressions
* 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
* @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
* @run main Driver Lambda
* @author Werner Dietl
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
public class Lambda {

View File

@ -25,12 +25,17 @@
* @test
* @bug 8042451
* @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
* @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;
public class MethodInvocationTypeArgument {

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver MethodParameters
*/

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver MethodReceivers
*/

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver MethodReturns
*/

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver MethodThrows
*/

View File

@ -21,14 +21,19 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
import static java.lang.System.lineSeparator;
/*
* @test
* @bug 8042451
* @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
* @run main Driver MethodTypeParam
*/

View File

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

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451 8044009 8044010
* @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
* @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java
* @run main Driver NestedTypes

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver NewObjects
*/

View File

@ -21,102 +21,126 @@
* questions.
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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;
import jdk.internal.classfile.*;
import jdk.internal.classfile.attribute.*;
import java.util.*;
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) {
List<TypeAnnotation> annos = new ArrayList<>();
findAnnotations(cf, annos);
public static List<TAD> extendedAnnotationsOf(ClassModel cm) {
List<TAD> annos = new ArrayList<>();
findAnnotations(cm, annos);
return annos;
}
/////////////////// Extract type annotations //////////////////
private static void findAnnotations(ClassFile cf, List<TypeAnnotation> annos) {
findAnnotations(cf, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, Attribute.RuntimeInvisibleTypeAnnotations, annos);
private static void findAnnotations(ClassModel cm, List<TAD> annos) {
findAnnotations(cm, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(cm, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
for (Field f : cf.fields) {
findAnnotations(cf, f, annos);
for (FieldModel f : cm.fields()) {
findAnnotations(f, annos);
}
for (Method m: cf.methods) {
findAnnotations(cf, m, annos);
for (MethodModel m: cm.methods()) {
findAnnotations(m, annos);
}
}
private static void findAnnotations(ClassFile cf, Method m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
}
private static void findAnnotations(ClassFile cf, Field m, List<TypeAnnotation> annos) {
findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos);
findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos);
private static void findAnnotations(AttributedElement ae, List<TAD> annos) {
findAnnotations(ae, Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS, annos);
findAnnotations(ae, Attributes.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, annos);
}
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
private static void findAnnotations(ClassFile cf, String name, List<TypeAnnotation> annos) {
int index = cf.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = cf.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
private static <T extends Attribute<T>> void findAnnotations(ClassModel cm, AttributeMapper<T> attrName, List<TAD> annos) {
Attribute<T> attr = cm.findAttribute(attrName).orElse(null);
if (attr != null) {
if (attr instanceof RuntimeVisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} else if (attr instanceof RuntimeInvisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} else throw new AssertionError();
}
}
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
private static void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
private static <T extends Attribute<T>> void findAnnotations(AttributedElement m, AttributeMapper<T> attrName, List<TAD> annos) {
Attribute<T> attr = m.findAttribute(attrName).orElse(null);
if (attr != null) {
if (attr instanceof RuntimeVisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} else if (attr instanceof RuntimeInvisibleTypeAnnotationsAttribute tAttr) {
annos.addAll(Objects.requireNonNull(generateTADList(tAttr.annotations(), null)));
} 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));
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();
}
}
}
}
// test the result of Attributes.getIndex according to expectations
// encoded in the method's name
private static void findAnnotations(ClassFile cf, Field m, String name, List<TypeAnnotation> annos) {
int index = m.attributes.getIndex(cf.constant_pool, name);
if (index != -1) {
Attribute attr = m.attributes.get(index);
assert attr instanceof RuntimeTypeAnnotations_attribute;
RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
annos.addAll(Arrays.asList(tAttr.annotations));
// get each target information and wrap with TAD (corresponding with TADescription in driver class)
private static List<TAD> generateTADList(List<TypeAnnotation> annos, CodeAttribute cAttr) {
List<TAD> result = new ArrayList<>();
for (TypeAnnotation anno: annos) {
TAD tad = new TAD();
tad.annotation = anno.className().stringValue();
tad.type = anno.targetInfo().targetType();
switch (anno.targetInfo().targetType()) {
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 /////////////////////
@ -124,84 +148,98 @@ public class ReferenceInfoUtil {
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)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
int length = a.size();
if (a2.size() != length)
return false;
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 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) &&
p1.type == p2.type &&
(p1.location.equals(p2.location)) &&
areEquals(p1.genericLocation, p2.genericLocation) &&
areEquals(p1.offset, p2.offset) &&
areEquals(p1.lvarOffset, p2.lvarOffset) &&
areEquals(p1.lvarLength, p2.lvarLength) &&
areEquals(p1.lvarIndex, p2.lvarIndex) &&
areEquals(p1.bound_index, p2.bound_index) &&
areEquals(p1.parameter_index, p2.parameter_index) &&
areEquals(p1.type_index, p2.type_index) &&
areEquals(p1.exception_index, p2.exception_index);
areEquals(p1.boundIndex, p2.boundIndex) &&
areEquals(p1.paramIndex, p2.paramIndex) &&
areEquals(p1.typeIndex, p2.typeIndex) &&
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 + ";";
for (TypeAnnotation anno : annotations) {
String actualName = cf.constant_pool.getUTF8Value(anno.annotation.type_index);
for (TAD anno : annotations) {
String actualName = anno.annotation;
if (properName.equals(actualName))
return anno;
}
return null;
}
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos,
List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry {
public static boolean compare(Map<String, TAD> expectedAnnos,
List<TAD> actualAnnos) {
if (actualAnnos.size() != expectedAnnos.size()) {
throw new ComparisionException("Wrong number of annotations",
expectedAnnos,
actualAnnos);
}
for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) {
String aName = e.getKey();
TypeAnnotation.Position expected = e.getValue();
TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf);
if (actual == null)
for (Map.Entry<String, TAD> expectedAno : expectedAnnos.entrySet()) {
String aName = expectedAno.getKey();
TAD expectedTAD = expectedAno.getValue();
TAD actualTAD = findAnnotation(aName, actualAnnos);
if (actualTAD == null)
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 +
"\n Expected: " + expected.toString() +
"\n Found: " + actual.position.toString());
"\n Expected: " + expectedTAD +
"\n Found: " + actualTAD);
}
}
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 {
private static final long serialVersionUID = -3930499712333815821L;
public final Map<String, TypeAnnotation.Position> expected;
public final List<TypeAnnotation> found;
public final Map<String, ReferenceInfoUtil.TAD> expected;
public final List<ReferenceInfoUtil.TAD> found;
public ComparisionException(String message) {
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);
this.expected = expected;
this.found = found;

View File

@ -21,12 +21,17 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @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
* @run main Driver RepeatingTypeAnnotations
* @author Werner Dietl

View File

@ -25,12 +25,17 @@
* @test
* @bug 8042451
* @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
* @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;
public class ResourceVariable {

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver TypeCasts
*/

View File

@ -21,13 +21,18 @@
* questions.
*/
import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
import static jdk.internal.classfile.TypeAnnotation.TargetType.*;
/*
* @test
* @bug 8042451
* @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
* @run main Driver TypeTests
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access
// 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
* final field of type java.lang.Object having ConstantValue attribute with

View File

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

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access
// 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
* and a non-abstract method in an interface. Loading the classfile will produce

View File

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

View File

@ -25,7 +25,7 @@
// key: compiler.misc.bad.class.file.header
// key: compiler.err.cant.access
// 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
* and a static method in an interface. Loading the classfile will produce

View File

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

View File

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

View File

@ -28,7 +28,12 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile
* java.base/jdk.internal.classfile
* java.base/jdk.internal.classfile.attribute
* java.base/jdk.internal.classfile.constantpool
* java.base/jdk.internal.classfile.instruction
* java.base/jdk.internal.classfile.components
* java.base/jdk.internal.classfile.impl
* @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
* @run main SymLinkArchiveTest
*/

View File

@ -28,7 +28,12 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.classfile
* java.base/jdk.internal.classfile
* java.base/jdk.internal.classfile.attribute
* java.base/jdk.internal.classfile.constantpool
* java.base/jdk.internal.classfile.instruction
* java.base/jdk.internal.classfile.components
* java.base/jdk.internal.classfile.impl
* @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
* @run main SymLinkShortNameTest
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,12 @@
* @test
* @bug 8025998 8026749 8054220 8058227
* @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
* @run main LocalVariableTable
*/
@ -33,7 +38,8 @@
import java.io.*;
import java.lang.annotation.*;
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
@ -42,12 +48,12 @@ import com.sun.tools.classfile.*;
*
* 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
* 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.
*
* The test looks for test cases represented by nested classes whose
* 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
* expected names in the LVT is provided in an annotation on the class for
* the test case.
@ -81,29 +87,28 @@ public class LocalVariableTable {
return;
}
ClassFile cf = ClassFile.read(getClass().getResource(c.getName() + ".class").openStream());
Method m = getLambdaMethod(cf);
ClassModel cm = Classfile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")).openStream().readAllBytes());
MethodModel m = getLambdaMethod(cm);
if (m == null) {
error("lambda method not found");
return;
}
Code_attribute code = (Code_attribute) m.attributes.get(Attribute.Code);
CodeAttribute code = m.findAttribute(Attributes.CODE).orElse(null);
if (code == null) {
error("Code attribute not found");
return;
}
LocalVariableTable_attribute lvt =
(LocalVariableTable_attribute) code.attributes.get(Attribute.LocalVariableTable);
LocalVariableTableAttribute lvt = code.findAttribute(Attributes.LOCAL_VARIABLE_TABLE).orElse(null);
if (lvt == null) {
error("LocalVariableTable attribute not found");
return;
}
Set<String> foundNames = new LinkedHashSet<>();
for (LocalVariableTable_attribute.Entry e: lvt.local_variable_table) {
foundNames.add(cf.constant_pool.getUTF8Value(e.name_index));
for (LocalVariableInfo e: lvt.localVariables()) {
foundNames.add(e.name().stringValue());
}
Set<String> expectNames = new LinkedHashSet<>(Arrays.asList(expect.value()));
@ -120,9 +125,9 @@ public class LocalVariableTable {
}
/** Get a method whose name begins "lambda$...". */
Method getLambdaMethod(ClassFile cf) throws ConstantPoolException {
for (Method m: cf.methods) {
if (m.getName(cf.constant_pool).startsWith("lambda$"))
MethodModel getLambdaMethod(ClassModel cf) {
for (MethodModel m: cf.methods()) {
if (m.methodName().stringValue().startsWith("lambda$"))
return m;
}
return null;

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