diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java index e82b291360b6bdaac43ecfbbf5eda97535d17059..b8249dbd7dde18478d37dd054e8c8415a6b2f0e0 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicInterpreter.java @@ -61,7 +61,7 @@ public class BasicInterpreter extends Interpreter implements Opcodes * version. */ public BasicInterpreter() { - super(ASM7); + super(/* latest api = */ ASM7); if (getClass() != BasicInterpreter.class) { throw new IllegalStateException(); } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java index 72f68937ecb7151ad00795f734c290766504abba..2b7b64bd0b393f9e8c5fe77391d4b1cd9a3effff 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/BasicVerifier.java @@ -47,7 +47,7 @@ public class BasicVerifier extends BasicInterpreter { * use this constructor. Instead, they must use the {@link #BasicVerifier(int)} version. */ public BasicVerifier() { - super(ASM7); + super(/* latest api = */ ASM7); if (getClass() != BasicVerifier.class) { throw new IllegalStateException(); } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java index 351af441e019618dbf1bcca8075f54d86875284d..6b305ca5a7da59434607c94ecccdabbb2cf2aa59 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SimpleVerifier.java @@ -93,7 +93,12 @@ public class SimpleVerifier extends BasicVerifier { final Type currentSuperClass, final List currentClassInterfaces, final boolean isInterface) { - this(ASM7, currentClass, currentSuperClass, currentClassInterfaces, isInterface); + this( + /* latest api = */ ASM7, + currentClass, + currentSuperClass, + currentClassInterfaces, + isInterface); if (getClass() != SimpleVerifier.class) { throw new IllegalStateException(); } diff --git a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java index 4bdbd2a9f704f40664eea67f6b9d477ec62e4bb6..b987031ca4c877133aa1ea512a6cf9f8001082b7 100644 --- a/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java +++ b/asm-analysis/src/main/java/org/objectweb/asm/tree/analysis/SourceInterpreter.java @@ -51,7 +51,7 @@ public class SourceInterpreter extends Interpreter implements Opcod * version. */ public SourceInterpreter() { - super(ASM7); + super(/* latest api = */ ASM7); if (getClass() != SourceInterpreter.class) { throw new IllegalStateException(); } diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java index 32ea8780cfba190624e2f8c4d782e5a451b4e84c..80644ace6296acd9f8aa8f0eea6a83d6397ff255 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerTest.java @@ -1173,7 +1173,7 @@ public class AnalyzerTest extends AsmTest { private static class MockInterpreter extends Interpreter { MockInterpreter() { - super(Opcodes.ASM7); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL); } @Override diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java index 3741e074fedc2d0a100fb34a45ae6242ca89d800..1ea146a64c70753ee578e3e61ace8e20a3c20231 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/AnalyzerWithBasicInterpreterTest.java @@ -125,7 +125,7 @@ public class AnalyzerWithBasicInterpreterTest extends AsmTest { new ClassReader(PrecompiledClass.JDK8_ALL_FRAMES.getBytes()).accept(classNode, 0); Analyzer analyzer = new Analyzer( - new BasicInterpreter(Opcodes.ASM7) { + new BasicInterpreter(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public BasicValue merge(final BasicValue value1, final BasicValue value2) { return new BasicValue(super.merge(value1, value2).getType()); diff --git a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java index 95bf87a7e904bc875ddd75d62afe903540324dd1..5a8a42d2a3575447f21a511c21380ccb2e072c10 100644 --- a/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java +++ b/asm-analysis/src/test/java/org/objectweb/asm/tree/analysis/SimpleVerifierTest.java @@ -81,7 +81,12 @@ public class SimpleVerifierTest { Type superType = Type.getObjectType("D"); Type interfaceType = Type.getObjectType("I"); SimpleVerifier simpleVerifier = - new SimpleVerifier(Opcodes.ASM7, baseType, superType, Arrays.asList(interfaceType), false) { + new SimpleVerifier( + /* latest */ Opcodes.ASM8_EXPERIMENTAL, + baseType, + superType, + Arrays.asList(interfaceType), + false) { @Override public boolean isAssignableFrom(final Type type1, final Type type2) { @@ -114,7 +119,8 @@ public class SimpleVerifierTest { Type baseType = Type.getObjectType("C"); Type interfaceType = Type.getObjectType("I"); SimpleVerifier simpleVerifier = - new SimpleVerifier(Opcodes.ASM7, interfaceType, null, null, true) { + new SimpleVerifier( + /* latest */ Opcodes.ASM8_EXPERIMENTAL, interfaceType, null, null, true) { @Override protected Type getSuperClass(final Type type) { diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java index 2e4412bc12f5b96c7ae45edaec21b1931eb2126d..bbf4e57b6871c09123d788c83636e669092fc755 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnalyzerAdapter.java @@ -116,7 +116,7 @@ public class AnalyzerAdapter extends MethodVisitor { final String name, final String descriptor, final MethodVisitor methodVisitor) { - this(Opcodes.ASM7, owner, access, name, descriptor, methodVisitor); + this(/* latest api = */ Opcodes.ASM7, owner, access, name, descriptor, methodVisitor); if (getClass() != AnalyzerAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java index fd86b455a15d13b99348b7a21bab1e09d3fcb5cf..36e32ad73909b265d8f5e3317f891123bab77d70 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/AnnotationRemapper.java @@ -49,7 +49,7 @@ public class AnnotationRemapper extends AnnotationVisitor { * @param remapper the remapper to use to remap the types in the visited annotation. */ public AnnotationRemapper(final AnnotationVisitor annotationVisitor, final Remapper remapper) { - this(Opcodes.ASM7, annotationVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, annotationVisitor, remapper); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java index 4860b827109bfc70a7093781de66f90213eea216..41574618229d20b9572eca86a785bc4831e9f7c9 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ClassRemapper.java @@ -73,7 +73,7 @@ public class ClassRemapper extends ClassVisitor { * @param remapper the remapper to use to remap the types in the visited class. */ public ClassRemapper(final ClassVisitor classVisitor, final Remapper remapper) { - this(Opcodes.ASM7, classVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, classVisitor, remapper); } /** @@ -204,6 +204,11 @@ public class ClassRemapper extends ClassVisitor { super.visitNestMember(remapper.mapType(nestMember)); } + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + super.visitPermittedSubtypeExperimental(remapper.mapType(permittedSubtype)); + } + /** * Constructs a new remapper for fields. The default implementation of this method returns a new * {@link FieldRemapper}. diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java b/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java index f9b4120e176ff1a0c47290ada57ffebd4e439d34..9aee1d37c716c05ca94bdf25ed37774615861d59 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/CodeSizeEvaluator.java @@ -47,7 +47,7 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes { private int maxSize; public CodeSizeEvaluator(final MethodVisitor methodVisitor) { - this(Opcodes.ASM7, methodVisitor); + this(/* latest api = */ Opcodes.ASM7, methodVisitor); } protected CodeSizeEvaluator(final int api, final MethodVisitor methodVisitor) { diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java index fd1936b62ce549ea3aca23bedde5f110d1d26670..b4c818cadf44b6d3e348c608a44e258f1065d4ea 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/FieldRemapper.java @@ -51,7 +51,7 @@ public class FieldRemapper extends FieldVisitor { * @param remapper the remapper to use to remap the types in the visited field. */ public FieldRemapper(final FieldVisitor fieldVisitor, final Remapper remapper) { - this(Opcodes.ASM7, fieldVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, fieldVisitor, remapper); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java index d5a5edddbe6aa6b0a04aee32443f75c328ab6096..283c637da59d4a4ede1a7f17c1358453b3f75946 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/GeneratorAdapter.java @@ -201,7 +201,7 @@ public class GeneratorAdapter extends LocalVariablesSorter { final int access, final String name, final String descriptor) { - this(Opcodes.ASM7, methodVisitor, access, name, descriptor); + this(/* latest api = */ Opcodes.ASM7, methodVisitor, access, name, descriptor); if (getClass() != GeneratorAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java index 3c58a672ba0329b63e5fbaa4d311ff0ab03be35d..2bad7a8fecadd21555cabfa4471d1dd47853b3b9 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/InstructionAdapter.java @@ -53,7 +53,7 @@ public class InstructionAdapter extends MethodVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public InstructionAdapter(final MethodVisitor methodVisitor) { - this(Opcodes.ASM7, methodVisitor); + this(/* latest api = */ Opcodes.ASM7, methodVisitor); if (getClass() != InstructionAdapter.class) { throw new IllegalStateException(); } @@ -621,7 +621,7 @@ public class InstructionAdapter extends MethodVisitor { || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) { throw new UnsupportedOperationException("This feature requires ASM5"); } - if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) { + if (api < Opcodes.ASM7 && value instanceof ConstantDynamic) { throw new UnsupportedOperationException("This feature requires ASM7"); } if (value instanceof Integer) { diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java index eca5266fb17a4b27af36c0fdc35ff27403b22dfb..33bc9715aa3c456c8d69928d2d41ef92261dc967 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/JSRInlinerAdapter.java @@ -98,7 +98,14 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes { final String descriptor, final String signature, final String[] exceptions) { - this(Opcodes.ASM7, methodVisitor, access, name, descriptor, signature, exceptions); + this( + /* latest api = */ Opcodes.ASM7, + methodVisitor, + access, + name, + descriptor, + signature, + exceptions); if (getClass() != JSRInlinerAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java index 73c0e046844e95b6c12757ce047442dd33106468..c139f9e92b1974b0869ef4db2ae398d2ed1ddff6 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/LocalVariablesSorter.java @@ -81,7 +81,7 @@ public class LocalVariablesSorter extends MethodVisitor { */ public LocalVariablesSorter( final int access, final String descriptor, final MethodVisitor methodVisitor) { - this(Opcodes.ASM7, access, descriptor, methodVisitor); + this(/* latest api = */ Opcodes.ASM7, access, descriptor, methodVisitor); if (getClass() != LocalVariablesSorter.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java index b54a54d105eb0f91ae127dcd4d3003a059d075ac..3fe7e83314bcd26713f3319c48804fd487b60aad 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/MethodRemapper.java @@ -53,7 +53,7 @@ public class MethodRemapper extends MethodVisitor { * @param remapper the remapper to use to remap the types in the visited method. */ public MethodRemapper(final MethodVisitor methodVisitor, final Remapper remapper) { - this(Opcodes.ASM7, methodVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, methodVisitor, remapper); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java index 7792bbdbeb02f075a191a4876c0ec2e9c14e4bc3..e3eafba099d6ba4fca77a90bc0b183d427b7f6d0 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/ModuleRemapper.java @@ -49,7 +49,7 @@ public class ModuleRemapper extends ModuleVisitor { * @param remapper the remapper to use to remap the types in the visited module. */ public ModuleRemapper(final ModuleVisitor moduleVisitor, final Remapper remapper) { - this(Opcodes.ASM7, moduleVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, moduleVisitor, remapper); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java index 279f91edc5530ec00590aa9b538de80200205757..d193684b51b8a48e413efff3d1816b51d4772461 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SerialVersionUIDAdder.java @@ -150,7 +150,7 @@ public class SerialVersionUIDAdder extends ClassVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public SerialVersionUIDAdder(final ClassVisitor classVisitor) { - this(Opcodes.ASM7, classVisitor); + this(/* latest api = */ Opcodes.ASM7, classVisitor); if (getClass() != SerialVersionUIDAdder.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java index e3eb2d585b22d17b297697c4c3a57981e529e0d3..003759fc1b5118e4c78c468e1676e5ddde3cd4b0 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/SignatureRemapper.java @@ -53,7 +53,7 @@ public class SignatureRemapper extends SignatureVisitor { * @param remapper the remapper to use to remap the types in the visited signature. */ public SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper) { - this(Opcodes.ASM7, signatureVisitor, remapper); + this(/* latest api = */ Opcodes.ASM7, signatureVisitor, remapper); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java index db1da0497a87a3efabf2d10203d29e70da7b2442..eb3b46f54061d2cb90703393a06f342a0e833de1 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/StaticInitMerger.java @@ -61,7 +61,7 @@ public class StaticInitMerger extends ClassVisitor { * null. */ public StaticInitMerger(final String prefix, final ClassVisitor classVisitor) { - this(Opcodes.ASM7, prefix, classVisitor); + this(/* latest api = */ Opcodes.ASM7, prefix, classVisitor); } /** diff --git a/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java index e245d2f6739e1a6a47c982986ae04c9e63ec754b..4989f6a7154bb6314e9d092e4b8c1cb00acc8ef2 100644 --- a/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java +++ b/asm-commons/src/main/java/org/objectweb/asm/commons/TryCatchBlockSorter.java @@ -70,7 +70,14 @@ public class TryCatchBlockSorter extends MethodNode { final String descriptor, final String signature, final String[] exceptions) { - this(Opcodes.ASM7, methodVisitor, access, name, descriptor, signature, exceptions); + this( + /* latest api = */ Opcodes.ASM7, + methodVisitor, + access, + name, + descriptor, + signature, + exceptions); if (getClass() != TryCatchBlockSorter.class) { throw new IllegalStateException(); } diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java index d6088872ee230bafeea7bcfb4dc19b92abb37bab..8023c1eccebc2fdad0ef2c069d15857f1f6b50ba 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/AdviceAdapterTest.java @@ -557,8 +557,8 @@ public class AdviceAdapterTest extends AsmTest { MethodNode outputMethod = new MethodNode(Opcodes.ACC_PUBLIC, "", "(I)V", null, null); AdviceAdapter adviceAdapter = new AdviceAdapter( - Opcodes.ASM7, - new MethodVisitor(Opcodes.ASM7, outputMethod) {}, + /* latest */ Opcodes.ASM8_EXPERIMENTAL, + new MethodVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL, outputMethod) {}, Opcodes.ACC_PUBLIC, "", "()V") { @@ -616,7 +616,12 @@ public class AdviceAdapterTest extends AsmTest { private static class BasicAdviceAdapter extends AdviceAdapter { BasicAdviceAdapter(final MethodVisitor methodVisitor) { - super(Opcodes.ASM7, methodVisitor, Opcodes.ACC_PUBLIC, "", "(I)V"); + super( + /* latest */ Opcodes.ASM8_EXPERIMENTAL, + methodVisitor, + Opcodes.ACC_PUBLIC, + "", + "(I)V"); } @Override diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java index e10754187a1b000c578d2be6778d042ff97c2c30..3d22a449e0afefcacd425694ccafe2c1e3992abf 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/AnalyzerAdapterTest.java @@ -181,7 +181,7 @@ public class AnalyzerAdapterTest extends AsmTest { private boolean hasOriginalFrame; AnalyzedFramesInserter(final MethodVisitor methodVisitor) { - super(Opcodes.ASM7, methodVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, methodVisitor); } void setAnalyzerAdapter(final AnalyzerAdapter analyzerAdapter) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java index 106089145daee3b65fe133cce18e8b825cce76a2..3e1e47b785fd9f7f5613a0af8aa2ebf136db0f1d 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ClassRemapperTest.java @@ -149,7 +149,7 @@ public class ClassRemapperTest extends AsmTest { ClassNode classNode = new ClassNode(); ClassRemapper classRemapper = new ClassRemapper( - Opcodes.ASM7, + /* latest */ Opcodes.ASM8_EXPERIMENTAL, classNode, new Remapper() { @Override diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java index 5007c1aec8fbfd51ebe980c833cc8f33b10e0d63..c6d0fd617a33170b160fdf7acecdf60b42b3303f 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/GeneratorAdapterTest.java @@ -848,7 +848,11 @@ public class GeneratorAdapterTest { textifier = new Textifier(); generatorAdapter = new GeneratorAdapter( - Opcodes.ASM7, new TraceMethodVisitor(textifier), access, name, descriptor); + /* latest */ Opcodes.ASM8_EXPERIMENTAL, + new TraceMethodVisitor(textifier), + access, + name, + descriptor); } public String push(final boolean value) { @@ -1221,9 +1225,7 @@ public class GeneratorAdapterTest { @Override public String toString() { String result = - textifier - .text - .stream() + textifier.text.stream() .map(text -> text.toString().trim()) .collect(Collectors.joining(" ")); textifier.text.clear(); diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java index 0551ae6b20e6afc9688f03e7e31b63a5033933df..14dab5198c55fe1d54dd9ad713b8d0f53a7c1166 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/InstructionAdapterTest.java @@ -174,9 +174,7 @@ public class InstructionAdapterTest extends AsmTest { assertEquals( "ICONST_0 ICONST_1 ICONST_2 BIPUSH 51 ICONST_4 ICONST_5 LDC 6 LDC 7.0 LDC 8.0 LDC \"9\" " + "LDC Lpkg/Class;.class LDC pkg/Class.nameI (1)", - textifier - .text - .stream() + textifier.text.stream() .map(text -> text.toString().trim()) .collect(Collectors.joining(" "))); } diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java index 79d53e029af5733862988a57ddf0cd5db6376b0d..c95f93efeece4136e546358d88b2795053e93d2a 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/LocalVariablesSorterTest.java @@ -218,7 +218,7 @@ public class LocalVariablesSorterTest extends AsmTest { new ClassReader(Files.newInputStream(Paths.get("src/test/resources/Issue317586.class"))); ClassWriter classWriter = new ClassWriter(0); ClassVisitor localVariablesSorter = - new LocalVariablesSorterClassAdapter(Opcodes.ASM7, classWriter); + new LocalVariablesSorterClassAdapter(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classWriter); classReader.accept(localVariablesSorter, ClassReader.EXPAND_FRAMES); diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java index d305d5b031022e5c51d1806fa6643cd3fb65f0f3..49d59afa2f5ba86594b1171eeb4b4ce628aa0048 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleHashesAttributeTest.java @@ -60,7 +60,7 @@ public class ModuleHashesAttributeTest { ModuleHashesAttribute moduleHashesAttribute = new ModuleHashesAttribute(); new ClassReader(classWriter.toByteArray()) .accept( - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visitAttribute(final Attribute attribute) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java index ff0fc94f9d2a7d1c1dfc00e788e732fee28682dd..5bad87b60a50ce0f912f0f25abf82a3bf08b7feb 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleResolutionAttributeTest.java @@ -51,7 +51,7 @@ public class ModuleResolutionAttributeTest { ModuleResolutionAttribute moduleResolutionAttribute = new ModuleResolutionAttribute(); new ClassReader(classWriter.toByteArray()) .accept( - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visitAttribute(final Attribute attribute) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java index 9a4a86ba38159da965b0e878736e91176753c897..39efd9db18060b24603295209e2a4b30dc6b8e79 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/ModuleTargetAttributeTest.java @@ -51,7 +51,7 @@ public class ModuleTargetAttributeTest { ModuleTargetAttribute moduleTargetAttribute = new ModuleTargetAttribute(); new ClassReader(classWriter.toByteArray()) .accept( - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visitAttribute(final Attribute attribute) { diff --git a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java index 04f506b7e0207a62f76b0bb9568a69e5185d827a..58716a7590382b13f8ac5fee4e69d32cc6765831 100644 --- a/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java +++ b/asm-commons/src/test/java/org/objectweb/asm/commons/SerialVersionUidAdderTest.java @@ -122,7 +122,8 @@ public class SerialVersionUidAdderTest extends AsmTest { ClassReader classReader = new ClassReader(classParameter.getBytes()); ClassWriter classWriter = new ClassWriter(0); - classReader.accept(new SerialVersionUIDAdder(classWriter), 0); + classReader.accept( + new SerialVersionUIDAdder(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classWriter), 0); if ((classReader.getAccess() & Opcodes.ACC_ENUM) == 0) { assertTrue(new ClassFile(classWriter.toByteArray()).toString().contains("serialVersionUID")); diff --git a/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java index ba37d1cb41f2f7904715fa0a687d4e27f3e69ff9..015cadf0014b44172599b3a687dcacb44929606c 100644 --- a/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java +++ b/asm-test/src/main/java/org/objectweb/asm/test/AsmTest.java @@ -92,7 +92,7 @@ public abstract class AsmTest { * The expected pattern (i.e. regular expression) that ASM's UnsupportedOperationException * messages are supposed to match. */ - public static final String UNSUPPORTED_OPERATION_MESSAGE_PATTERN = ".* requires ASM[567]"; + public static final String UNSUPPORTED_OPERATION_MESSAGE_PATTERN = ".* requires ASM[5678].*"; /** * A precompiled class, hand-crafted to contain some set of class file structures. These classes @@ -122,7 +122,8 @@ public abstract class AsmTest { JDK9_MODULE("jdk9.module-info"), JDK11_ALL_INSTRUCTIONS("jdk11.AllInstructions"), JDK11_ALL_STRUCTURES("jdk11.AllStructures"), - JDK11_ALL_STRUCTURES_NESTED("jdk11.AllStructures$Nested"); + JDK11_ALL_STRUCTURES_NESTED("jdk11.AllStructures$Nested"), + JDK14_ALL_STRUCTURES("jdk14.AllStructures"); private final String name; private byte[] bytes; @@ -164,7 +165,13 @@ public abstract class AsmTest { if (name.startsWith("jdk9.") && api.value() < Api.ASM6.value()) { return true; } - return name.startsWith("jdk11.") && api.value() < Api.ASM7.value(); + if (name.startsWith("jdk11.") && api.value() < Api.ASM7.value()) { + return true; + } + if (name.startsWith("jdk14.") && api.value() < Api.ASM8.value()) { + return true; + } + return false; } /** @@ -181,6 +188,9 @@ public abstract class AsmTest { if (name.startsWith("jdk11.")) { return Util.getMajorJavaVersion() < 11; } + if (name.startsWith("jdk14.")) { + return Util.getMajorJavaVersion() < 14; + } return false; } @@ -247,7 +257,8 @@ public abstract class AsmTest { ASM4("ASM4", 4 << 16), ASM5("ASM5", 5 << 16), ASM6("ASM6", 6 << 16), - ASM7("ASM7", 7 << 16); + ASM7("ASM7", 7 << 16), + ASM8("ASM8", 1 << 24 | 8 << 16 | 0 << 8); private final String name; private final int value; @@ -260,7 +271,7 @@ public abstract class AsmTest { /** * Returns the int value of this version, as expected by ASM. * - * @return one of the ASM4, ASM5, ASM6 or ASM7 constants from the ASM Opcodes interface. + * @return one of the ASM4, ASM5, ASM6, ASM7 or ASM8 constants from the ASM Opcodes interface. */ public int value() { return value; @@ -269,7 +280,7 @@ public abstract class AsmTest { /** * Returns a human readable symbol corresponding to this version. * - * @return one of "ASM4", "ASM5", "ASM6" or "ASM7". + * @return one of "ASM4", "ASM5", "ASM6" "ASM7" or or "ASM8". */ @Override public String toString() { @@ -294,10 +305,10 @@ public abstract class AsmTest { * with {@code @MethodSource("allClassesAndLatestApi")} will be executed on all the precompiled * classes, with the latest api. * - * @return all the possible (precompiledClass, ASM7) pairs, for all the precompiled classes. + * @return all the possible (precompiledClass, ASM8) pairs, for all the precompiled classes. */ public static Stream allClassesAndLatestApi() { - return classesAndApis(Api.ASM7); + return classesAndApis(Api.ASM8); } private static Stream classesAndApis(final Api... apis) { diff --git a/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java b/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java index b26bc8a76ce16dac6143d799a2c763875ac168c7..a796256c930aa3c1265f8d0874604f20defd7abd 100644 --- a/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java +++ b/asm-test/src/main/java/org/objectweb/asm/test/ClassFile.java @@ -494,6 +494,8 @@ public class ClassFile { dumpNestHostAttribute(parser, builder); } else if (attributeName.equals("NestMembers")) { dumpNestMembersAttribute(parser, builder); + } else if (attributeName.equals("PermittedSubtypes")) { + dumpPermittedSubtypesAttribute(parser, builder); } else if (attributeName.equals("StackMap")) { dumpStackMapAttribute(parser, builder); } else if (!attributeName.equals("CodeComment") && !attributeName.equals("Comment")) { @@ -1686,6 +1688,22 @@ public class ClassFile { } } + /** + * Parses and dumps a PermittedSubtypes attribute. + * + * @param parser a class parser. + * @param builder a dump builder. + * @throws IOException if the class can't be parsed. + * @see JEP 360 + */ + private static void dumpPermittedSubtypesAttribute(final Parser parser, final Builder builder) + throws IOException { + int numberOfClasses = builder.add("number_of_classes: ", parser.u2()); + for (int i = 0; i < numberOfClasses; ++i) { + builder.addCpInfo("class: ", parser.u2()); + } + } + /** * Parses and dumps a StackMap attribute. * diff --git a/asm-test/src/main/resources/jdk14/AllStructures$ClassSubType.class b/asm-test/src/main/resources/jdk14/AllStructures$ClassSubType.class new file mode 100644 index 0000000000000000000000000000000000000000..eec72864674a54bb12c1d0b92f21acbd49f87f00 Binary files /dev/null and b/asm-test/src/main/resources/jdk14/AllStructures$ClassSubType.class differ diff --git a/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class b/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class new file mode 100644 index 0000000000000000000000000000000000000000..b144463f51fe5ae0317c9bdff305c9392238ffa8 Binary files /dev/null and b/asm-test/src/main/resources/jdk14/AllStructures$RecordSubType.class differ diff --git a/asm-test/src/main/resources/jdk14/AllStructures.class b/asm-test/src/main/resources/jdk14/AllStructures.class new file mode 100644 index 0000000000000000000000000000000000000000..88ca1ecd6910468ab7392548d906c51e34752221 Binary files /dev/null and b/asm-test/src/main/resources/jdk14/AllStructures.class differ diff --git a/asm-test/src/resources/java/jdk14/AllStructures.java b/asm-test/src/resources/java/jdk14/AllStructures.java new file mode 100644 index 0000000000000000000000000000000000000000..120c9ad8a004394f766a69b4841a1a8e727f68bd --- /dev/null +++ b/asm-test/src/resources/java/jdk14/AllStructures.java @@ -0,0 +1,37 @@ +// ASM: a very small and fast Java bytecode manipulation framework +// Copyright (c) 2000-2011 INRIA, France Telecom +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +package jdk14; + +public sealed interface AllStructures { + final class ClassSubType { + + } + record RecordSubType(int component1, String component2) { + + } +} \ No newline at end of file diff --git a/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java index e69f36f0dea2a93c533719ca4d719fdfc28da615..482d8c09d3d9bcc7d7c08f0d33c0b7df15fc196b 100644 --- a/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java +++ b/asm-test/src/test/java/org/objectweb/asm/test/AsmTestTest.java @@ -98,7 +98,7 @@ public class AsmTestTest extends AsmTest { new HashSet(Arrays.asList(PrecompiledClass.values())), allArguments.stream().map(arg -> arg.get()[0]).collect(Collectors.toSet())); assertEquals( - new HashSet(Arrays.asList(Api.ASM7)), + new HashSet(Arrays.asList(Api.ASM8)), allArguments.stream().map(arg -> arg.get()[1]).collect(Collectors.toSet())); } } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java index ecbb2efd8ed5c0c20863642aac14f09d273dd49f..3915e3b40b92a17bf5a726a083b02ef528a2a346 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/AnnotationNode.java @@ -60,7 +60,7 @@ public class AnnotationNode extends AnnotationVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public AnnotationNode(final String descriptor) { - this(Opcodes.ASM7, descriptor); + this(/* latest api = */ Opcodes.ASM7, descriptor); if (getClass() != AnnotationNode.class) { throw new IllegalStateException(); } @@ -84,7 +84,7 @@ public class AnnotationNode extends AnnotationVisitor { * @param values where the visited values must be stored. */ AnnotationNode(final List values) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.values = values; } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java index 97dd1c69307d80cfc8560da6d430d2378a3f64f1..6f455bd7b62f893b53de2f17322455d44f26d12d 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ClassNode.java @@ -126,6 +126,15 @@ public class ClassNode extends ClassVisitor { /** The internal names of the nest members of this class. May be {@literal null}. */ public List nestMembers; + /** + * Experimental, use at your own risk. This method will be renamed when it becomes stable, this + * will break existing code using it. The internal names of the permitted subtypes of this + * class. May be {@literal null}. + * + * @deprecated this API is experimental. + */ + @Deprecated public List permittedSubtypesExperimental; + /** The fields of this class. */ public List fields; @@ -236,6 +245,11 @@ public class ClassNode extends ClassVisitor { nestMembers = Util.add(nestMembers, nestMember); } + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + permittedSubtypesExperimental = Util.add(permittedSubtypesExperimental, permittedSubtype); + } + @Override public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { @@ -285,6 +299,9 @@ public class ClassNode extends ClassVisitor { * {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public void check(final int api) { + if (api != Opcodes.ASM8_EXPERIMENTAL && permittedSubtypesExperimental != null) { + throw new UnsupportedClassVersionException(); + } if (api < Opcodes.ASM7 && (nestHostClass != null || nestMembers != null)) { throw new UnsupportedClassVersionException(); } @@ -395,6 +412,12 @@ public class ClassNode extends ClassVisitor { classVisitor.visitNestMember(nestMembers.get(i)); } } + // Visit the permitted subtypes. + if (permittedSubtypesExperimental != null) { + for (int i = 0, n = permittedSubtypesExperimental.size(); i < n; ++i) { + classVisitor.visitPermittedSubtypeExperimental(permittedSubtypesExperimental.get(i)); + } + } // Visit the inner classes. for (int i = 0, n = innerClasses.size(); i < n; ++i) { innerClasses.get(i).accept(classVisitor); diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java index 5b5084d5c9b46eedfdbde07e2bde1b9365f95a0d..40f51594f402e4819a7c5c3e0f379bc3ff24af38 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/FieldNode.java @@ -99,7 +99,7 @@ public class FieldNode extends FieldVisitor { final String descriptor, final String signature, final Object value) { - this(Opcodes.ASM7, access, name, descriptor, signature, value); + this(/* latest api = */ Opcodes.ASM7, access, name, descriptor, signature, value); if (getClass() != FieldNode.class) { throw new IllegalStateException(); } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java index e22033c145ed469983e67699aa059f58d73c3741..f93bf3aafd8c5fa9d2cedfa5d114e222e230682a 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/LocalVariableAnnotationNode.java @@ -84,7 +84,7 @@ public class LocalVariableAnnotationNode extends TypeAnnotationNode { final LabelNode[] end, final int[] index, final String descriptor) { - this(Opcodes.ASM7, typeRef, typePath, start, end, index, descriptor); + this(/* latest api = */ Opcodes.ASM7, typeRef, typePath, start, end, index, descriptor); } /** diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java index 2ab6bb2dbe669f993e336c3fe8ab3f0f75189c56..274a02be2f23862cab7a6c4dc98874fac07f6bb8 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/MethodNode.java @@ -155,7 +155,7 @@ public class MethodNode extends MethodVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public MethodNode() { - this(Opcodes.ASM7); + this(/* latest api = */ Opcodes.ASM7); if (getClass() != MethodNode.class) { throw new IllegalStateException(); } @@ -191,7 +191,7 @@ public class MethodNode extends MethodVisitor { final String descriptor, final String signature, final String[] exceptions) { - this(Opcodes.ASM7, access, name, descriptor, signature, exceptions); + this(/* latest api = */ Opcodes.ASM7, access, name, descriptor, signature, exceptions); if (getClass() != MethodNode.class) { throw new IllegalStateException(); } @@ -621,7 +621,7 @@ public class MethodNode extends MethodVisitor { throw new UnsupportedClassVersionException(); } } - if (api != Opcodes.ASM7) { + if (api < Opcodes.ASM7) { for (int i = instructions.size() - 1; i >= 0; --i) { AbstractInsnNode insn = instructions.get(i); if (insn instanceof LdcInsnNode) { diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java index c1c8705f4a6bc94a6e8bd3ec622fa1c9109e720b..7fa8a9ded7d2d58d447bcfde2c1f8093ed7b9cda 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/ModuleNode.java @@ -84,7 +84,7 @@ public class ModuleNode extends ModuleVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public ModuleNode(final String name, final int access, final String version) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); if (getClass() != ModuleNode.class) { throw new IllegalStateException(); } diff --git a/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java index 8634828ba63d7212e97ffd3db798bff550c9a8be..66825fc423de5434e5105ecb67e0dde94bbde764 100644 --- a/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java +++ b/asm-tree/src/main/java/org/objectweb/asm/tree/TypeAnnotationNode.java @@ -59,7 +59,7 @@ public class TypeAnnotationNode extends AnnotationNode { * @throws IllegalStateException If a subclass calls this constructor. */ public TypeAnnotationNode(final int typeRef, final TypePath typePath, final String descriptor) { - this(Opcodes.ASM7, typeRef, typePath, descriptor); + this(/* latest api = */ Opcodes.ASM7, typeRef, typePath, descriptor); if (getClass() != TypeAnnotationNode.class) { throw new IllegalStateException(); } diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java index 87069b57d97d373325d7722b99de818e4f9099d0..4db26993f9def4b772863fdec12ccd3156dc7619 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/AnnotationNodeTest.java @@ -103,7 +103,7 @@ public class AnnotationNodeTest extends AsmTest { annotationNode.visitAnnotation("annotation", "Lpkg/Annotation;"); AnnotationNode dstAnnotationNode = new AnnotationNode("LJ;"); AnnotationVisitor skipNestedAnnotationsVisitor = - new AnnotationVisitor(Opcodes.ASM7, dstAnnotationNode) { + new AnnotationVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL, dstAnnotationNode) { @Override public AnnotationVisitor visitAnnotation(final String name, final String descriptor) { diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java index 2cf2a144cd4c3f1f7d17531caa5dc4be7f222dfd..0b9985fdd64c79e4ac996d00ef9b627f550a7fcd 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/ClassNodeTest.java @@ -221,6 +221,9 @@ public class ClassNodeTest extends AsmTest { @Override public void visitNestMember(final String nestMember) {} + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) {} + @Override public void visitAttribute(final Attribute attribute) {} } diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java index d5ebeb72e011dca8d03566d741e5a9bdd62020cb..1a523e738a07fcd8508f13fd55386c7ebd5084ea 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/InsnListTest.java @@ -109,7 +109,7 @@ public class InsnListTest { InsnList dstInsnList = new InsnList(); insnList.accept( - new MethodVisitor(Opcodes.ASM7) { + new MethodVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visitInsn(final int opcode) { dstInsnList.add(new InsnNode(opcode)); diff --git a/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java b/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java index fa6134e9fbe30352b57420104e7d1f34a1e6c783..0dab5d2f890feb2804c00ac388582d4f9b221319 100644 --- a/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java +++ b/asm-tree/src/test/java/org/objectweb/asm/tree/ModuleNodeTest.java @@ -48,7 +48,16 @@ public class ModuleNodeTest extends AsmTest { public void testConstructor() { ModuleNode moduleNode1 = new ModuleNode("module1", 123, "1.0"); ModuleNode moduleNode2 = - new ModuleNode(Opcodes.ASM7, "module2", 456, "2.0", null, null, null, null, null); + new ModuleNode( + /* latest */ Opcodes.ASM8_EXPERIMENTAL, + "module2", + 456, + "2.0", + null, + null, + null, + null, + null); assertEquals("module1", moduleNode1.name); assertEquals(123, moduleNode1.access); @@ -70,7 +79,7 @@ public class ModuleNodeTest extends AsmTest { ModuleNode moduleNode = new ModuleNode("module", 123, "1.0"); ModuleNode dstModuleNode = new ModuleNode("", 0, ""); ClassVisitor copyModuleVisitor = - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public ModuleVisitor visitModule( final String name, final int access, final String version) { diff --git a/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java index f459eddc40f0e16f5d8b806f1af6b77366c9f398..25266df7915fb8a00802a0db4e12ef8d20e72d28 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/ASMifier.java @@ -123,7 +123,7 @@ public class ASMifier extends Printer { * @throws IllegalStateException If a subclass calls this constructor. */ public ASMifier() { - this(Opcodes.ASM7, "classWriter", 0); + this(/* latest api = */ Opcodes.ASM7, "classWriter", 0); if (getClass() != ASMifier.class) { throw new IllegalStateException(); } @@ -320,6 +320,15 @@ public class ASMifier extends Printer { text.add(stringBuilder.toString()); } + @Override + public void visitPermittedSubtypeExperimental(final String visitPermittedSubtype) { + stringBuilder.setLength(0); + stringBuilder.append("classWriter.visitPermittedSubtypeExperimental("); + appendConstant(visitPermittedSubtype); + stringBuilder.append(END_PARAMETERS); + text.add(stringBuilder.toString()); + } + @Override public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java index 6a868f367f3b50559f5d339ed900424340f4f7a1..372658ca8e78495301b77baead979c0c70265292 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckAnnotationAdapter.java @@ -52,7 +52,7 @@ public class CheckAnnotationAdapter extends AnnotationVisitor { } CheckAnnotationAdapter(final AnnotationVisitor annotationVisitor, final boolean useNamedValues) { - super(Opcodes.ASM7, annotationVisitor); + super(/* latest api = */ Opcodes.ASM7, annotationVisitor); this.useNamedValue = useNamedValues; } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java index 11792a0cd97614d68e359b09babacfa1818e540c..54117fed49a0f7bb649c17b649bd2e9546539c9b 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckClassAdapter.java @@ -173,7 +173,7 @@ public class CheckClassAdapter extends ClassVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public CheckClassAdapter(final ClassVisitor classVisitor, final boolean checkDataFlow) { - this(Opcodes.ASM7, classVisitor, checkDataFlow); + this(/* latest api = */ Opcodes.ASM7, classVisitor, checkDataFlow); if (getClass() != CheckClassAdapter.class) { throw new IllegalStateException(); } @@ -319,6 +319,13 @@ public class CheckClassAdapter extends ClassVisitor { super.visitNestMember(nestMember); } + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + checkState(); + CheckMethodAdapter.checkInternalName(version, permittedSubtype, "permittedSubtype"); + super.visitPermittedSubtypeExperimental(permittedSubtype); + } + @Override public void visitOuterClass(final String owner, final String name, final String descriptor) { checkState(); @@ -1009,7 +1016,8 @@ public class CheckClassAdapter extends ClassVisitor { final PrintWriter printWriter) { ClassNode classNode = new ClassNode(); classReader.accept( - new CheckClassAdapter(Opcodes.ASM7, classNode, false) {}, ClassReader.SKIP_DEBUG); + new CheckClassAdapter(Opcodes.ASM8_EXPERIMENTAL, classNode, false) {}, + ClassReader.SKIP_DEBUG); Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName); List methods = classNode.methods; diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java index 205d94845b30128dd3f0cef515e495e50ae4af56..12a6eef64b78e0a2644ecb2e15d164508cbaaa85 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckFieldAdapter.java @@ -52,7 +52,7 @@ public class CheckFieldAdapter extends FieldVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public CheckFieldAdapter(final FieldVisitor fieldVisitor) { - this(Opcodes.ASM7, fieldVisitor); + this(/* latest api = */ Opcodes.ASM7, fieldVisitor); if (getClass() != CheckFieldAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java index ba8c0e1be67c5572c973182a76291dae38aeace3..7a78134318d0e2983193bd316a435e1cd62dc9f2 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckMethodAdapter.java @@ -366,7 +366,7 @@ public class CheckMethodAdapter extends MethodVisitor { */ public CheckMethodAdapter( final MethodVisitor methodVisitor, final Map labelInsnIndices) { - this(Opcodes.ASM7, methodVisitor, labelInsnIndices); + this(/* latest api = */ Opcodes.ASM7, methodVisitor, labelInsnIndices); if (getClass() != CheckMethodAdapter.class) { throw new IllegalStateException(); } @@ -412,7 +412,8 @@ public class CheckMethodAdapter extends MethodVisitor { final String descriptor, final MethodVisitor methodVisitor, final Map labelInsnIndices) { - this(Opcodes.ASM7, access, name, descriptor, methodVisitor, labelInsnIndices); + this( + /* latest api = */ Opcodes.ASM7, access, name, descriptor, methodVisitor, labelInsnIndices); if (getClass() != CheckMethodAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java index c2e292d285dea0f2fb7c222955f6813241553202..f1943da5764028ebf0f1c0083731fb66fe8e1942 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckModuleAdapter.java @@ -71,7 +71,7 @@ public class CheckModuleAdapter extends ModuleVisitor { * @throws IllegalStateException If a subclass calls this constructor. */ public CheckModuleAdapter(final ModuleVisitor moduleVisitor, final boolean isOpen) { - this(Opcodes.ASM7, moduleVisitor, isOpen); + this(/* latest api = */ Opcodes.ASM7, moduleVisitor, isOpen); if (getClass() != CheckModuleAdapter.class) { throw new IllegalStateException(); } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java b/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java index 2ec182e1b332fbb9c8ecc87c3cd9f82360827cec..800f90bef7d59790ed5a835e818bfa78d6354d4d 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/CheckSignatureAdapter.java @@ -123,7 +123,7 @@ public class CheckSignatureAdapter extends SignatureVisitor { * null}. */ public CheckSignatureAdapter(final int type, final SignatureVisitor signatureVisitor) { - this(Opcodes.ASM7, type, signatureVisitor); + this(/* latest api = */ Opcodes.ASM7, type, signatureVisitor); } /** diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Printer.java b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java index 93f6e35a5c254c86ee644906ae05faad97d0d0a1..9889540e749923295c98f7c3701ead4ef8a69b3f 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/Printer.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/Printer.java @@ -452,6 +452,19 @@ public abstract class Printer { throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); } + /** + * Experimental, use at your own risk. This method will be renamed when it becomes stable, this + * will break existing code using it. Visits a permitted subtypes. A permitted subtypes is one + * of the allowed subtypes of the current class. + * + * @param permittedSubtype the internal name of a permitted subtype. + * @deprecated this API is experimental. + */ + @Deprecated + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + throw new UnsupportedOperationException(UNSUPPORTED_OPERATION); + } + /** * Class inner name. See {@link org.objectweb.asm.ClassVisitor#visitInnerClass}. * diff --git a/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java index ff81b2c610a9711808e25c1a98f93867ecc05167..3fb36499feb8afeeaad2ef8d44c1a046b28f3bc4 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/Textifier.java @@ -111,7 +111,7 @@ public class Textifier extends Printer { * @throws IllegalStateException If a subclass calls this constructor. */ public Textifier() { - this(Opcodes.ASM7); + this(/* latest api = */ Opcodes.ASM7); if (getClass() != Textifier.class) { throw new IllegalStateException(); } @@ -301,6 +301,15 @@ public class Textifier extends Printer { text.add(stringBuilder.toString()); } + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + stringBuilder.setLength(0); + stringBuilder.append(tab).append("PERMITTEDSUBTYPE "); + appendDescriptor(INTERNAL_NAME, permittedSubtype); + stringBuilder.append('\n'); + text.add(stringBuilder.toString()); + } + @Override public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java index 1cc9621a685a0d66b99734ef064f254836ed9b40..01b22a753948e19d72ca22883ffe9446dd46b673 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceAnnotationVisitor.java @@ -57,7 +57,7 @@ public final class TraceAnnotationVisitor extends AnnotationVisitor { * @param printer the printer to convert the visited annotation into text. */ public TraceAnnotationVisitor(final AnnotationVisitor annotationVisitor, final Printer printer) { - super(Opcodes.ASM7, annotationVisitor); + super(/* latest api = */ Opcodes.ASM7, annotationVisitor); this.printer = printer; } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java index cf9fa51e22cce19b1b20baaf3bf2e70787b27e8b..12397fe8b77fd7f11de404dccff7b5c80a276f67 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceClassVisitor.java @@ -118,7 +118,7 @@ public final class TraceClassVisitor extends ClassVisitor { */ public TraceClassVisitor( final ClassVisitor classVisitor, final Printer printer, final PrintWriter printWriter) { - super(Opcodes.ASM7, classVisitor); + super(/* latest api = */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); this.printWriter = printWriter; this.p = printer; } @@ -186,6 +186,12 @@ public final class TraceClassVisitor extends ClassVisitor { super.visitNestMember(nestMember); } + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + p.visitPermittedSubtypeExperimental(permittedSubtype); + super.visitPermittedSubtypeExperimental(permittedSubtype); + } + @Override public void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java index 7405d34492e1c4a78828af3c4be08df8e9965527..642cf0d6e6249509cc21cc1581b5bb508e9b0007 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceFieldVisitor.java @@ -60,7 +60,7 @@ public final class TraceFieldVisitor extends FieldVisitor { * @param printer the printer to convert the visited field into text. */ public TraceFieldVisitor(final FieldVisitor fieldVisitor, final Printer printer) { - super(Opcodes.ASM7, fieldVisitor); + super(/* latest api = */ Opcodes.ASM7, fieldVisitor); this.p = printer; } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java index 10b8f7f4c0635aa0a93549e232d4c2adaf071933..6a06c48b1819f4e7efc570d3eed5632a609e666a 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceMethodVisitor.java @@ -62,7 +62,7 @@ public final class TraceMethodVisitor extends MethodVisitor { * @param printer the printer to convert the visited method into text. */ public TraceMethodVisitor(final MethodVisitor methodVisitor, final Printer printer) { - super(Opcodes.ASM7, methodVisitor); + super(/* latest api = */ Opcodes.ASM7, methodVisitor); this.p = printer; } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java index 84bbfb1f6ee8ff1314fc1d8662727c4942df26e8..b08ed6c7e04ff54a744010a114675a677ed4c12e 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceModuleVisitor.java @@ -57,7 +57,7 @@ public final class TraceModuleVisitor extends ModuleVisitor { * @param printer the printer to convert the visited module into text. */ public TraceModuleVisitor(final ModuleVisitor moduleVisitor, final Printer printer) { - super(Opcodes.ASM7, moduleVisitor); + super(/* latest api = */ Opcodes.ASM7, moduleVisitor); this.p = printer; } diff --git a/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java b/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java index 09485a5c265b3bd79d02c9cac4e663507c66ff42..77ffe4ff17fff8d14bfb2fd059bed1e0eb7465dc 100644 --- a/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java +++ b/asm-util/src/main/java/org/objectweb/asm/util/TraceSignatureVisitor.java @@ -109,13 +109,13 @@ public final class TraceSignatureVisitor extends SignatureVisitor { * @param accessFlags for class type signatures, the access flags of the class. */ public TraceSignatureVisitor(final int accessFlags) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.isInterface = (accessFlags & Opcodes.ACC_INTERFACE) != 0; this.declaration = new StringBuilder(); } private TraceSignatureVisitor(final StringBuilder stringBuilder) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.isInterface = false; this.declaration = stringBuilder; } diff --git a/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java index 47b57ab781af80e02092975e776e441510755886..01352b521154c355ffc3ba2527739e3553e5cf27 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/CheckClassAdapterTest.java @@ -404,7 +404,7 @@ public class CheckClassAdapterTest extends AsmTest implements Opcodes { final PrecompiledClass classParameter, final Api apiParameter) { byte[] classFile = classParameter.getBytes(); ClassReader classReader = new ClassReader(classFile); - ClassVisitor classVisitor = new CheckClassAdapter(null); + ClassVisitor classVisitor = new CheckClassAdapter(apiParameter.value(), null, true) {}; Executable accept = () -> classReader.accept(classVisitor, attributes(), 0); @@ -417,7 +417,11 @@ public class CheckClassAdapterTest extends AsmTest implements Opcodes { final PrecompiledClass classParameter, final Api apiParameter) { byte[] classFile = classParameter.getBytes(); ClassReader classReader = new ClassReader(classFile); - ClassVisitor classVisitor = new CheckClassAdapter(new ClassVisitor(Opcodes.ASM7, null) {}); + ClassVisitor classVisitor = + new CheckClassAdapter( + apiParameter.value(), + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL, null) {}, + true) {}; Executable accept = () -> classReader.accept(classVisitor, attributes(), 0); diff --git a/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java index 9c6072a94b05e4b9097f65f65d7ccc04dddf0189..3bb00e29344e7920e9c81084b0c0dc023c22799d 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/PrinterTest.java @@ -48,7 +48,7 @@ public class PrinterTest { @Test public void testVisitModule_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitModule = () -> printer.visitModule(null, 0, null); @@ -58,7 +58,7 @@ public class PrinterTest { @Test public void testVisitNestHost_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitNestHost = () -> printer.visitNestHost(null); @@ -68,7 +68,7 @@ public class PrinterTest { @Test public void testVisitClassTypeAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitClassTypeAnnotation = () -> printer.visitClassTypeAnnotation(0, null, null, false); @@ -80,7 +80,7 @@ public class PrinterTest { @Test public void testVisitNestMember_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitNestMember = () -> printer.visitNestMember(null); @@ -88,9 +88,19 @@ public class PrinterTest { assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage()); } + @Test + public void testVisitPermittedSubtype_unsupportedByDefault() { + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); + + Executable visitPermittedSubtype = () -> printer.visitPermittedSubtypeExperimental(null); + + Exception exception = assertThrows(UnsupportedOperationException.class, visitPermittedSubtype); + assertEquals(UNSUPPORTED_OPERATION_MESSAGE, exception.getMessage()); + } + @Test public void testVisitMainClass_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitMainClass = () -> printer.visitMainClass(null); @@ -100,7 +110,7 @@ public class PrinterTest { @Test public void testVisitPackage_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitPackage = () -> printer.visitPackage(null); @@ -110,7 +120,7 @@ public class PrinterTest { @Test public void testVisitRequire_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitRequire = () -> printer.visitRequire(null, 0, null); @@ -120,7 +130,7 @@ public class PrinterTest { @Test public void testVisitExport_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitExport = () -> printer.visitExport(null, 0); @@ -130,7 +140,7 @@ public class PrinterTest { @Test public void testVisitOpen_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitOpen = () -> printer.visitOpen(null, 0); @@ -140,7 +150,7 @@ public class PrinterTest { @Test public void testVisitUse_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitUse = () -> printer.visitUse(null); @@ -150,7 +160,7 @@ public class PrinterTest { @Test public void testVisitProvide_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitProvide = () -> printer.visitProvide(null); @@ -160,7 +170,7 @@ public class PrinterTest { @Test public void testVisitModuleEnd_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitModuleEnd = () -> printer.visitModuleEnd(); @@ -170,7 +180,7 @@ public class PrinterTest { @Test public void testVisitFieldTypeAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitFieldTypeAnnotation = () -> printer.visitFieldTypeAnnotation(0, null, null, false); @@ -182,7 +192,7 @@ public class PrinterTest { @Test public void testVisitParameter_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitParameter = () -> printer.visitParameter(null, 0); @@ -192,7 +202,7 @@ public class PrinterTest { @Test public void testVisitMethodTypeAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitMethodTypeAnnotation = () -> printer.visitMethodTypeAnnotation(0, null, null, false); @@ -204,7 +214,7 @@ public class PrinterTest { @Test public void testVisitAnnotableParameterCount_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitAnnotableParameterCount = () -> printer.visitAnnotableParameterCount(0, false); @@ -226,7 +236,7 @@ public class PrinterTest { @Test public void testVisitMethodInsn_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitMethodInsn = () -> printer.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", false); @@ -237,7 +247,7 @@ public class PrinterTest { @Test public void testVisitMethodInsn_ifItf_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitMethodInsn = () -> printer.visitMethodInsn(Opcodes.INVOKESPECIAL, "owner", "name", "()V", true); @@ -248,7 +258,7 @@ public class PrinterTest { @Test public void testVisitInsnAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitInsnAnnotation = () -> printer.visitInsnAnnotation(0, null, null, false); @@ -258,7 +268,7 @@ public class PrinterTest { @Test public void testVisitTryCatchAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitTryCatchAnnotation = () -> printer.visitTryCatchAnnotation(0, null, null, false); @@ -270,7 +280,7 @@ public class PrinterTest { @Test public void testVisitLocalVariableAnnotation_unsupportedByDefault() { - Printer printer = new EmptyPrinter(Opcodes.ASM7); + Printer printer = new EmptyPrinter(/* latest */ Opcodes.ASM8_EXPERIMENTAL); Executable visitLocalVariableAnnotation = () -> printer.visitLocalVariableAnnotation(0, null, null, null, null, null, false); diff --git a/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java b/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java index 4cd24f7ad46b4f9a0f9a19e9ab13b6634a340571..dceb914ec154238172d743a7b51293fef35ee868 100644 --- a/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java +++ b/asm-util/src/test/java/org/objectweb/asm/util/SignaturesProviders.java @@ -37,7 +37,7 @@ public final class SignaturesProviders { private static void collectSignatures(final PrecompiledClass classParameter) { ClassReader classReader = new ClassReader(classParameter.getBytes()); classReader.accept( - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visit( final int version, diff --git a/asm-util/src/test/resources/jdk14.AllStructures.txt b/asm-util/src/test/resources/jdk14.AllStructures.txt new file mode 100644 index 0000000000000000000000000000000000000000..9dfe2bd03c289c3fa8e743fdc54ed402050ce706 --- /dev/null +++ b/asm-util/src/test/resources/jdk14.AllStructures.txt @@ -0,0 +1,14 @@ +// class version 58.65535 (-65478) +// access flags 0x601 +public abstract interface jdk14/AllStructures { + + // compiled from: AllStructures.java + NESTMEMBER jdk14/AllStructures$RecordSubType + NESTMEMBER jdk14/AllStructures$ClassSubType + PERMITTEDSUBTYPE jdk14/AllStructures$RecordSubType + PERMITTEDSUBTYPE jdk14/AllStructures$ClassSubType + // access flags 0x19 + public final static INNERCLASS jdk14/AllStructures$RecordSubType jdk14/AllStructures RecordSubType + // access flags 0x19 + public final static INNERCLASS jdk14/AllStructures$ClassSubType jdk14/AllStructures ClassSubType +} diff --git a/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java b/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java index 63d5360714d42ed96c0a3f476bbc53660cfb2953..92f7feb07756aab21bff8af93f979d7a7e732237 100644 --- a/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/AnnotationVisitor.java @@ -68,9 +68,16 @@ public abstract class AnnotationVisitor { * calls. May be {@literal null}. */ public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM8_EXPERIMENTAL) { + Constants.checkAsm8Experimental(this); + } this.api = api; this.av = annotationVisitor; } diff --git a/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java b/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java index d85e255d867f30c08327a1a426ed856b330bb5c3..009d94bb93c796dc9e71fe490a7d4f0a533d0f1c 100644 --- a/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java +++ b/asm/src/main/java/org/objectweb/asm/AnnotationWriter.java @@ -112,7 +112,7 @@ final class AnnotationWriter extends AnnotationVisitor { final boolean useNamedValues, final ByteVector annotation, final AnnotationWriter previousAnnotation) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.symbolTable = symbolTable; this.useNamedValues = useNamedValues; this.annotation = annotation; diff --git a/asm/src/main/java/org/objectweb/asm/ClassReader.java b/asm/src/main/java/org/objectweb/asm/ClassReader.java index 8ebc7a237d82895424b1de05f3b419bbb62cee0d..a7520739ac443adf07738590b8a3d24d76a6963b 100644 --- a/asm/src/main/java/org/objectweb/asm/ClassReader.java +++ b/asm/src/main/java/org/objectweb/asm/ClassReader.java @@ -466,6 +466,8 @@ public class ClassReader { String nestHostClass = null; // - The offset of the NestMembers attribute, or 0. int nestMembersOffset = 0; + // - The offset of the PermittedSubtypes attribute, or 0 + int permittedSubtypesOffset = 0; // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field). // This list in the reverse order or their order in the ClassFile structure. Attribute attributes = null; @@ -488,6 +490,8 @@ public class ClassReader { nestHostClass = readClass(currentAttributeOffset, charBuffer); } else if (Constants.NEST_MEMBERS.equals(attributeName)) { nestMembersOffset = currentAttributeOffset; + } else if (Constants.PERMITTED_SUBTYPES.equals(attributeName)) { + permittedSubtypesOffset = currentAttributeOffset; } else if (Constants.SIGNATURE.equals(attributeName)) { signature = readUTF8(currentAttributeOffset, charBuffer); } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { @@ -662,6 +666,17 @@ public class ClassReader { } } + // Visit the PermittedSubtypes attribute. + if (permittedSubtypesOffset != 0) { + int numberOfPermittedSubtypes = readUnsignedShort(permittedSubtypesOffset); + int currentPermittedSubtypeOffset = permittedSubtypesOffset + 2; + while (numberOfPermittedSubtypes-- > 0) { + classVisitor.visitPermittedSubtypeExperimental( + readClass(currentPermittedSubtypeOffset, charBuffer)); + currentPermittedSubtypeOffset += 2; + } + } + // Visit the InnerClasses attribute. if (innerClassesOffset != 0) { int numberOfClasses = readUnsignedShort(innerClassesOffset); diff --git a/asm/src/main/java/org/objectweb/asm/ClassVisitor.java b/asm/src/main/java/org/objectweb/asm/ClassVisitor.java index 0c3d2decc676cc7c79192d7472a91879bac185c3..5fd79987eda2a5ce6ae9fe7ef15807b47c3abd72 100644 --- a/asm/src/main/java/org/objectweb/asm/ClassVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/ClassVisitor.java @@ -30,9 +30,9 @@ package org.objectweb.asm; /** * A visitor to visit a Java class. The methods of this class must be called in the following order: * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code - * visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code - * visitAttribute} )* ( {@code visitNestMember} | {@code visitInnerClass} | {@code visitField} | - * {@code visitMethod} )* {@code visitEnd}. + * visitPermittedSubtype} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code + * visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code + * visitInnerClass} | {@code visitField} | {@code visitMethod} )* {@code visitEnd}. * * @author Eric Bruneton */ @@ -66,9 +66,16 @@ public abstract class ClassVisitor { * null. */ public ClassVisitor(final int api, final ClassVisitor classVisitor) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM8_EXPERIMENTAL) { + Constants.checkAsm8Experimental(this); + } this.api = api; this.cv = classVisitor; } @@ -240,6 +247,24 @@ public abstract class ClassVisitor { } } + /** + * Experimental, use at your own risk. This method will be renamed when it becomes stable, this + * will break existing code using it. Visits a permitted subtypes. A permitted subtypes is one + * of the allowed subtypes of the current class. + * + * @param permittedSubtype the internal name of a permitted subtype. + * @deprecated this API is experimental. + */ + @Deprecated + public void visitPermittedSubtypeExperimental(final String permittedSubtype) { + if (api != Opcodes.ASM8_EXPERIMENTAL) { + throw new UnsupportedOperationException("This feature requires ASM8_EXPERIMENTAL"); + } + if (cv != null) { + cv.visitPermittedSubtypeExperimental(permittedSubtype); + } + } + /** * Visits information about an inner class. This inner class is not necessarily a member of the * class being visited. diff --git a/asm/src/main/java/org/objectweb/asm/ClassWriter.java b/asm/src/main/java/org/objectweb/asm/ClassWriter.java index d18797418fcb75bf679a33fa22c0c5d9b01135f4..40c2af03377fdb1dda7a0513677b6bb158b0236c 100644 --- a/asm/src/main/java/org/objectweb/asm/ClassWriter.java +++ b/asm/src/main/java/org/objectweb/asm/ClassWriter.java @@ -177,6 +177,12 @@ public class ClassWriter extends ClassVisitor { /** The 'classes' array of the NestMembers attribute, or {@literal null}. */ private ByteVector nestMemberClasses; + /** The number_of_classes field of the PermittedSubtypes attribute, or 0. */ + private int numberOfPermittedSubtypeClasses; + + /** The 'classes' array of the PermittedSubtypes attribute, or {@literal null}. */ + private ByteVector permittedSubtypeClasses; + /** * The first non standard attribute of this class. The next ones can be accessed with the {@link * Attribute#nextAttribute} field. May be {@literal null}. @@ -234,7 +240,7 @@ public class ClassWriter extends ClassVisitor { * maximum stack size nor the stack frames will be computed for these methods. */ public ClassWriter(final ClassReader classReader, final int flags) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader); if ((flags & COMPUTE_FRAMES) != 0) { this.compute = MethodWriter.COMPUTE_ALL_FRAMES; @@ -352,6 +358,15 @@ public class ClassWriter extends ClassVisitor { nestMemberClasses.putShort(symbolTable.addConstantClass(nestMember).index); } + @Override + public final void visitPermittedSubtypeExperimental(final String permittedSubtype) { + if (permittedSubtypeClasses == null) { + permittedSubtypeClasses = new ByteVector(); + } + ++numberOfPermittedSubtypeClasses; + permittedSubtypeClasses.putShort(symbolTable.addConstantClass(permittedSubtype).index); + } + @Override public final void visitInnerClass( final String name, final String outerName, final String innerName, final int access) { @@ -526,6 +541,11 @@ public class ClassWriter extends ClassVisitor { size += 8 + nestMemberClasses.length; symbolTable.addConstantUtf8(Constants.NEST_MEMBERS); } + if (permittedSubtypeClasses != null) { + ++attributesCount; + size += 8 + permittedSubtypeClasses.length; + symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES); + } if (firstAttribute != null) { attributesCount += firstAttribute.getAttributeCount(); size += firstAttribute.computeAttributesSize(symbolTable); @@ -630,6 +650,13 @@ public class ClassWriter extends ClassVisitor { .putShort(numberOfNestMemberClasses) .putByteArray(nestMemberClasses.data, 0, nestMemberClasses.length); } + if (permittedSubtypeClasses != null) { + result + .putShort(symbolTable.addConstantUtf8(Constants.PERMITTED_SUBTYPES)) + .putInt(permittedSubtypeClasses.length + 2) + .putShort(numberOfPermittedSubtypeClasses) + .putByteArray(permittedSubtypeClasses.data, 0, permittedSubtypeClasses.length); + } if (firstAttribute != null) { firstAttribute.putAttributes(symbolTable, result); } @@ -666,6 +693,8 @@ public class ClassWriter extends ClassVisitor { nestHostClassIndex = 0; numberOfNestMemberClasses = 0; nestMemberClasses = null; + numberOfPermittedSubtypeClasses = 0; + permittedSubtypeClasses = null; firstAttribute = null; compute = hasFrames ? MethodWriter.COMPUTE_INSERTED_FRAMES : MethodWriter.COMPUTE_NOTHING; new ClassReader(classFile, 0, /* checkClassVersion = */ false) diff --git a/asm/src/main/java/org/objectweb/asm/Constants.java b/asm/src/main/java/org/objectweb/asm/Constants.java index 26db7e9c8f337d154f984f6f3f508a44d54400e5..8e4beef2efa83063e50220188b7546c0dc263f49 100644 --- a/asm/src/main/java/org/objectweb/asm/Constants.java +++ b/asm/src/main/java/org/objectweb/asm/Constants.java @@ -27,6 +27,10 @@ // THE POSSIBILITY OF SUCH DAMAGE. package org.objectweb.asm; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + /** * Defines additional JVM opcodes, access flags and constants which are not part of the ASM public * API. @@ -68,6 +72,7 @@ final class Constants implements Opcodes { static final String MODULE_MAIN_CLASS = "ModuleMainClass"; static final String NEST_HOST = "NestHost"; static final String NEST_MEMBERS = "NestMembers"; + static final String PERMITTED_SUBTYPES = "PermittedSubtypes"; // ASM specific access flags. // WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard @@ -174,4 +179,27 @@ final class Constants implements Opcodes { static final int ASM_GOTO_W = 220; private Constants() {} + + static void checkAsm8Experimental(final Object caller) { + Class callerClass = caller.getClass(); + if (callerClass.getName().startsWith("org.objectweb.asm.")) { + return; + } + String callerClassResource = callerClass.getName().replace('.', '/') + ".class"; + InputStream inputStream = callerClass.getClassLoader().getResourceAsStream(callerClassResource); + if (inputStream == null) { + throw new IllegalStateException("Bytecode not available, can't check class version"); + } + int minorVersion; + try (DataInputStream callerClassStream = new DataInputStream(inputStream); ) { + callerClassStream.readInt(); + minorVersion = callerClassStream.readUnsignedShort(); + } catch (IOException ioe) { + throw new IllegalStateException("i/O error, can't check class version", ioe); + } + if (minorVersion != 0xFFFF) { + throw new IllegalStateException( + "ASM8_EXPERIMENTAL can only be used by classes compiled with --enable-preview"); + } + } } diff --git a/asm/src/main/java/org/objectweb/asm/FieldVisitor.java b/asm/src/main/java/org/objectweb/asm/FieldVisitor.java index 2371baa44fc6a416cf094ab16adabfb56f6b79f6..797651c3c1fa932609c68c06fd6a815dc48c4662 100644 --- a/asm/src/main/java/org/objectweb/asm/FieldVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/FieldVisitor.java @@ -64,9 +64,16 @@ public abstract class FieldVisitor { * null. */ public FieldVisitor(final int api, final FieldVisitor fieldVisitor) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM8_EXPERIMENTAL) { + Constants.checkAsm8Experimental(this); + } this.api = api; this.fv = fieldVisitor; } diff --git a/asm/src/main/java/org/objectweb/asm/FieldWriter.java b/asm/src/main/java/org/objectweb/asm/FieldWriter.java index dec33121ebaeddd45fcda420940e3eb6d04e79b9..bd5fd858fb06fb517a3c1ad3620513624289821c 100644 --- a/asm/src/main/java/org/objectweb/asm/FieldWriter.java +++ b/asm/src/main/java/org/objectweb/asm/FieldWriter.java @@ -124,7 +124,7 @@ final class FieldWriter extends FieldVisitor { final String descriptor, final String signature, final Object constantValue) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.symbolTable = symbolTable; this.accessFlags = access; this.nameIndex = symbolTable.addConstantUtf8(name); diff --git a/asm/src/main/java/org/objectweb/asm/MethodVisitor.java b/asm/src/main/java/org/objectweb/asm/MethodVisitor.java index fadfd6a43115531342d6d5a43fba073e9ae631bf..0088aef3c59a16ac567d7ccad2c259ebb1605361 100644 --- a/asm/src/main/java/org/objectweb/asm/MethodVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/MethodVisitor.java @@ -80,9 +80,16 @@ public abstract class MethodVisitor { * be null. */ public MethodVisitor(final int api, final MethodVisitor methodVisitor) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM8_EXPERIMENTAL) { + Constants.checkAsm8Experimental(this); + } this.api = api; this.mv = methodVisitor; } @@ -534,7 +541,7 @@ public abstract class MethodVisitor { || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) { throw new UnsupportedOperationException(REQUIRES_ASM5); } - if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) { + if (api < Opcodes.ASM7 && value instanceof ConstantDynamic) { throw new UnsupportedOperationException("This feature requires ASM7"); } if (mv != null) { diff --git a/asm/src/main/java/org/objectweb/asm/MethodWriter.java b/asm/src/main/java/org/objectweb/asm/MethodWriter.java index 6bd72efccdb5f720e8141487a0b435fdc8dbccb2..0eda40c757d91bfe4d13102fc7279528d7ddb1d5 100644 --- a/asm/src/main/java/org/objectweb/asm/MethodWriter.java +++ b/asm/src/main/java/org/objectweb/asm/MethodWriter.java @@ -592,7 +592,7 @@ final class MethodWriter extends MethodVisitor { final String signature, final String[] exceptions, final int compute) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.symbolTable = symbolTable; this.accessFlags = "".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access; this.nameIndex = symbolTable.addConstantUtf8(name); diff --git a/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java b/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java index dced10ba1ca5320c466471ace8f2bdf2b3fc3723..0aec7ded6efed199b8df5029a3cd92bea5a4a720 100644 --- a/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/ModuleVisitor.java @@ -66,9 +66,16 @@ public abstract class ModuleVisitor { * be null. */ public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } + if (api == Opcodes.ASM8_EXPERIMENTAL) { + Constants.checkAsm8Experimental(this); + } this.api = api; this.mv = moduleVisitor; } diff --git a/asm/src/main/java/org/objectweb/asm/ModuleWriter.java b/asm/src/main/java/org/objectweb/asm/ModuleWriter.java index 7658734db686096ddfe79a9fd2be1fec2f16c019..b7015f5025b7161cd49f6c0ab3fd8fcaf1603a3c 100644 --- a/asm/src/main/java/org/objectweb/asm/ModuleWriter.java +++ b/asm/src/main/java/org/objectweb/asm/ModuleWriter.java @@ -94,7 +94,7 @@ final class ModuleWriter extends ModuleVisitor { private int mainClassIndex; ModuleWriter(final SymbolTable symbolTable, final int name, final int access, final int version) { - super(Opcodes.ASM7); + super(/* latest api = */ Opcodes.ASM7); this.symbolTable = symbolTable; this.moduleNameIndex = name; this.moduleFlags = access; diff --git a/asm/src/main/java/org/objectweb/asm/Opcodes.java b/asm/src/main/java/org/objectweb/asm/Opcodes.java index ef25ea5a348d920ae713009d81eecf67dc503ed1..e11867a7756a43daf1a73a3871070467288440e9 100644 --- a/asm/src/main/java/org/objectweb/asm/Opcodes.java +++ b/asm/src/main/java/org/objectweb/asm/Opcodes.java @@ -48,6 +48,14 @@ public interface Opcodes { int ASM6 = 6 << 16 | 0 << 8; int ASM7 = 7 << 16 | 0 << 8; + /** + * Experimental, use at your own risk. This field will be renamed when it becomes stable, this + * will break existing code using it. Only code compiled with --enable-preview can use this. + * + * @deprecated This API is experimental. + */ + @Deprecated int ASM8_EXPERIMENTAL = 1 << 24 | 8 << 16 | 0 << 8; + /* * Internal flags used to redirect calls to deprecated methods. For instance, if a visitOldStuff * method in API_OLD is deprecated and replaced with visitNewStuff in API_NEW, then the diff --git a/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java b/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java index 4b1f2b62b5d4313849c4659ca90274c89ff79b69..f2d21862d85a4857b32555839fe49d294e669e4c 100644 --- a/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java +++ b/asm/src/main/java/org/objectweb/asm/signature/SignatureVisitor.java @@ -72,7 +72,11 @@ public abstract class SignatureVisitor { * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. */ public SignatureVisitor(final int api) { - if (api != Opcodes.ASM7 && api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4) { + if (api != Opcodes.ASM7 + && api != Opcodes.ASM6 + && api != Opcodes.ASM5 + && api != Opcodes.ASM4 + && api != Opcodes.ASM8_EXPERIMENTAL) { throw new IllegalArgumentException("Unsupported api " + api); } this.api = api; diff --git a/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java index 0be0442d139bc19b205bcad25df5979b5646b906..df649189ff10a3aacd0ee9b0d126290e3baf84e4 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassReaderTest.java @@ -398,6 +398,9 @@ public class ClassReaderTest extends AsmTest implements Opcodes { @Override public void visitNestMember(final String nestMember) {} + + @Override + public void visitPermittedSubtypeExperimental(final String permittedSubtype) {} }; Executable accept = () -> classReader.accept(classVisitor, 0); @@ -414,7 +417,8 @@ public class ClassReaderTest extends AsmTest implements Opcodes { || invalidClass == InvalidClass.INVALID_CP_INFO_TAG); ClassReader classReader = new ClassReader(invalidClass.getBytes()); - Executable accept = () -> classReader.accept(new EmptyClassVisitor(ASM7), 0); + Executable accept = + () -> classReader.accept(new EmptyClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL), 0); if (invalidClass == InvalidClass.INVALID_CONSTANT_POOL_INDEX || invalidClass == InvalidClass.INVALID_CONSTANT_POOL_REFERENCE @@ -437,12 +441,14 @@ public class ClassReaderTest extends AsmTest implements Opcodes { Executable accept = () -> classReader.accept(classVisitor, 0); + boolean hasPermittedSubtypes = classParameter == PrecompiledClass.JDK14_ALL_STRUCTURES; boolean hasNestHostOrMembers = classParameter == PrecompiledClass.JDK11_ALL_STRUCTURES || classParameter == PrecompiledClass.JDK11_ALL_STRUCTURES_NESTED; boolean hasModules = classParameter == PrecompiledClass.JDK9_MODULE; boolean hasTypeAnnotations = classParameter == PrecompiledClass.JDK8_ALL_STRUCTURES; - if ((hasNestHostOrMembers && apiParameter.value() < ASM7) + if ((hasPermittedSubtypes && apiParameter.value() != ASM8_EXPERIMENTAL) + || (hasNestHostOrMembers && apiParameter.value() < ASM7) || (hasModules && apiParameter.value() < ASM6) || (hasTypeAnnotations && apiParameter.value() < ASM5)) { Exception exception = assertThrows(UnsupportedOperationException.class, accept); @@ -520,7 +526,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { ClassReader classReader = new ClassReader(PrecompiledClass.JDK5_LOCAL_CLASS.getBytes()); AtomicInteger parameterIndex = new AtomicInteger(-1); ClassVisitor readParameterIndexVisitor = - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public MethodVisitor visitMethod( final int access, @@ -555,7 +561,7 @@ public class ClassReaderTest extends AsmTest implements Opcodes { ClassReader classReader = new ClassReader(classFile); AtomicInteger classVersion = new AtomicInteger(0); ClassVisitor readVersionVisitor = - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visit( final int version, diff --git a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java index 292d565601205b1fb79e51d48d7c1f8517ff856c..e81e2af8fd14481eafb0313b05800ef1431f1438 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java @@ -250,7 +250,7 @@ public class ClassVisitorTest extends AsmTest { ClassReader classReader = new ClassReader(classFile); ClassWriter classWriter = new ClassWriter(0); ClassVisitor classVisitor = - new ClassVisitor(Opcodes.ASM7, classWriter) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classWriter) { @Override public ModuleVisitor visitModule( @@ -454,7 +454,7 @@ public class ClassVisitorTest extends AsmTest { private static class ChangeExceptionAdapter extends ClassVisitor { ChangeExceptionAdapter(final ClassVisitor classVisitor) { - super(Opcodes.ASM7, classVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); } @Override @@ -476,7 +476,7 @@ public class ClassVisitorTest extends AsmTest { private final int newVersion; ChangeVersionAdapter(final ClassVisitor classVisitor, final int newVersion) { - super(Opcodes.ASM7, classVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); this.newVersion = newVersion; } @@ -497,7 +497,7 @@ public class ClassVisitorTest extends AsmTest { private final int accessFlags; ChangeAccessAdapter(final ClassVisitor classVisitor, final int accessFlags) { - super(Opcodes.ASM7, classVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); this.accessFlags = accessFlags; } @@ -518,7 +518,7 @@ public class ClassVisitorTest extends AsmTest { private final boolean visibilityValue; RemoveAnnotationAdapter(final ClassVisitor classVisitor, final boolean visibilityValue) { - super(Opcodes.ASM7, classVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); this.visibilityValue = visibilityValue; } @@ -659,7 +659,7 @@ public class ClassVisitorTest extends AsmTest { private static class AddParameterAdapter extends ClassVisitor { public AddParameterAdapter(final ClassVisitor classVisitor) { - super(Opcodes.ASM7, classVisitor); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classVisitor); } @Override diff --git a/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java index 99dcc81e6b3fe8e9088307c7fb4d144f213d7681..0ecab7ae7892bfef74b606173644c08b82d7160e 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassWriterTest.java @@ -105,6 +105,8 @@ public class ClassWriterTest extends AsmTest { "nestHostClassIndex", "numberOfNestMemberClasses", "nestMemberClasses", + "numberOfPermittedSubtypeClasses", + "permittedSubtypeClasses", "firstAttribute", "compute")); // IMPORTANT: if this fails, update the string list AND update the logic that resets the diff --git a/asm/src/test/java/org/objectweb/asm/ConstantsTest.java b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java index 4fa80bcd7033944d08e774f0f6cb418f35643983..35db5daf94a5051dcc674349da938e7e387efd9f 100644 --- a/asm/src/test/java/org/objectweb/asm/ConstantsTest.java +++ b/asm/src/test/java/org/objectweb/asm/ConstantsTest.java @@ -137,8 +137,7 @@ public class ConstantsTest { List verificationTypeInfoTags = getConstants(ConstantType.VERIFICATION_TYPE_INFO_TAG); Set verificationTypeInfoTagValues = - verificationTypeInfoTags - .stream() + verificationTypeInfoTags.stream() .map(ConstantsTest::getIntegerValue) .collect(Collectors.toSet()); @@ -163,8 +162,7 @@ public class ConstantsTest { } private static List getConstants(final ConstantType constantType) { - return Arrays.asList(Constants.class.getFields()) - .stream() + return Arrays.asList(Constants.class.getFields()).stream() .filter(field -> getType(field).equals(constantType)) .collect(Collectors.toList()); } @@ -175,6 +173,7 @@ public class ConstantsTest { case "ASM5": case "ASM6": case "ASM7": + case "ASM8_EXPERIMENTAL": return ConstantType.ASM_VERSION; case "V_PREVIEW": case "V1_1": @@ -217,6 +216,7 @@ public class ConstantsTest { case "ACC_MODULE": return ConstantType.ACCESS_FLAG; case "ACC_DEPRECATED": + case "ACC_SEALED": case "ACC_CONSTRUCTOR": return ConstantType.ASM_ACCESS_FLAG; case "T_BOOLEAN": diff --git a/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java b/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java index c5cd57bc415ba470a737a8c086f3c17efd4b40c1..da4b31e411487cfda4736f5412fd22a4989afdc8 100644 --- a/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java +++ b/asm/src/test/java/org/objectweb/asm/MethodVisitorTest.java @@ -535,13 +535,13 @@ public class MethodVisitorTest extends AsmTest { } } - /** A {@link MethodVisitor} that logs the calls to its ASM5 visitMethodInsn method. */ + /** A {@link MethodVisitor} that logs the calls to its visitMethodInsn method. */ private static class LogMethodVisitor extends MethodVisitor { private final StringWriter log; LogMethodVisitor(final StringWriter log) { - super(Opcodes.ASM7); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL); this.log = log; } diff --git a/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java b/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java index c3fa0487915b5fe33d519cde3e101ce2a6dc0d27..ba8179f2c9a96373ef6cc6a93f53aff2087cf2e1 100644 --- a/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java +++ b/asm/src/test/java/org/objectweb/asm/MethodWriterTest.java @@ -92,7 +92,8 @@ public class MethodWriterTest { Constants.MODULE_PACKAGES, Constants.MODULE_MAIN_CLASS, Constants.NEST_HOST, - Constants.NEST_MEMBERS)); + Constants.NEST_MEMBERS, + Constants.PERMITTED_SUBTYPES)); // IMPORTANT: if this fails, update the list AND update MethodWriter.canCopyMethodAttributes(), // if needed. assertEquals(expectedAttributes, actualAttributes); diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java b/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java index d2646817a0e79410e991ebee66532893d9bc86ed..fba35b85932cd2ed99565809b2fdcc22d6fa34db 100644 --- a/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java +++ b/asm/src/test/java/org/objectweb/asm/signature/SignatureReaderTest.java @@ -51,7 +51,8 @@ public class SignatureReaderTest extends AsmTest { }) public void testAccept_validClassOrMethodSignature(final String signature) { SignatureReader signatureReader = new SignatureReader(signature); - SignatureVisitor signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {}; + SignatureVisitor signatureVisitor = + new SignatureVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) {}; Executable acceptVisitor = () -> signatureReader.accept(signatureVisitor); @@ -62,7 +63,8 @@ public class SignatureReaderTest extends AsmTest { @MethodSource("org.objectweb.asm.signature.SignaturesProviders#fieldSignatures") public void testAccept_validFieldSignature(final String signature) { SignatureReader signatureReader = new SignatureReader(signature); - SignatureVisitor signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {}; + SignatureVisitor signatureVisitor = + new SignatureVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) {}; Executable acceptVisitor = () -> signatureReader.acceptType(signatureVisitor); @@ -73,7 +75,8 @@ public class SignatureReaderTest extends AsmTest { public void testAccept_invalidSignature() { String invalidSignature = "-"; SignatureReader signatureReader = new SignatureReader(invalidSignature); - SignatureVisitor signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {}; + SignatureVisitor signatureVisitor = + new SignatureVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) {}; Executable acceptVisitor = () -> signatureReader.accept(signatureVisitor); diff --git a/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java index 382098653ad3973bae60ecfa2cb8feae3ba76990..e1207ecb29676f57130572d5bb1b7eaee61266e4 100644 --- a/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java +++ b/asm/src/test/java/org/objectweb/asm/signature/SignaturesProviders.java @@ -37,7 +37,7 @@ public final class SignaturesProviders { private static void collectSignatures(final PrecompiledClass classParameter) { ClassReader classReader = new ClassReader(classParameter.getBytes()); classReader.accept( - new ClassVisitor(Opcodes.ASM7) { + new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { @Override public void visit( final int version, diff --git a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java index 79505312bbae70c8320940741f1e4f575e6b42e6..98d66ed4872a1d46ef620e8fe04604551a9edde8 100644 --- a/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java +++ b/benchmarks/src/jmh/java/org/objectweb/asm/benchmarks/TypeBenchmark.java @@ -88,7 +88,7 @@ public class TypeBenchmark extends AbstractBenchmark { }; CollectTypesVisitor() { - super(Opcodes.ASM7); + super(/* latest */ Opcodes.ASM8_EXPERIMENTAL); } @Override diff --git a/build.gradle b/build.gradle index 174ff81b663e254cc5d30cdf3b383995a2e86c48..2bf14fd36cb00ec291a35e3657af6969be8b36c7 100644 --- a/build.gradle +++ b/build.gradle @@ -169,6 +169,7 @@ project(':tools:retrofitter') { // and tested with :asm-test and JUnit. subprojects { apply plugin: 'com.github.sherter.google-java-format' + googleJavaFormat.toolVersion = '1.7' googleJavaFormat.exclude 'src/resources/java/**/*' // Check the coding style with Checkstyle. Fail in case of error or warning.