diff --git a/test/jdk/java/lang/StackWalker/TestBCI.java b/test/jdk/java/lang/StackWalker/TestBCI.java index c7d3a332ce1..3cba0505e9c 100644 --- a/test/jdk/java/lang/StackWalker/TestBCI.java +++ b/test/jdk/java/lang/StackWalker/TestBCI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, 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 @@ -25,22 +25,18 @@ * @test * @bug 8140450 * @summary Basic test for the StackWalker::getByteCodeIndex method - * @modules jdk.jdeps/com.sun.tools.classfile + * @enablePreview * @run main TestBCI */ -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.Descriptor; -import com.sun.tools.classfile.LineNumberTable_attribute; -import com.sun.tools.classfile.Method; - import java.lang.StackWalker.StackFrame; import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.constant.MethodTypeDesc; import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -66,12 +62,12 @@ public class TestBCI { private final Map methods; private final Class clazz; - TestBCI(Class c) throws ConstantPoolException, IOException { + TestBCI(Class c) throws IllegalArgumentException, IOException { Map methods; String filename = c.getName().replace('.', '/') + ".class"; try (InputStream in = c.getResourceAsStream(filename)) { - ClassFile cf = ClassFile.read(in); - methods = Arrays.stream(cf.methods) + var cf = ClassFile.of().parse(in.readAllBytes()); + methods = cf.methods().stream() .map(m -> new MethodInfo(cf, m)) .collect(Collectors.toMap(MethodInfo::name, Function.identity())); } @@ -129,37 +125,20 @@ public class TestBCI { } static class MethodInfo { - final Method method; + final MethodModel method; final String name; - final String paramTypes; - final String returnType; + final MethodTypeDesc desc; final Map> bciToLineNumbers = new HashMap<>(); - MethodInfo(ClassFile cf, Method m) { + MethodInfo(ClassModel cf, MethodModel m) { this.method = m; - - String name; - String paramTypes; - String returnType; - LineNumberTable_attribute.Entry[] lineNumberTable; - try { - // method name - name = m.getName(cf.constant_pool); - // signature - paramTypes = m.descriptor.getParameterTypes(cf.constant_pool); - returnType = m.descriptor.getReturnType(cf.constant_pool); - Code_attribute codeAttr = (Code_attribute) - m.attributes.get(Attribute.Code); - lineNumberTable = ((LineNumberTable_attribute) - codeAttr.attributes.get(Attribute.LineNumberTable)).line_number_table; - } catch (ConstantPoolException|Descriptor.InvalidDescriptor e) { - throw new RuntimeException(e); - } - this.name = name; - this.paramTypes = paramTypes; - this.returnType = returnType; - Arrays.stream(lineNumberTable).forEach(entry -> - bciToLineNumbers.computeIfAbsent(entry.start_pc, _n -> new TreeSet<>()) - .add(entry.line_number)); + this.name = m.methodName().stringValue(); + this.desc = m.methodTypeSymbol(); + m.code().orElseThrow(() -> new IllegalArgumentException("Missing Code in " + m)) + .findAttribute(Attributes.LINE_NUMBER_TABLE) + .orElseThrow(() -> new IllegalArgumentException("Missing LineNumberTable in " + m)) + .lineNumbers().forEach(entry -> + bciToLineNumbers.computeIfAbsent(entry.startPc(), _ -> new TreeSet<>()) + .add(entry.lineNumber())); } String name() { @@ -178,7 +157,7 @@ public class TestBCI { public String toString() { StringBuilder sb = new StringBuilder(); sb.append(name); - sb.append(paramTypes).append(returnType).append(" "); + sb.append(desc.displayDescriptor()).append(" "); bciToLineNumbers.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .forEach(entry -> sb.append("bci:").append(entry.getKey()).append(" ") diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/CallerSensitiveFinder.java b/test/jdk/jdk/internal/reflect/CallerSensitive/CallerSensitiveFinder.java index 763222e6845..a313aab2552 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/CallerSensitiveFinder.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/CallerSensitiveFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ -21,12 +21,16 @@ * questions. */ -import com.sun.tools.classfile.*; -import static com.sun.tools.classfile.ConstantPool.*; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.UncheckedIOException; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.Opcode; +import java.lang.classfile.constantpool.MethodRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -47,7 +51,7 @@ import java.util.stream.Stream; * @bug 8010117 * @summary Verify if CallerSensitive methods are annotated with * CallerSensitive annotation - * @modules jdk.jdeps/com.sun.tools.classfile jdk.jdeps/com.sun.tools.jdeps + * @enablePreview * @build CallerSensitiveFinder * @run main/othervm/timeout=900 CallerSensitiveFinder */ @@ -87,58 +91,71 @@ public class CallerSensitiveFinder { } private final List csMethodsMissingAnnotation = new CopyOnWriteArrayList<>(); - private final ReferenceFinder finder; public CallerSensitiveFinder() { - this.finder = new ReferenceFinder(getFilter(), getVisitor()); pool = Executors.newFixedThreadPool(numThreads); } - private ReferenceFinder.Filter getFilter() { - final String classname = "jdk/internal/reflect/Reflection"; - final String method = "getCallerClass"; - return new ReferenceFinder.Filter() { - public boolean accept(ConstantPool cpool, CPRefInfo cpref) { - try { - CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo(); - return cpref.getClassName().equals(classname) && nat.getName().equals(method); - } catch (ConstantPoolException ex) { - throw new RuntimeException(ex); + private void check(ClassModel clazz) { + final String className = "jdk/internal/reflect/Reflection"; + final String methodName = "getCallerClass"; + boolean checkMethods = false; + for (var pe : clazz.constantPool()) { + if (pe instanceof MethodRefEntry ref + && ref.owner().name().equalsString(className) + && ref.name().equalsString(methodName)) { + checkMethods = true; + } + } + + if (!checkMethods) + return; + + for (var method : clazz.methods()) { + var code = method.code().orElse(null); + if (code == null) + continue; + + boolean needsCsm = false; + for (var element : code) { + if (element instanceof InvokeInstruction invoke + && invoke.opcode() == Opcode.INVOKESTATIC + && invoke.method() instanceof MethodRefEntry ref + && ref.owner().name().equalsString(className) + && ref.name().equalsString(methodName)) { + needsCsm = true; + break; } } - }; + + if (needsCsm) { + process(clazz, method); + } + } } - private ReferenceFinder.Visitor getVisitor() { - return new ReferenceFinder.Visitor() { - public void visit(ClassFile cf, Method m, List refs) { - try { - // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass - // which is a "special" delegate to the internal getCallerClass - if (cf.getName().equals("sun/reflect/Reflection") && - m.getName(cf.constant_pool).equals("getCallerClass")) - return; + private void process(ClassModel cf, MethodModel m) { + // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass + // which is a "special" delegate to the internal getCallerClass + if (cf.thisClass().name().equalsString("sun/reflect/Reflection") && + m.methodName().equalsString("getCallerClass")) + return; - String name = String.format("%s#%s %s", cf.getName(), - m.getName(cf.constant_pool), - m.descriptor.getValue(cf.constant_pool)); - if (!CallerSensitiveFinder.isCallerSensitive(m, cf.constant_pool)) { - csMethodsMissingAnnotation.add(name); - System.err.println("Missing @CallerSensitive: " + name); - } else { - if (verbose) { - System.out.format("@CS %s%n", name); - } - } - } catch (ConstantPoolException ex) { - throw new RuntimeException(ex); - } + String name = cf.thisClass().asInternalName() + '#' + + m.methodName().stringValue() + ' ' + + m.methodType().stringValue(); + if (!CallerSensitiveFinder.isCallerSensitive(m)) { + csMethodsMissingAnnotation.add(name); + System.err.println("Missing @CallerSensitive: " + name); + } else { + if (verbose) { + System.out.format("@CS %s%n", name); } - }; + } } public List run(Stream classes)throws IOException, InterruptedException, - ExecutionException, ConstantPoolException + ExecutionException, IllegalArgumentException { classes.forEach(p -> pool.submit(getTask(p))); waitForCompletion(); @@ -146,16 +163,11 @@ public class CallerSensitiveFinder { } private static final String CALLER_SENSITIVE_ANNOTATION = "Ljdk/internal/reflect/CallerSensitive;"; - private static boolean isCallerSensitive(Method m, ConstantPool cp) - throws ConstantPoolException - { - RuntimeAnnotations_attribute attr = - (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations); + private static boolean isCallerSensitive(MethodModel m) { + var attr = m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null); if (attr != null) { - for (int i = 0; i < attr.annotations.length; i++) { - Annotation ann = attr.annotations[i]; - String annType = cp.getUTF8Value(ann.type_index); - if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) { + for (var ann : attr.annotations()) { + if (ann.className().equalsString(CALLER_SENSITIVE_ANNOTATION)) { return true; } } @@ -174,12 +186,11 @@ public class CallerSensitiveFinder { private FutureTask getTask(Path p) { FutureTask task = new FutureTask<>(new Callable<>() { public Void call() throws Exception { - try (InputStream is = Files.newInputStream(p)) { - finder.parse(ClassFile.read(is)); + try { + var clz = ClassFile.of().parse(p); // propagate IllegalArgumentException + check(clz); } catch (IOException x) { throw new UncheckedIOException(x); - } catch (ConstantPoolException x) { - throw new RuntimeException(x); } return null; } diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java index 0a9d75e27a8..0a8a0ccfaea 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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 @@ -21,21 +21,23 @@ * questions. */ -import com.sun.tools.classfile.*; - -import static com.sun.tools.classfile.AccessFlags.ACC_PRIVATE; -import static com.sun.tools.classfile.ConstantPool.*; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.UncheckedIOException; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.Opcode; +import java.lang.classfile.constantpool.MethodRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; +import java.lang.reflect.AccessFlag; import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -50,12 +52,13 @@ import java.util.concurrent.FutureTask; import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.lang.constant.ConstantDescs.CD_Class; + /* * @test * @summary CallerSensitive methods should be static or final instance * methods except the known list of non-final instance methods - * @modules jdk.jdeps/com.sun.tools.classfile - * jdk.jdeps/com.sun.tools.jdeps + * @enablePreview * @build CheckCSMs * @run main/othervm/timeout=900 CheckCSMs */ @@ -66,7 +69,7 @@ public class CheckCSMs { // The goal is to remove this list of Non-final instance @CS methods // over time. Do not add any new one to this list. - private static Set KNOWN_NON_FINAL_CSMS = + private static final Set KNOWN_NON_FINAL_CSMS = Set.of("java/io/ObjectStreamField#getType ()Ljava/lang/Class;", "java/lang/Runtime#load (Ljava/lang/String;)V", "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V", @@ -111,119 +114,120 @@ public class CheckCSMs { private final Set nonFinalCSMs = new ConcurrentSkipListSet<>(); private final Map> csmWithCallerParameter = new ConcurrentHashMap<>(); - private final ReferenceFinder finder; public CheckCSMs() { - this.finder = new ReferenceFinder(getFilter(), getVisitor()); pool = Executors.newFixedThreadPool(numThreads); - } public Set run(Stream classes) throws IOException, InterruptedException, ExecutionException, - ConstantPoolException + IllegalArgumentException { classes.forEach(p -> pool.submit(getTask(p))); waitForCompletion(); return nonFinalCSMs; } + private void check(ClassModel clazz) { + final String className = "jdk/internal/reflect/Reflection"; + final String methodName = "getCallerClass"; + boolean checkMethods = false; + for (var pe : clazz.constantPool()) { + if (pe instanceof MethodRefEntry ref + && ref.owner().name().equalsString(className) + && ref.name().equalsString(methodName)) { + checkMethods = true; + } + } - private ReferenceFinder.Filter getFilter() { - final String classname = "jdk/internal/reflect/Reflection"; - final String method = "getCallerClass"; - return new ReferenceFinder.Filter() { - public boolean accept(ConstantPool cpool, CPRefInfo cpref) { - try { - CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo(); - return cpref.getClassName().equals(classname) && nat.getName().equals(method); - } catch (ConstantPoolException ex) { - throw new RuntimeException(ex); + if (!checkMethods) + return; + + for (var method : clazz.methods()) { + var code = method.code().orElse(null); + if (code == null) + continue; + + boolean needsCsm = false; + for (var element : code) { + if (element instanceof InvokeInstruction invoke + && invoke.opcode() == Opcode.INVOKESTATIC + && invoke.method() instanceof MethodRefEntry ref + && ref.owner().name().equalsString(className) + && ref.name().equalsString(methodName)) { + needsCsm = true; + break; } } - }; - } - private ReferenceFinder.Visitor getVisitor() { - return new ReferenceFinder.Visitor() { - public void visit(ClassFile cf, Method m, List refs) { - try { - // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass - // which is a "special" delegate to the internal getCallerClass - if (cf.getName().equals("sun/reflect/Reflection") && - m.getName(cf.constant_pool).equals("getCallerClass")) - return; - - String name = methodSignature(cf, m); - if (!CheckCSMs.isStaticOrFinal(cf, m, cf.constant_pool)) { - System.err.println("Unsupported @CallerSensitive: " + name); - nonFinalCSMs.add(name); - } else { - if (listCSMs) { - System.out.format("@CS %s%n", name); - } - } - - // find the adapter implementation for CSM with the caller parameter - if (!csmWithCallerParameter.containsKey(cf.getName())) { - Set methods = Arrays.stream(cf.methods) - .filter(m0 -> csmWithCallerParameter(cf, m, m0)) - .map(m0 -> methodSignature(cf, m0)) - .collect(Collectors.toSet()); - csmWithCallerParameter.put(cf.getName(), methods); - } - } catch (ConstantPoolException ex) { - throw new RuntimeException(ex); - } + if (needsCsm) { + process(clazz, method); } - }; - } - - private static String methodSignature(ClassFile cf, Method m) { - try { - return String.format("%s#%s %s", cf.getName(), - m.getName(cf.constant_pool), - m.descriptor.getValue(cf.constant_pool)); - } catch (ConstantPoolException ex) { - throw new RuntimeException(ex); } } - private static boolean csmWithCallerParameter(ClassFile cf, Method csm, Method m) { - ConstantPool cp = cf.constant_pool; - try { - int csmParamCount = csm.descriptor.getParameterCount(cp); - int paramCount = m.descriptor.getParameterCount(cp); - // an adapter method must have the same name and return type and a trailing Class parameter - if (!(csm.getName(cp).equals(m.getName(cp)) && - paramCount == (csmParamCount+1) && - m.descriptor.getReturnType(cp).equals(csm.descriptor.getReturnType(cp)))) { + private void process(ClassModel cf, MethodModel m) { + // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass + // which is a "special" delegate to the internal getCallerClass + if (cf.thisClass().name().equalsString("sun/reflect/Reflection") + && m.methodName().equalsString("getCallerClass")) + return; + + String name = methodSignature(cf, m); + if (!CheckCSMs.isStaticOrFinal(cf, m)) { + System.err.println("Unsupported @CallerSensitive: " + name); + nonFinalCSMs.add(name); + } else { + if (listCSMs) { + System.out.format("@CS %s%n", name); + } + } + + // find the adapter implementation for CSM with the caller parameter + if (!csmWithCallerParameter.containsKey(cf.thisClass().asInternalName())) { + Set methods = cf.methods().stream() + .filter(m0 -> csmWithCallerParameter(cf, m, m0)) + .map(m0 -> methodSignature(cf, m0)) + .collect(Collectors.toSet()); + csmWithCallerParameter.put(cf.thisClass().asInternalName(), methods); + } + } + + private static String methodSignature(ClassModel cf, MethodModel m) { + return cf.thisClass().asInternalName() + '#' + + m.methodName().stringValue() + ' ' + + m.methodType().stringValue(); + } + + private static boolean csmWithCallerParameter(ClassModel cf, MethodModel csm, MethodModel m) { + var csmType = csm.methodTypeSymbol(); + var mType = m.methodTypeSymbol(); + // an adapter method must have the same name and return type and a trailing Class parameter + if (!(csm.methodName().equals(m.methodName()) && + mType.parameterCount() == (csmType.parameterCount() + 1) && + mType.returnType().equals(csmType.returnType()))) { + return false; + } + // the descriptor of the adapter method must have the parameters + // of the caller-sensitive method and an additional Class parameter + for (int i = 0; i < csmType.parameterCount(); i++) { + if (mType.parameterType(i) != csmType.parameterType(i)) { return false; } - // the descriptor of the adapter method must have the parameters - // of the caller-sensitive method and an additional Class parameter - String csmDesc = csm.descriptor.getParameterTypes(cp); - String desc = m.descriptor.getParameterTypes(cp); - int index = desc.indexOf(", java.lang.Class)"); - if (index == -1) { - index = desc.indexOf("java.lang.Class)"); - if (index == -1) return false; - } - String s = desc.substring(0, index) + ")"; - if (s.equals(csmDesc)) { - if (!m.access_flags.is(ACC_PRIVATE)) { - throw new RuntimeException(methodSignature(cf, m) + " adapter method for " + - methodSignature(cf, csm) + " must be private"); - } - if (!isCallerSensitiveAdapter(m, cp)) { - throw new RuntimeException(methodSignature(cf, m) + " adapter method for " + - methodSignature(cf, csm) + " must be annotated with @CallerSensitiveAdapter"); - } - return true; - } - } catch (ConstantPoolException|Descriptor.InvalidDescriptor e) { - throw new RuntimeException(e); } - return false; + + if (!mType.parameterType(mType.parameterCount() - 1).equals(CD_Class)) { + return false; + } + + if (!m.flags().has(AccessFlag.PRIVATE)) { + throw new RuntimeException(methodSignature(cf, m) + " adapter method for " + + methodSignature(cf, csm) + " must be private"); + } + if (!isCallerSensitiveAdapter(m)) { + throw new RuntimeException(methodSignature(cf, m) + " adapter method for " + + methodSignature(cf, csm) + " must be annotated with @CallerSensitiveAdapter"); + } + return true; } private static final String CALLER_SENSITIVE_ANNOTATION @@ -231,16 +235,13 @@ public class CheckCSMs { private static final String CALLER_SENSITIVE_ADAPTER_ANNOTATION = "Ljdk/internal/reflect/CallerSensitiveAdapter;"; - private static boolean isCallerSensitive(Method m, ConstantPool cp) - throws ConstantPoolException + private static boolean isCallerSensitive(MethodModel m) + throws IllegalArgumentException { - RuntimeAnnotations_attribute attr = - (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations); + var attr = m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null); if (attr != null) { - for (int i = 0; i < attr.annotations.length; i++) { - Annotation ann = attr.annotations[i]; - String annType = cp.getUTF8Value(ann.type_index); - if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) { + for (var ann : attr.annotations()) { + if (ann.className().equalsString(CALLER_SENSITIVE_ANNOTATION)) { return true; } } @@ -248,16 +249,12 @@ public class CheckCSMs { return false; } - private static boolean isCallerSensitiveAdapter(Method m, ConstantPool cp) - throws ConstantPoolException - { - RuntimeAnnotations_attribute attr = - (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeInvisibleAnnotations); + private static boolean isCallerSensitiveAdapter(MethodModel m) { + var attr = m.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null); + if (attr != null) { - for (int i = 0; i < attr.annotations.length; i++) { - Annotation ann = attr.annotations[i]; - String annType = cp.getUTF8Value(ann.type_index); - if (CALLER_SENSITIVE_ADAPTER_ANNOTATION.equals(annType)) { + for (var ann : attr.annotations()) { + if (ann.className().equalsString(CALLER_SENSITIVE_ADAPTER_ANNOTATION)) { return true; } } @@ -265,16 +262,14 @@ public class CheckCSMs { return false; } - private static boolean isStaticOrFinal(ClassFile cf, Method m, ConstantPool cp) - throws ConstantPoolException - { - if (!isCallerSensitive(m, cp)) + private static boolean isStaticOrFinal(ClassModel cf, MethodModel m) { + if (!isCallerSensitive(m)) return false; // either a static method or a final instance method - return m.access_flags.is(AccessFlags.ACC_STATIC) || - m.access_flags.is(AccessFlags.ACC_FINAL) || - cf.access_flags.is(AccessFlags.ACC_FINAL); + return m.flags().has(AccessFlag.STATIC) || + m.flags().has(AccessFlag.FINAL) || + cf.flags().has(AccessFlag.FINAL); } private final List> tasks = new ArrayList<>(); @@ -288,12 +283,11 @@ public class CheckCSMs { private FutureTask getTask(Path p) { FutureTask task = new FutureTask<>(new Callable<>() { public Void call() throws Exception { - try (InputStream is = Files.newInputStream(p)) { - finder.parse(ClassFile.read(is)); + try { + var clz = ClassFile.of().parse(p); // propagate IllegalArgumentException + check(clz); } catch (IOException x) { throw new UncheckedIOException(x); - } catch (ConstantPoolException x) { - throw new RuntimeException(x); } return null; } diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/MissingCallerSensitive.java b/test/jdk/jdk/internal/reflect/CallerSensitive/MissingCallerSensitive.java index b9d4706fe40..781c75b23ae 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/MissingCallerSensitive.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/MissingCallerSensitive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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,8 +27,7 @@ * @bug 8010117 * @summary Test CallerSensitiveFinder to find missing annotation * @modules java.base/jdk.internal.reflect - * jdk.jdeps/com.sun.tools.classfile - * jdk.jdeps/com.sun.tools.jdeps + * @enablePreview * @compile -XDignore.symbol.file MissingCallerSensitive.java * @build CallerSensitiveFinder * @run main MissingCallerSensitive diff --git a/test/langtools/jdk/javadoc/tool/CheckResourceKeys.java b/test/langtools/jdk/javadoc/tool/CheckResourceKeys.java index 0a72e7dff89..f188aa036f4 100644 --- a/test/langtools/jdk/javadoc/tool/CheckResourceKeys.java +++ b/test/langtools/jdk/javadoc/tool/CheckResourceKeys.java @@ -29,15 +29,17 @@ * jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.resources:open * jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.resources:open * jdk.javadoc/jdk.javadoc.internal.tool.resources:open - * jdk.jdeps/com.sun.tools.classfile + * @enablePreview */ import java.io.*; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.constantpool.Utf8Entry; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.tools.*; -import com.sun.tools.classfile.*; /** * Compare string constants in javadoc classes against keys in javadoc resource bundles. @@ -268,15 +270,15 @@ public class CheckResourceKeys { //System.err.println("scan " + fo.getName()); InputStream in = fo.openInputStream(); try { - 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 cf = ClassFile.of().parse(in.readAllBytes()); + for (var cpinfo : cf.constantPool()) { + if (cpinfo instanceof Utf8Entry utf8Entry) { + String v = utf8Entry.stringValue(); if (v.matches("(doclet|main|javadoc|tag)\\.[A-Za-z0-9-_.]+")) results.add(v); } } - } catch (ConstantPoolException ignore) { + } catch (IllegalArgumentException ignore) { } finally { in.close(); } diff --git a/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java b/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java index e81db00e5df..734b1741682 100644 --- a/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java +++ b/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ -25,60 +25,66 @@ * @test * @bug 7166455 * @summary javac doesn't set ACC_STRICT bit on for strictfp class - * @modules jdk.jdeps/com.sun.tools.classfile - * @compile -source 16 -target 16 CheckACC_STRICTFlagOnclinitTest.java - * @run main CheckACC_STRICTFlagOnclinitTest + * @library /tools/lib /test/lib + * @enablePreview */ +import jdk.test.lib.compiler.CompilerUtils; +import toolbox.ToolBox; + +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.nio.file.Path; 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; - -public strictfp class CheckACC_STRICTFlagOnclinitTest { +public class CheckACC_STRICTFlagOnclinitTest { private static final String AssertionErrorMessage = "All methods should have the ACC_STRICT access flag " + "please check output"; private static final String offendingMethodErrorMessage = "Method %s of class %s doesn't have the ACC_STRICT access flag"; - static { - class Foo { - class Bar { - void m11() {} + private static final String SOURCE = """ + public strictfp class Test { + static { + class Foo { + class Bar { + void m11() {} + } + void m1() {} + } + } + void m2() { + class Any { + void m21() {} + } + } } - void m1() {} - } - } - void m2() { - class Any { - void m21() {} - } - } + """; - private List errors = new ArrayList<>(); + private final List errors = new ArrayList<>(); public static void main(String[] args) - throws IOException, ConstantPoolException, InvalidDescriptor { + throws IOException { new CheckACC_STRICTFlagOnclinitTest().run(); } private void run() - throws IOException, ConstantPoolException, InvalidDescriptor { - String testClasses = System.getProperty("test.classes"); - check(testClasses, - "CheckACC_STRICTFlagOnclinitTest.class", - "CheckACC_STRICTFlagOnclinitTest$1Foo.class", - "CheckACC_STRICTFlagOnclinitTest$1Foo$Bar.class", - "CheckACC_STRICTFlagOnclinitTest$1Any.class"); - if (errors.size() > 0) { + throws IOException { + Path in = Path.of("in"); + Path out = Path.of("out"); + ToolBox toolBox = new ToolBox(); + toolBox.writeJavaFiles(in, SOURCE); + CompilerUtils.compile(in, out, "--release", "16"); + check(out, + "Test.class", + "Test$1Foo.class", + "Test$1Foo$Bar.class", + "Test$1Any.class"); + if (!errors.isEmpty()) { for (String error: errors) { System.err.println(error); } @@ -86,37 +92,17 @@ public strictfp class CheckACC_STRICTFlagOnclinitTest { } } - void check(String dir, String... fileNames) - throws - IOException, - ConstantPoolException, - Descriptor.InvalidDescriptor { + void check(Path dir, String... fileNames) throws IOException { for (String fileName : fileNames) { - ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); + ClassModel classFileToCheck = ClassFile.of().parse(dir.resolve(fileName)); - 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())); } } } } - -// this version of the code can be used when ClassFile API in not in a preview -// void check(String dir, String... fileNames) throws IOException{ -// for (String fileName : fileNames) { -// ClassModel classFileToCheck = ClassFile.of().parse(new File(dir, fileName).toPath()); -// -// for (MethodModel method : classFileToCheck.methods()) { -// if ((method.flags().flagsMask() & ClassFile.ACC_STRICT) == 0) { -// errors.add(String.format(offendingMethodErrorMessage, -// method.methodName().stringValue(), -// classFileToCheck.thisClass().asInternalName())); -// } -// } -// } -// } - } diff --git a/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java b/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java index 39b9cd52998..72576a7fcb8 100644 --- a/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java +++ b/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, 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 @@ -21,76 +21,78 @@ * 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.test.lib.compiler.CompilerUtils; +import toolbox.ToolBox; -import java.io.File; +import java.lang.classfile.Attributes; +import java.lang.classfile.BootstrapMethodEntry; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.CodeElement; +import java.lang.classfile.MethodModel; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MethodHandleEntry; +import java.lang.classfile.instruction.InvokeDynamicInstruction; +import java.nio.file.Path; /* * @test * @bug 8148483 8151516 8151223 * @summary Test that StringConcat is working for JDK >= 9 - * @modules jdk.jdeps/com.sun.tools.classfile - * - * @clean * - * @compile -source 8 -target 8 TestIndyStringConcat.java - * @run main TestIndyStringConcat false - * - * @clean * - * @compile -XDstringConcat=inline TestIndyStringConcat.java - * @run main TestIndyStringConcat false - * - * @clean * - * @compile -XDstringConcat=indy TestIndyStringConcat.java - * @run main TestIndyStringConcat true - * - * @clean * - * @compile -XDstringConcat=indyWithConstants TestIndyStringConcat.java - * @run main TestIndyStringConcat true + * @library /tools/lib /test/lib + * @enablePreview + * @run main TestIndyStringConcat */ public class TestIndyStringConcat { - static String other; + private static final String SOURCE = """ + public class IndyStringConcat { + static String other; - public static String test() { - return "Foo" + other; - } + public static String test() { + return "Foo" + other; + } + } + """; public static void main(String[] args) throws Exception { - boolean expected = Boolean.valueOf(args[0]); - boolean actual = hasStringConcatFactoryCall("test"); - if (expected != actual) { - throw new AssertionError("expected = " + expected + ", actual = " + actual); + Path src = Path.of("src"); + ToolBox toolBox = new ToolBox(); + toolBox.writeJavaFiles(src, SOURCE); + + int errors = 0; + errors += test(false, "java8", "-source", "8", "-target", "8"); + errors += test(false, "inline", "-XDstringConcat=inline"); + errors += test(true, "indy", "-XDstringConcat=indy"); + errors += test(true, "indyWithConstants", "-XDstringConcat=indyWithConstants"); + + if (errors > 0) { + throw new AssertionError(errors + " cases failed"); } } - 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; + public static int test(boolean expected, String label, String... args) throws Exception { + Path src = Path.of("src"); + Path out = Path.of(label); + CompilerUtils.compile(src, out, args); + if (hasStringConcatFactoryCall(out.resolve("IndyStringConcat.class"), "test") != expected) { + System.err.println("Expected " + expected + " failed for case " + label); + return 1; + } + return 0; + } - BootstrapMethods_attribute bsm_attr = - (BootstrapMethods_attribute)classFile - .getAttribute(Attribute.BootstrapMethods); + public static boolean hasStringConcatFactoryCall(Path file, String methodName) throws Exception { + ClassModel classFile = ClassFile.of().parse(file); - 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 indy) { + BootstrapMethodEntry bsmSpec = indy.invokedynamic().bootstrap(); + MethodHandleEntry bsmInfo = bsmSpec.bootstrapMethod(); + if (bsmInfo.reference().owner().asInternalName().equals("java/lang/invoke/StringConcatFactory")) { return true; } } @@ -100,27 +102,4 @@ public class TestIndyStringConcat { return false; } -// this version of the code can be used when ClassFile API in not in a preview -// public static boolean hasStringConcatFactoryCall(String methodName) throws Exception { -// ClassModel classFile = ClassFile.of().parse(new File(System.getProperty("test.classes", "."), -// TestIndyStringConcat.class.getName() + ".class").toPath()); -// -// 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; -// } -// } -// } -// } -// } -// return false; -// } - } diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java deleted file mode 100644 index b8fdcff4e88..00000000000 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, 2016, 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.Attribute; -import com.sun.tools.classfile.ClassFile; -import com.sun.tools.classfile.SourceFile_attribute; - -import java.io.InputStream; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.tools.JavaFileObject; - -import toolbox.ToolBox; - -/** - * Base class for Source file attribute tests. Checks expected file name for specified classes in the SourceFile attribute. - * To add new tests you should extend the SourceFileTestBase class and invoke {@link #test} for static sources - * or {@link #compileAndTest} for generated sources. For more information see corresponding methods. - * - * @see #test - * @see #compileAndTest - */ -public class SourceFileTestBase_legacy extends TestBase { - /** - * Checks expected fileName for the specified class in the SourceFile attribute. - * - * @param classToTest class to check its SourceFile attribute - * @param fileName expected name of the file from which the test file is compiled. - */ - protected void test(Class classToTest, String fileName) throws Exception { - assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName); - } - - /** - * Checks expected fileName for the specified class in the SourceFile attribute. - * - * @param classToTest class name to check its SourceFile attribute - * @param fileName expected name of the file from which the test file is compiled. - */ - protected void test(String classToTest, String fileName) throws Exception { - assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName); - } - - /** - * Checks expected fileName for the specified class in the SourceFile attribute. - * - * @param classToTest path of class to check its SourceFile attribute - * @param fileName expected name of the file from which the test file is compiled. - */ - protected void test(Path classToTest, String fileName) throws Exception { - assertAttributePresent(ClassFile.read(classToTest), fileName); - } - - /** - * Compiles sourceCode and for each specified class name checks the SourceFile attribute. - * The file name is extracted from source code. - * - * @param sourceCode source code to compile - * @param classesToTest class names to check their SourceFile attribute. - */ - protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception { - - Map classes = compile(sourceCode).getClasses(); - String fileName = ToolBox.getJavaFileNameFromSource(sourceCode); - for (String className : classesToTest) { - ClassFile classFile; - try (InputStream input = classes.get(className).openInputStream()) { - classFile = ClassFile.read(input); - } - assertAttributePresent(classFile, fileName); - } - } - - private void assertAttributePresent(ClassFile classFile, String fileName) throws Exception { - - //We need to count attributes with the same names because there is no appropriate API in the ClassFile. - - List sourceFileAttributes = new ArrayList<>(); - for (Attribute a : classFile.attributes.attrs) { - if (Attribute.SourceFile.equals(a.getName(classFile.constant_pool))) { - sourceFileAttributes.add((SourceFile_attribute) a); - } - } - - assertEquals(sourceFileAttributes.size(), 1, "Should be the only SourceFile attribute"); - - SourceFile_attribute attribute = sourceFileAttributes.get(0); - - assertEquals(classFile.constant_pool.getUTF8Info(attribute.attribute_name_index).value, - Attribute.SourceFile, "Incorrect attribute name"); - assertEquals(classFile.constant_pool.getUTF8Info(attribute.sourcefile_index).value, fileName, - "Incorrect source file name"); - assertEquals(attribute.attribute_length, 2, "Incorrect attribute length"); - } -} diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java index 92a6e6b9bae..33f55545d81 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -25,27 +25,49 @@ * @test * @summary sourcefile attribute test for synthetic class. * @bug 8040129 - * @library /tools/lib /tools/javac/lib ../lib_legacy + * @library /tools/lib /tools/javac/lib /test/lib ../lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * jdk.jdeps/com.sun.tools.classfile - * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase_legacy - * @compile -source 10 -target 10 SyntheticClassTest.java - * @run main SyntheticClassTest true - * @clean SyntheticClassTest$1 - * @compile SyntheticClassTest.java - * @run main SyntheticClassTest false + * java.base/jdk.internal.classfile.impl + * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase + * @enablePreview + * @run main SyntheticClassTest */ +import jdk.test.lib.compiler.CompilerUtils; +import toolbox.ToolBox; + import java.nio.file.NoSuchFileException; +import java.nio.file.Path; -public class SyntheticClassTest extends SourceFileTestBase_legacy { +public class SyntheticClassTest extends SourceFileTestBase { public static void main(String[] args) throws Exception { - boolean expectSynthetic = Boolean.parseBoolean(args[0]); - new Inner(); + String sourceCode = """ + public class SyntheticClass { + static class Inner { + private Inner() { + } + } + public SyntheticClass() { + new Inner(); + } + } + """; + Path srcDir = Path.of("src"); + Path v10Dir = Path.of("out10"); + Path modernDir = Path.of("out"); + ToolBox toolBox = new ToolBox(); + toolBox.writeJavaFiles(srcDir, sourceCode); + CompilerUtils.compile(srcDir, v10Dir, "--release", "10"); + CompilerUtils.compile(srcDir, modernDir); + test(v10Dir, true); + test(modernDir, false); + } + + private static void test(Path path, boolean expectSynthetic) throws Exception { try { - new SyntheticClassTest().test("SyntheticClassTest$1", "SyntheticClassTest.java"); + new SyntheticClassTest().test(path.resolve("SyntheticClass$1.class"), "SyntheticClass.java"); if (!expectSynthetic) { throw new AssertionError("Synthetic class should not have been emitted!"); } @@ -55,9 +77,4 @@ public class SyntheticClassTest extends SourceFileTestBase_legacy { } } } - - static class Inner { - private Inner() { - } - } } diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java index 76d5d3c178d..e4dfb5000f5 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, 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 @@ -29,12 +29,14 @@ * compiling with --release 14. * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * jdk.jdeps/com.sun.tools.classfile - * @library /tools/lib /tools/javac/lib ../lib_legacy - * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase - * @build SyntheticTestDriver_legacy ExpectedClass ExpectedClasses + * @library /tools/lib /tools/javac/lib ../lib + * @build toolbox.ToolBox InMemoryFileManager + * ExpectedClass ExpectedClasses + * @compile --enable-preview --source ${jdk.version} --target ${jdk.version} + * SyntheticTestDriver.java + * ../lib/TestResult.java ../lib/TestBase.java * @compile --source 14 -target 14 -XDdeduplicateLambdas=false BridgeMethodsForLambdaTargetRelease14Test.java - * @run main SyntheticTestDriver_legacy BridgeMethodsForLambdaTargetRelease14Test + * @run main/othervm --enable-preview SyntheticTestDriver BridgeMethodsForLambdaTargetRelease14Test */ import java.util.Comparator; diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java deleted file mode 100644 index c9e333b0d4e..00000000000 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2015, 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 java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.regex.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import com.sun.tools.classfile.*; - -/** - * The tests work as follows. Firstly, it looks through the test cases - * and extracts the appropriate compiled classes. Each test case contains - * a set of expected classes, methods and fields. Those class members must not have - * the Synthetic attribute, while other found classes, methods and fields must have - * the Synthetic attribute if they are not in the set of expected class members. - * - * Each test executes SyntheticTestDriver specifying the name of test cases and - * the number of expected synthetic classes. Each test class is annotated by - * annotations which contains non-synthetic class members. - * - * See the appropriate class for more information about a test case. - */ -public class SyntheticTestDriver_legacy extends TestResult { - - private static final String ACC_SYNTHETIC = "ACC_SYNTHETIC"; - - private final String testCaseName; - private final Map classes; - private final Map expectedClasses; - - public static void main(String[] args) - throws TestFailedException, ConstantPoolException, IOException, ClassNotFoundException { - if (args.length != 1 && args.length != 2) { - throw new IllegalArgumentException("Usage: SyntheticTestDriver []"); - } - int numberOfSyntheticClasses = args.length == 1 ? 0 : Integer.parseInt(args[1]); - new SyntheticTestDriver_legacy(args[0]).test(numberOfSyntheticClasses); - } - - public SyntheticTestDriver_legacy(String testCaseName) throws IOException, ConstantPoolException, ClassNotFoundException { - Class clazz = Class.forName(testCaseName); - this.testCaseName = testCaseName; - this.expectedClasses = Stream.of(clazz.getAnnotationsByType(ExpectedClass.class)) - .collect(Collectors.toMap(ExpectedClass::className, Function.identity())); - this.classes = new HashMap<>(); - Path classDir = getClassDir().toPath(); - Pattern filePattern = Pattern.compile(Pattern.quote(testCaseName.replace('.', File.separatorChar)) + ".*\\.class"); - List paths = Files.walk(classDir) - .map(p -> classDir.relativize(p.toAbsolutePath())) - .filter(p -> filePattern.matcher(p.toString()).matches()) - .collect(Collectors.toList()); - for (Path path : paths) { - String className = path.toString().replace(".class", "").replace(File.separatorChar, '.'); - classes.put(className, readClassFile(classDir.resolve(path).toFile())); - } - if (classes.isEmpty()) { - throw new RuntimeException("Classes have not been found."); - } - boolean success = classes.entrySet().stream() - .allMatch(e -> e.getKey().startsWith(testCaseName)); - if (!success) { - classes.forEach((className, $) -> printf("Found class: %s\n", className)); - throw new RuntimeException("Found classes are not from the test case : " + testCaseName); - } - } - - private String getMethodName(ClassFile classFile, Method method) - throws ConstantPoolException, Descriptor.InvalidDescriptor { - String methodName = method.getName(classFile.constant_pool); - String parameters = method.descriptor.getParameterTypes(classFile.constant_pool); - return methodName + parameters; - } - - public void test(int expectedNumberOfSyntheticClasses) throws TestFailedException { - try { - addTestCase(testCaseName); - Set foundClasses = new HashSet<>(); - - int numberOfSyntheticClasses = 0; - for (Map.Entry entry : classes.entrySet()) { - String className = entry.getKey(); - ClassFile classFile = entry.getValue(); - foundClasses.add(className); - if (testAttribute( - classFile, - () -> (Synthetic_attribute) classFile.getAttribute(Attribute.Synthetic), - classFile.access_flags::getClassFlags, - expectedClasses.keySet(), - className, - "Testing class " + className)) { - ++numberOfSyntheticClasses; - } - ExpectedClass expectedClass = expectedClasses.get(className); - Set expectedMethods = expectedClass != null - ? toSet(expectedClass.expectedMethods()) - : new HashSet<>(); - int numberOfSyntheticMethods = 0; - Set foundMethods = new HashSet<>(); - for (Method method : classFile.methods) { - String methodName = getMethodName(classFile, method); - foundMethods.add(methodName); - if (testAttribute( - classFile, - () -> (Synthetic_attribute) method.attributes.get(Attribute.Synthetic), - method.access_flags::getMethodFlags, - expectedMethods, - methodName, - "Testing method " + methodName + " in class " - + className)) { - ++numberOfSyntheticMethods; - } - } - checkContains(foundMethods, expectedMethods, - "Checking that all methods of class " + className - + " without Synthetic attribute have been found"); - checkEquals(numberOfSyntheticMethods, - expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticMethods(), - "Checking number of synthetic methods in class: " + className); - - Set expectedFields = expectedClass != null - ? toSet(expectedClass.expectedFields()) - : new HashSet<>(); - int numberOfSyntheticFields = 0; - Set foundFields = new HashSet<>(); - for (Field field : classFile.fields) { - String fieldName = field.getName(classFile.constant_pool); - foundFields.add(fieldName); - if (testAttribute( - classFile, - () -> (Synthetic_attribute) field.attributes.get(Attribute.Synthetic), - field.access_flags::getFieldFlags, - expectedFields, - fieldName, - "Testing field " + fieldName + " in class " - + className)) { - ++numberOfSyntheticFields; - } - } - checkContains(foundFields, expectedFields, - "Checking that all fields of class " + className - + " without Synthetic attribute have been found"); - checkEquals(numberOfSyntheticFields, - expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticFields(), - "Checking number of synthetic fields in class: " + className); - } - checkContains(foundClasses, expectedClasses.keySet(), - "Checking that all classes have been found"); - checkEquals(numberOfSyntheticClasses, expectedNumberOfSyntheticClasses, - "Checking number of synthetic classes"); - } catch (Exception e) { - addFailure(e); - } finally { - checkStatus(); - } - } - - private boolean testAttribute(ClassFile classFile, - Supplier getSyntheticAttribute, - Supplier> getAccessFlags, - Set expectedMembers, String memberName, - String info) throws ConstantPoolException { - echo(info); - String className = classFile.getName(); - Synthetic_attribute attr = getSyntheticAttribute.get(); - Set flags = getAccessFlags.get(); - if (expectedMembers.contains(memberName)) { - checkNull(attr, "Member must not have synthetic attribute : " - + memberName); - checkFalse(flags.contains(ACC_SYNTHETIC), - "Member must not have synthetic flag : " + memberName - + " in class : " + className); - return false; - } else { - return checkNull(attr, "Synthetic attribute should not be generated") - && checkTrue(flags.contains(ACC_SYNTHETIC), "Member must have synthetic flag : " - + memberName + " in class : " + className); - } - } - - private Set toSet(String[] strings) { - HashSet set = new HashSet<>(); - Collections.addAll(set, strings); - return set; - } -} diff --git a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java deleted file mode 100644 index 08de973cc3f..00000000000 --- a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2014, 2016, 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 java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -import javax.tools.DiagnosticCollector; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.ToolProvider; - -import com.sun.tools.classfile.ClassFile; -import com.sun.tools.classfile.ConstantPoolException; - -import toolbox.JavacTask; -import toolbox.ToolBox; - -/** - * Base class for class file attribute tests. - * Contains methods for compiling generated sources in memory, - * for reading files from disk and a lot of assert* methods. - */ -public class TestBase { - - public static final String LINE_SEPARATOR = System.lineSeparator(); - public static final boolean isDumpOfSourceEnabled = Boolean.getBoolean("dump.src"); - - private InMemoryFileManager compile( - List options, - Function src2JavaFileObject, - List sources) - throws IOException, CompilationException { - - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - List src = sources.stream() - .map(src2JavaFileObject) - .collect(Collectors.toList()); - - DiagnosticCollector dc = new DiagnosticCollector<>(); - try (InMemoryFileManager fileManager - = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) { - JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, dc, options, null, src); - boolean success = task.call(); - if (!success) { - String errorMessage = dc.getDiagnostics().stream() - .map(Object::toString) - .collect(Collectors.joining("\n")); - throw new CompilationException("Compilation Error\n\n" + errorMessage); - } - return fileManager; - } - } - - /** - * Compiles sources in memory. - * - * @param sources to compile - * @return in-memory file manager which contains class files and class loader - */ - public InMemoryFileManager compile(String... sources) - throws IOException, CompilationException { - return compile(Collections.emptyList(), sources); - } - - /** - * Compiles sources in memory. - * - * @param options compiler options. - * @param sources sources to compile. - * @return in-memory file manager which contains class files and class loader. - */ - public InMemoryFileManager compile(List options, String... sources) - throws IOException, CompilationException { - return compile(options, ToolBox.JavaSource::new, Arrays.asList(sources)); - } - - /** - * Compiles sources in memory. - * - * @param sources sources[i][0] - name of file, sources[i][1] - sources. - * @return in-memory file manager which contains class files and class loader. - */ - public InMemoryFileManager compile(String[]... sources) throws IOException, - CompilationException { - return compile(Collections.emptyList(), sources); - } - - /** - * Compiles sources in memory. - * - * @param options compiler options - * @param sources sources[i][0] - name of file, sources[i][1] - sources. - * @return in-memory file manager which contains class files and class loader. - */ - public InMemoryFileManager compile(List options, String[]... sources) - throws IOException, CompilationException { - return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), Arrays.asList(sources)); - } - - /** - * Returns class file that is read from {@code is}. - * - * @param is an input stream - * @return class file that is read from {@code is} - * @throws IOException if I/O error occurs - * @throws ConstantPoolException if constant pool error occurs - */ - public ClassFile readClassFile(InputStream is) throws IOException, ConstantPoolException { - return ClassFile.read(is); - } - - /** - * Returns class file that is read from {@code fileObject}. - * - * @param fileObject a file object - * @return class file that is read from {@code fileObject} - * @throws IOException if I/O error occurs - * @throws ConstantPoolException if constant pool error occurs - */ - public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException { - try (InputStream is = fileObject.openInputStream()) { - return readClassFile(is); - } - } - - /** - * Returns class file that corresponds to {@code clazz}. - * - * @param clazz a class - * @return class file that is read from {@code clazz} - * @throws IOException if I/O error occurs - * @throws ConstantPoolException if constant pool error occurs - */ - public ClassFile readClassFile(Class clazz) throws IOException, ConstantPoolException { - return readClassFile(getClassFile(clazz)); - } - - /** - * Returns class file that corresponds to {@code className}. - * - * @param className a class name - * @return class file that is read from {@code className} - * @throws IOException if I/O error occurs - * @throws ConstantPoolException if constant pool error occurs - */ - public ClassFile readClassFile(String className) throws IOException, ConstantPoolException { - return readClassFile(getClassFile(className + ".class")); - } - - /** - * Returns class file that is read from {@code file}. - * - * @param file a file - * @return class file that is read from {@code file} - * @throws IOException if I/O error occurs - * @throws ConstantPoolException if constant pool error occurs - */ - public ClassFile readClassFile(File file) throws IOException, ConstantPoolException { - try (InputStream is = new FileInputStream(file)) { - return readClassFile(is); - } - } - - public void assertEquals(Object actual, Object expected, String message) { - if (!Objects.equals(actual, expected)) - throw new AssertionFailedException(String.format("%s%nGot: %s, Expected: %s", - message, actual, expected)); - } - - public void assertNull(Object actual, String message) { - assertEquals(actual, null, message); - } - - public void assertNotNull(Object actual, String message) { - if (Objects.isNull(actual)) { - throw new AssertionFailedException(message + " : Expected not null value"); - } - } - - public void assertTrue(boolean actual, String message) { - assertEquals(actual, true, message); - } - - public void assertFalse(boolean actual, String message) { - assertEquals(actual, false, message); - } - - public void assertContains(Set found, Set expected, String message) { - Set copy = new HashSet<>(expected); - copy.removeAll(found); - assertTrue(found.containsAll(expected), message + " : " + copy); - } - - public void writeToFile(Path path, String source) throws IOException { - try (BufferedWriter writer = Files.newBufferedWriter(path)) { - writer.write(source); - } - } - - public void writeToFileIfEnabled(Path path, String source) throws IOException { - if (isDumpOfSourceEnabled) { - writeToFile(path, source); - } else { - System.err.println("Source dumping disabled. To enable, run the test with '-Ddump.src=true'"); - } - } - - public File getSourceDir() { - return new File(System.getProperty("test.src", ".")); - } - - public File getClassDir() { - return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath())); - } - - public File getSourceFile(String fileName) { - return new File(getSourceDir(), fileName); - } - - public File getClassFile(String fileName) { - return new File(getClassDir(), fileName); - } - - public File getClassFile(Class clazz) { - return getClassFile(clazz.getName().replace(".", "/") + ".class"); - } - - /** - * Prints message to standard error. New lines are converted to system dependent NL. - * - * @param message string to print. - */ - public void echo(String message) { - printf(message + "\n"); - } - - /** - * Substitutes args in template and prints result to standard error. - * New lines are converted to system dependent NL. - * - * @param template template in standard String.format(...) format. - * @param args arguments to substitute in template. - */ - public void printf(String template, Object... args) { - System.err.printf(String.format(template, args).replace("\n", LINE_SEPARATOR)); - } - - public static class CompilationException extends Exception { - - public CompilationException(String message) { - super(message); - } - } - - public static class AssertionFailedException extends RuntimeException { - public AssertionFailedException(String message) { - super(message); - } - } -} diff --git a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java deleted file mode 100644 index 4c9662f110f..00000000000 --- a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2014, 2017, 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 java.io.PrintWriter; -import java.io.StringWriter; -import java.util.*; - -/** - * This class accumulates test results. Test results can be checked with method {@code checkStatus}. - */ -public class TestResult extends TestBase { - - private final List testCasesInfo; - - public TestResult() { - testCasesInfo = new ArrayList<>(); - } - - /** - * Adds new test case info. - * - * @param info the information about test case - */ - public void addTestCase(String info) { - System.err.println("Test case: " + info); - testCasesInfo.add(new Info(info)); - } - - public boolean checkEquals(Object actual, Object expected, String message) { - echo("Testing : " + message); - if (!Objects.equals(actual, expected)) { - getLastTestCase().addAssert(String.format("%s\n" + - "Expected: %s,\n" + - " Got: %s", message, expected, actual)); - return false; - } - return true; - } - - public boolean checkNull(Object actual, String message) { - return checkEquals(actual, null, message); - } - - public boolean checkNotNull(Object actual, String message) { - echo("Testing : " + message); - if (Objects.isNull(actual)) { - getLastTestCase().addAssert(message + " : Expected not null value"); - return false; - } - return true; - } - - public boolean checkFalse(boolean actual, String message) { - return checkEquals(actual, false, message); - } - - public boolean checkTrue(boolean actual, String message) { - return checkEquals(actual, true, message); - } - - public boolean checkContains(Collection found, Collection expected, String message) { - Set copy = new HashSet<>(expected); - copy.removeAll(found); - if (!found.containsAll(expected)) { - return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" + - "Actual: " + found); - } else { - return checkTrue(true, message + " PASS : all elements found"); - } - } - - public void addFailure(Throwable th) { - if (testCasesInfo.isEmpty()) { - testCasesInfo.add(new Info("Dummy info")); - } - getLastTestCase().addFailure(th); - } - - private Info getLastTestCase() { - if (testCasesInfo.isEmpty()) { - throw new IllegalStateException("Test case should be created"); - } - return testCasesInfo.get(testCasesInfo.size() - 1); - } - - /** - * Throws {@code TestFailedException} if one of the checks are failed - * or an exception occurs. Prints error message of failed test cases. - * - * @throws TestFailedException if one of the checks are failed - * or an exception occurs - */ - public void checkStatus() throws TestFailedException { - int passed = 0; - int failed = 0; - for (Info testCaseInfo : testCasesInfo) { - if (testCaseInfo.isFailed()) { - String info = testCaseInfo.info().replace("\n", LINE_SEPARATOR); - String errorMessage = testCaseInfo.getMessage().replace("\n", LINE_SEPARATOR); - System.err.printf("Failure in test case:%n%s%n%s%n", info, errorMessage); - ++failed; - } else { - ++passed; - } - } - System.err.printf("Test cases: passed: %d, failed: %d, total: %d.%n", passed, failed, passed + failed); - if (failed > 0) { - throw new TestFailedException("Test failed"); - } - if (passed + failed == 0) { - throw new TestFailedException("Test cases were not found"); - } - } - - @Override - public void printf(String template, Object... args) { - getLastTestCase().printf(template, args); - } - - private static class Info { - - private final String info; - private final StringWriter writer; - private boolean isFailed; - - private Info(String info) { - this.info = info; - writer = new StringWriter(); - } - - public String info() { - return info; - } - - public boolean isFailed() { - return isFailed; - } - - public void printf(String template, Object... args) { - writer.write(String.format(template, args)); - } - - public void addFailure(Throwable th) { - isFailed = true; - printf("[ERROR] : %s\n", getStackTrace(th)); - } - - public void addAssert(String e) { - isFailed = true; - printf("[ASSERT] : %s\n", e); - } - - public String getMessage() { - return writer.toString(); - } - - public String getStackTrace(Throwable throwable) { - StringWriter stringWriter = new StringWriter(); - try (PrintWriter printWriter = new PrintWriter(stringWriter)) { - throwable.printStackTrace(printWriter); - } - return stringWriter.toString(); - } - } - - public static class TestFailedException extends Exception { - public TestFailedException(String message) { - super(message); - } - } -} diff --git a/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java b/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java index 8df5d1e0939..fd321f3a269 100644 --- a/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java +++ b/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ -25,44 +25,51 @@ * @test * @bug 8012723 * @summary strictfp interface misses strictfp modifer on default method - * @modules jdk.jdeps/com.sun.tools.classfile - * @compile -source 16 -target 16 CheckACC_STRICTFlagOnDefaultMethodTest.java + * @library /tools/lib /test/lib + * @enablePreview * @run main CheckACC_STRICTFlagOnDefaultMethodTest */ +import jdk.test.lib.compiler.CompilerUtils; +import toolbox.ToolBox; + +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.nio.file.Path; 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; - public class CheckACC_STRICTFlagOnDefaultMethodTest { private static final String AssertionErrorMessage = "All methods should have the ACC_STRICT access flag " + "please check output"; private static final String offendingMethodErrorMessage = "Method %s of class %s doesn't have the ACC_STRICT access flag"; + private static final String SOURCE = """ + strictfp interface StrictfpInterface { + default void default_interface_method() {} + static void static_interface_method() {} + } + """; private List errors = new ArrayList<>(); public static void main(String[] args) - throws IOException, ConstantPoolException, InvalidDescriptor { + throws IOException { new CheckACC_STRICTFlagOnDefaultMethodTest().run(); } private void run() - throws IOException, ConstantPoolException, InvalidDescriptor { - String testClasses = System.getProperty("test.classes"); - check(testClasses, - "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class"); - if (errors.size() > 0) { + throws IOException { + Path src = Path.of("src"); + Path out = Path.of("out"); + ToolBox toolBox = new ToolBox(); + toolBox.writeJavaFiles(src, SOURCE); + CompilerUtils.compile(src, out, "--release", "16"); + check(out, "StrictfpInterface.class"); + if (!errors.isEmpty()) { for (String error: errors) { System.err.println(error); } @@ -70,42 +77,17 @@ public class CheckACC_STRICTFlagOnDefaultMethodTest { } } - void check(String dir, String... fileNames) - throws - IOException, - ConstantPoolException, - Descriptor.InvalidDescriptor { + void check(Path dir, String... fileNames) throws IOException { for (String fileName : fileNames) { - ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); + ClassModel classFileToCheck = ClassFile.of().parse(dir.resolve(fileName)); - 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())); } } } } - -// this version of the code can be used when ClassFile API in not in a preview -// void check(String dir, String... fileNames) throws IOException { -// for (String fileName : fileNames) { -// ClassModel classFileToCheck = ClassFile.of().parse(new File(dir, fileName).toPath()); -// -// for (MethodModel method : classFileToCheck.methods()) { -// if ((method.flags().flagsMask() & ClassFile.ACC_STRICT) == 0) { -// errors.add(String.format(offendingMethodErrorMessage, -// method.methodName().stringValue(), -// classFileToCheck.thisClass().asInternalName())); -// } -// } -// } -// } - - strictfp interface StrictfpInterface { - default void default_interface_method() {} - static void static_interface_method() {} - } - } diff --git a/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java b/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java index b24144aa80f..47bc3f78f79 100644 --- a/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java +++ b/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, 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 @@ -25,27 +25,49 @@ * @test * @bug 8046060 * @summary Different results of floating point multiplication for lambda code block - * @modules jdk.jdeps/com.sun.tools.classfile - * @compile -source 16 -target 16 LambdaTestStrictFPFlag.java + * @library /tools/lib /test/lib + * @enablePreview * @run main LambdaTestStrictFPFlag */ -import java.io.*; -import java.net.URL; -import com.sun.tools.classfile.*; +import jdk.test.lib.compiler.CompilerUtils; +import toolbox.ToolBox; + +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.nio.file.Path; public class LambdaTestStrictFPFlag { + private static final String SOURCE = """ + class Test { + strictfp void test() { + Face itf = () -> { }; + } + } + + interface Face { + void m(); + } + """; + public static void main(String[] args) throws Exception { new LambdaTestStrictFPFlag().run(); } void run() throws Exception { - ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class"); - ConstantPool cp = cf.constant_pool; + Path src = Path.of("src"); + Path out = Path.of("out"); + + ToolBox toolBox = new ToolBox(); + toolBox.writeJavaFiles(src, SOURCE); + CompilerUtils.compile(src, out, "--release", "16"); + + ClassModel cm = ClassFile.of().parse(out.resolve("Test.class")); boolean found = false; - for (Method meth: cf.methods) { - if (meth.getName(cp).startsWith("lambda$")) { - if ((meth.access_flags.flags & AccessFlags.ACC_STRICT) == 0) { + for (MethodModel meth: cm.methods()) { + if (meth.methodName().stringValue().startsWith("lambda$")) { + if ((meth.flags().flagsMask() & ClassFile.ACC_STRICT) == 0){ throw new Exception("strict flag missing from lambda"); } found = true; @@ -55,41 +77,4 @@ public class LambdaTestStrictFPFlag { throw new Exception("did not find lambda method"); } } - -// this version of the code can be used when ClassFile API in not in a preview -// void run() throws Exception { -// ClassModel cm = getClassFile("LambdaTestStrictFPFlag$Test.class"); -// boolean found = false; -// for (MethodModel meth: cm.methods()) { -// if (meth.methodName().stringValue().startsWith("lambda$")) { -// if ((meth.flags().flagsMask() & ClassFile.ACC_STRICT) == 0){ -// throw new Exception("strict flag missing from lambda"); -// } -// found = true; -// } -// } -// if (!found) { -// throw new Exception("did not find lambda method"); -// } -// } - - ClassFile getClassFile(String name) throws IOException, ConstantPoolException { - URL url = getClass().getResource(name); - InputStream in = url.openStream(); - try { - return ClassFile.read(in); - } finally { - in.close(); - } - } - - class Test { - strictfp void test() { - Face itf = () -> { }; - } - } - - interface Face { - void m(); - } } diff --git a/test/langtools/tools/javap/T6866657.java b/test/langtools/tools/javap/T6866657.java index c935d4747f8..0b46cd07f66 100644 --- a/test/langtools/tools/javap/T6866657.java +++ b/test/langtools/tools/javap/T6866657.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, 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 @@ -25,12 +25,10 @@ * @test * @bug 6866657 * @summary add byteLength() method to primary classfile types - * @modules jdk.jdeps/com.sun.tools.classfile - * jdk.jdeps/com.sun.tools.javap + * @modules jdk.jdeps/com.sun.tools.javap */ import java.io.*; -import java.util.*; import javax.tools.*; import com.sun.tools.javap.*; diff --git a/test/langtools/tools/javap/T7186925.java b/test/langtools/tools/javap/T7186925.java index 2d4553526b1..dcbe8af10ba 100644 --- a/test/langtools/tools/javap/T7186925.java +++ b/test/langtools/tools/javap/T7186925.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -25,12 +25,9 @@ * @test * @bug 7186925 * @summary JavapTask passes null to java.io.Writer - * @modules jdk.jdeps/com.sun.tools.classfile - * jdk.jdeps/com.sun.tools.javap + * @modules jdk.jdeps/com.sun.tools.javap */ -import java.io.*; -import java.util.*; import javax.tools.*; import com.sun.tools.javap.*; diff --git a/test/langtools/tools/jdeps/APIDeps.java b/test/langtools/tools/jdeps/APIDeps.java index 05b4bd2f3a5..826135fd532 100644 --- a/test/langtools/tools/jdeps/APIDeps.java +++ b/test/langtools/tools/jdeps/APIDeps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -28,7 +28,6 @@ * @library lib * @modules java.base/sun.security.x509 * java.management - * jdk.jdeps/com.sun.tools.classfile * jdk.jdeps/com.sun.tools.jdeps * @run main APIDeps */ @@ -104,17 +103,17 @@ public class APIDeps { new String[] {"c.I", "e.E", "f.F", "m.Bar"}, new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none"}); test(new File(mDir, "Gee.class"), - new String[] {"g.G", "sun.security.x509.X509CertInfo", "com.sun.tools.classfile.ClassFile", + new String[] {"g.G", "sun.security.x509.X509CertInfo", "com.sun.tools.jdeps.Analyzer", "com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree"}, new String[] {"-classpath", testDir.getPath(), "-verbose"}); // -jdkinternals test(new File(mDir, "Gee.class"), - new String[] {"sun.security.x509.X509CertInfo", "com.sun.tools.classfile.ClassFile"}, + new String[] {"sun.security.x509.X509CertInfo", "com.sun.tools.jdeps.Analyzer"}, new String[] {"-jdkinternals", "-quiet"}); // -jdkinternals parses all classes on -classpath and the input arguments test(new File(mDir, "Gee.class"), - new String[] {"com.sun.tools.classfile.ClassFile", + new String[] {"com.sun.tools.jdeps.Analyzer", "sun.security.x509.X509CertInfo"}, // use -classpath tmp/a with no use of JDK internal API new String[] {"-classpath", dest.resolve("a").toString(), "-jdkinternals", "-quiet"}); diff --git a/test/langtools/tools/jdeps/m/Gee.java b/test/langtools/tools/jdeps/m/Gee.java index 194a30d7f1b..d1e56428acf 100644 --- a/test/langtools/tools/jdeps/m/Gee.java +++ b/test/langtools/tools/jdeps/m/Gee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ -26,7 +26,7 @@ package m; class Gee extends g.G { public sun.security.x509.X509CertInfo cert; - public com.sun.tools.classfile.ClassFile cf; // not exported + public com.sun.tools.jdeps.Analyzer analyzer; // not exported public com.sun.source.tree.BinaryTree tree; // exported public com.sun.management.ThreadMXBean mxbean; // exported }