Commit 9d468c94 authored by Eric Bruneton's avatar Eric Bruneton

Merge branch 'ASM7_NESTMATES'

parents bc615163 76941586
......@@ -56,8 +56,9 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
public static final Type NULL_TYPE = Type.getObjectType("null");
/**
* Constructs a new {@link BasicInterpreter} for the latest ASM API version. <i>Subclasses must not
* use this constructor</i>. Instead, they must use the {@link #BasicInterpreter(int)} version.
* Constructs a new {@link BasicInterpreter} for the latest ASM API version. <i>Subclasses must
* not use this constructor</i>. Instead, they must use the {@link #BasicInterpreter(int)}
* version.
*/
public BasicInterpreter() {
super(ASM6);
......@@ -70,8 +71,8 @@ public class BasicInterpreter extends Interpreter<BasicValue> implements Opcodes
* Constructs a new {@link BasicInterpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
*/
protected BasicInterpreter(final int api) {
super(api);
......
......@@ -44,8 +44,8 @@ import org.objectweb.asm.tree.MethodInsnNode;
public class BasicVerifier extends BasicInterpreter {
/**
* Constructs a new {@link BasicVerifier} for the latest ASM API version. <i>Subclasses must not use
* this constructor</i>. Instead, they must use the {@link #BasicVerifier(int)} version.
* Constructs a new {@link BasicVerifier} for the latest ASM API version. <i>Subclasses must not
* use this constructor</i>. Instead, they must use the {@link #BasicVerifier(int)} version.
*/
public BasicVerifier() {
super(ASM6);
......@@ -58,8 +58,8 @@ public class BasicVerifier extends BasicInterpreter {
* Constructs a new {@link BasicVerifier}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
*/
protected BasicVerifier(final int api) {
super(api);
......
......@@ -46,8 +46,8 @@ public abstract class Interpreter<V extends Value> {
/**
* The ASM API version supported by this interpreter. The value of this field must be one of
* {@link org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* {@link org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
*/
protected final int api;
......@@ -55,8 +55,8 @@ public abstract class Interpreter<V extends Value> {
* Constructs a new {@link Interpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
*/
protected Interpreter(final int api) {
this.api = api;
......
......@@ -105,8 +105,8 @@ public class SimpleVerifier extends BasicVerifier {
* loaded into the JVM since it may be incorrect.
*
* @param api the ASM API version supported by this verifier. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
* @param currentClass the type of the class to be verified.
* @param currentSuperClass the type of the super class of the class to be verified.
* @param currentClassInterfaces the types of the interfaces directly implemented by the class to
......
......@@ -47,8 +47,9 @@ import org.objectweb.asm.tree.MethodInsnNode;
public class SourceInterpreter extends Interpreter<SourceValue> implements Opcodes {
/**
* Constructs a new {@link SourceInterpreter} for the latest ASM API version. <i>Subclasses must not
* use this constructor</i>. Instead, they must use the {@link #SourceInterpreter(int)} version.
* Constructs a new {@link SourceInterpreter} for the latest ASM API version. <i>Subclasses must
* not use this constructor</i>. Instead, they must use the {@link #SourceInterpreter(int)}
* version.
*/
public SourceInterpreter() {
super(ASM6);
......@@ -61,8 +62,8 @@ public class SourceInterpreter extends Interpreter<SourceValue> implements Opcod
* Constructs a new {@link SourceInterpreter}.
*
* @param api the ASM API version supported by this interpreter. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
*/
protected SourceInterpreter(final int api) {
super(api);
......
......@@ -523,7 +523,12 @@ public class SimpleVerifierTest extends AsmTest implements Opcodes {
ClassNode classNode = new ClassNode();
new ClassReader(classParameter.getBytes()).accept(classNode, 0);
for (MethodNode methodNode : classNode.methods) {
Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(new SimpleVerifier());
Analyzer<BasicValue> analyzer =
new Analyzer<BasicValue>(
new SimpleVerifier(
Type.getObjectType(classNode.name),
Type.getObjectType(classNode.superName),
(classNode.access & Opcodes.ACC_INTERFACE) != 0));
analyzer.analyze(classNode.name, methodNode);
}
}
......
......@@ -97,7 +97,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
* Constructs a new {@link AdviceAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param methodVisitor the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......@@ -641,4 +641,4 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
* Opcodes#ATHROW}.
*/
protected void onMethodExit(final int opcode) {}
}
}
\ No newline at end of file
......@@ -126,7 +126,7 @@ public class AnalyzerAdapter extends MethodVisitor {
* Constructs a new {@link AnalyzerAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param owner the owner's class name.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......
......@@ -67,8 +67,8 @@ public class ClassRemapper extends ClassVisitor {
* Constructs a new {@link ClassRemapper}.
*
* @param api the ASM API version supported by this remapper. Must be one of {@link
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5} or {@link
* org.objectweb.asm.Opcodes#ASM6}.
* org.objectweb.asm.Opcodes#ASM4}, {@link org.objectweb.asm.Opcodes#ASM5}, {@link
* org.objectweb.asm.Opcodes#ASM6} or {@link org.objectweb.asm.Opcodes#ASM7_EXPERIMENTAL}.
* @param classVisitor the class visitor this remapper must deleted to.
* @param remapper the remapper to use to remap the types in the visited class.
*/
......@@ -181,6 +181,16 @@ public class ClassRemapper extends ClassVisitor {
descriptor == null ? null : remapper.mapMethodDesc(descriptor));
}
@Override
public void visitNestHostExperimental(final String nestHost) {
super.visitNestHostExperimental(remapper.mapType(nestHost));
}
@Override
public void visitNestMemberExperimental(final String nestMember) {
super.visitNestMemberExperimental(remapper.mapType(nestMember));
}
/**
* Constructs a new remapper for fields. The default implementation of this method returns a new
* {@link FieldRemapper}.
......@@ -224,4 +234,4 @@ public class ClassRemapper extends ClassVisitor {
protected ModuleVisitor createModuleRemapper(final ModuleVisitor moduleVisitor) {
return new ModuleRemapper(api, moduleVisitor, remapper);
}
}
}
\ No newline at end of file
......@@ -211,7 +211,7 @@ public class GeneratorAdapter extends LocalVariablesSorter {
* Constructs a new {@link GeneratorAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param methodVisitor the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
......@@ -1420,4 +1420,4 @@ public class GeneratorAdapter extends LocalVariablesSorter {
}
mark(catchLabel);
}
}
}
\ No newline at end of file
......@@ -62,7 +62,7 @@ public class InstructionAdapter extends MethodVisitor {
* Constructs a new {@link InstructionAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param methodVisitor the method visitor to which this adapter delegates calls.
*/
protected InstructionAdapter(final int api, final MethodVisitor methodVisitor) {
......@@ -1175,4 +1175,4 @@ public class InstructionAdapter extends MethodVisitor {
public void mark(final Label label) {
mv.visitLabel(label);
}
}
}
\ No newline at end of file
......@@ -108,7 +108,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
* Constructs a new {@link JSRInlinerAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param methodVisitor the method visitor to send the resulting inlined method code to, or <code>
* null</code>.
* @param access the method's access flags.
......@@ -560,4 +560,4 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
throw new UnsupportedOperationException();
}
}
}
}
\ No newline at end of file
......@@ -91,7 +91,7 @@ public class LocalVariablesSorter extends MethodVisitor {
* Constructs a new {@link LocalVariablesSorter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param access access flags of the adapted method.
* @param descriptor the method's descriptor (see {@link Type}).
* @param methodVisitor the method visitor to which this adapter delegates calls.
......
......@@ -160,7 +160,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* Constructs a new {@link SerialVersionUIDAdder}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param classVisitor a {@link ClassVisitor} to which this visitor will delegate calls.
*/
protected SerialVersionUIDAdder(final int api, final ClassVisitor classVisitor) {
......@@ -483,4 +483,4 @@ public class SerialVersionUIDAdder extends ClassVisitor {
this.descriptor = descriptor;
}
}
}
}
\ No newline at end of file
......@@ -151,7 +151,7 @@ public class AnalyzerAdapterTest extends AsmTest {
private boolean hasOriginalFrame;
AnalyzedFramesInserter(final MethodVisitor methodVisitor) {
super(Opcodes.ASM6, methodVisitor);
super(Opcodes.ASM7_EXPERIMENTAL, methodVisitor);
}
void setAnalyzerAdapter(final AnalyzerAdapter analyzerAdapter) {
......@@ -288,4 +288,4 @@ public class AnalyzerAdapterTest extends AsmTest {
super.visitMultiANewArrayInsn(descriptor, numDimensions);
}
}
}
}
\ No newline at end of file
......@@ -110,7 +110,7 @@ public class SerialVersionUIDAdderTest extends AsmTest {
final PrecompiledClass classParameter, final Api apiParameter) {
ClassReader classReader = new ClassReader(classParameter.getBytes());
ClassWriter classWriter = new ClassWriter(0);
classReader.accept(new SerialVersionUIDAdder(classWriter), 0);
classReader.accept(new SerialVersionUIDAdder(Opcodes.ASM7_EXPERIMENTAL, classWriter) {}, 0);
if ((classReader.getAccess() & Opcodes.ACC_ENUM) == 0) {
assertThatClass(classWriter.toByteArray()).contains("serialVersionUID");
}
......
......@@ -49,7 +49,7 @@ import java.util.stream.Stream;
/**
* Base class for the ASM tests. ASM can be used to read, write or transform any Java class, ranging
* from very old (e.g. JDK 1.3) to very recent classes, containing all possible class file
* structures. ASM can also be used with different variants of its API (ASM4, ASM5 or ASM6). In
* structures. ASM can also be used with different variants of its API (ASM4, ASM5, ASM6, etc). In
* order to test it thoroughly, it is therefore necessary to run read, write and transform tests,
* for each API version, and for each class in a set of classes containing all possible class file
* structures. The purpose of this class is to automate this process. For this it relies on:
......@@ -65,8 +65,8 @@ import java.util.stream.Stream;
* API) tuple.
* </ul>
*
* For instance, to run a test on all the precompiled classes, with both the ASM5 and the ASM6 API,
* use a subclass such as the following:
* <p>For instance, to run a test on all the precompiled classes, with all the APIs, use a subclass
* such as the following:
*
* <pre>
* public class MyParameterizedTest extends AsmTest {
......@@ -128,7 +128,9 @@ public abstract class AsmTest {
JDK8_ARTIFICIAL_STRUCTURES("jdk8.ArtificialStructures"),
JDK8_INNER_CLASS("jdk8.AllStructures$InnerClass"),
JDK8_LARGE_METHOD("jdk8.LargeMethod"),
JDK9_MODULE("jdk9.module-info");
JDK9_MODULE("jdk9.module-info"),
JDK11_ALL_STRUCTURES("jdk11.AllStructures"),
JDK11_ALL_STRUCTURES_NESTED("jdk11.AllStructures$Nested");
private final String name;
......@@ -155,10 +157,13 @@ public abstract class AsmTest {
* @return whether this class was compiled with a JDK which is more recent than api.
*/
public boolean isMoreRecentThan(final Api api) {
if (name.startsWith("jdk8") && api.value() < Api.ASM5.value()) {
if (name.startsWith("jdk8.") && api.value() < Api.ASM5.value()) {
return true;
}
return name.startsWith("jdk9") && api.value() < Api.ASM6.value();
if (name.startsWith("jdk9.") && api.value() < Api.ASM6.value()) {
return true;
}
return name.startsWith("jdk11.") && api.value() < Api.ASM7.value();
}
/**
......@@ -169,9 +174,12 @@ public abstract class AsmTest {
* less than 9.
*/
public boolean isMoreRecentThanCurrentJdk() {
if (name.startsWith("jdk9")) {
if (name.startsWith("jdk9.")) {
return getMajorJavaVersion() < 9;
}
if (name.startsWith("jdk11.")) {
return getMajorJavaVersion() < 11;
}
return false;
}
......@@ -226,7 +234,8 @@ public abstract class AsmTest {
public enum Api {
ASM4("ASM4", 4 << 16),
ASM5("ASM5", 5 << 16),
ASM6("ASM6", 6 << 16);
ASM6("ASM6", 6 << 16),
ASM7("ASM7", 1 << 24 | 7 << 16);
private final String name;
private final int value;
......@@ -239,7 +248,7 @@ public abstract class AsmTest {
/**
* Returns the int value of this version, as expected by ASM.
*
* @return one of the ASM4, ASM5 or ASM6 constants from the ASM Opcodes interface.
* @return one of the ASM4, ASM5, ASM6 or ASM7 constants from the ASM Opcodes interface.
*/
public int value() {
return value;
......@@ -248,7 +257,7 @@ public abstract class AsmTest {
/**
* Returns a human readable symbol corresponding to this version.
*
* @return one of "ASM4", "ASM5" or "ASM6".
* @return one of "ASM4", "ASM5", "ASM6" or "ASM7".
*/
@Override
public String toString() {
......@@ -273,10 +282,10 @@ public abstract class AsmTest {
* with <tt>@MethodSource("allClassesAndLatestApi")</tt> will be executed on all the precompiled
* classes, with the latest api.
*
* @return all the possible (precompiledClass, ASM6) pairs, for all the precompiled classes.
* @return all the possible (precompiledClass, ASM7) pairs, for all the precompiled classes.
*/
public static Stream<Arguments> allClassesAndLatestApi() {
return classesAndApis(Api.ASM6);
return classesAndApis(Api.ASM7);
}
private static Stream<Arguments> classesAndApis(final Api... apis) {
......
// 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 jdk11;
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Generates classes with all the JDK11 specific class file features.
*
* <p>TODO: remove this and use the JDK11 to compile equivalent classes, when it is released.
*
* @author Eric Bruneton
*/
public class DumpAllStructures implements Opcodes {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("AllStructures.class");
fileOutputStream.write(dumpAllStructures());
fileOutputStream.close();
fileOutputStream = new FileOutputStream("AllStructures$Nested.class");
fileOutputStream.write(dumpAllStructuresNested());
fileOutputStream.close();
}
private static byte[] dumpAllStructures() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classWriter.visit(
V11, ACC_PUBLIC + ACC_SUPER, "jdk11/AllStructures", null, "java/lang/Object", null);
classWriter.visitNestMember("jdk11/AllStructures$Nested");
addDefaultConstructor(classWriter);
classWriter.visitEnd();
return classWriter.toByteArray();
}
private static byte[] dumpAllStructuresNested() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classWriter.visit(
V11, ACC_PUBLIC + ACC_SUPER, "jdk11/AllStructures$Nested", null, "java/lang/Object", null);
classWriter.visitNestHost("jdk11/AllStructures");
addDefaultConstructor(classWriter);
classWriter.visitEnd();
return classWriter.toByteArray();
}
private static void addDefaultConstructor(final ClassWriter classWriter) {
MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
methodVisitor.visitCode();
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
methodVisitor.visitInsn(RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
}
}
......@@ -60,6 +60,9 @@ public class AsmTestTest extends AsmTest {
case ASM6:
assertEquals(majorVersion > /* V10 = */ 54, isMoreRecent);
break;
case ASM7:
assertEquals(majorVersion > /* V11 = */ 55, isMoreRecent);
break;
default:
fail("Unknown API value");
}
......@@ -69,9 +72,9 @@ public class AsmTestTest extends AsmTest {
@ParameterizedTest
@MethodSource(ALL_CLASSES_AND_LATEST_API)
public void testGetBytes(final PrecompiledClass classParameter, final Api apiParameter) {
assertEquals(Api.ASM6, apiParameter);
assertEquals(0x00060000, apiParameter.value());
assertEquals("ASM6", apiParameter.toString());
assertEquals(Api.ASM7, apiParameter);
assertEquals(0x01070000, apiParameter.value());
assertEquals("ASM7", apiParameter.toString());
byte[] classContent = classParameter.getBytes();
assertThatClass(classContent).contains(classParameter.getInternalName());
assertThatClass(classContent).isEqualTo(classContent);
......
......@@ -71,7 +71,7 @@ public class AnnotationNode extends AnnotationVisitor {
* Constructs a new {@link AnnotationNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param descriptor the class descriptor of the annotation class.
*/
public AnnotationNode(final int api, final String descriptor) {
......@@ -173,8 +173,8 @@ public class AnnotationNode extends AnnotationVisitor {
* checks that this node, and all its children recursively, do not contain elements that were
* introduced in more recent versions of the ASM API than the given version.
*
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or
* {@link Opcodes#ASM6}.
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5},
* {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public void check(final int api) {
// nothing to do
......
......@@ -121,6 +121,20 @@ public class ClassNode extends ClassVisitor {
/** The inner classes of this class. */
public List<InnerClassNode> innerClasses;
/**
* <b>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
* will break existing code using it</b>. The internal name of the nest host class of this class.
* May be <tt>null</tt>.
*/
public String nestHostClassExperimental;
/**
* <b>Experimental, use at your own risk. This field will be renamed when it becomes stable, this
* will break existing code using it</b>. The internal names of the nest members of this class.
* May be <tt>null</tt>.
*/
public List<String> nestMembersExperimental;
/** The fields of this class. */
public List<FieldNode> fields;
......@@ -144,7 +158,7 @@ public class ClassNode extends ClassVisitor {
* Constructs a new {@link ClassNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public ClassNode(final int api) {
super(api);
......@@ -186,6 +200,11 @@ public class ClassNode extends ClassVisitor {
return module;
}
@Override
public void visitNestHostExperimental(final String nestHost) {
this.nestHostClassExperimental = nestHost;
}
@Override
public void visitOuterClass(final String owner, final String name, final String descriptor) {
outerClass = owner;
......@@ -236,6 +255,14 @@ public class ClassNode extends ClassVisitor {
attrs.add(attribute);
}
@Override
public void visitNestMemberExperimental(final String nestMember) {
if (nestMembersExperimental == null) {
nestMembersExperimental = new ArrayList<String>();
}
nestMembersExperimental.add(nestMember);
}
@Override
public void visitInnerClass(
final String name, final String outerName, final String innerName, final int access) {
......@@ -281,10 +308,14 @@ public class ClassNode extends ClassVisitor {
* that this node, and all its children recursively, do not contain elements that were introduced
* in more recent versions of the ASM API than the given version.
*
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or
* {@link Opcodes#ASM6}.
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5},
* {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public void check(final int api) {
if (api < Opcodes.ASM7_EXPERIMENTAL
&& (nestHostClassExperimental != null || nestMembersExperimental != null)) {
throw new UnsupportedClassVersionException();
}
if (api < Opcodes.ASM6 && module != null) {
throw new UnsupportedClassVersionException();
}
......@@ -343,6 +374,10 @@ public class ClassNode extends ClassVisitor {
if (module != null) {
module.accept(classVisitor);
}
// Visit the nest host class.
if (nestHostClassExperimental != null) {
classVisitor.visitNestHostExperimental(nestHostClassExperimental);
}
// Visit the outer class.
if (outerClass != null) {
classVisitor.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
......@@ -382,6 +417,12 @@ public class ClassNode extends ClassVisitor {
classVisitor.visitAttribute(attrs.get(i));
}
}
// Visit the nest members.
if (nestMembersExperimental != null) {
for (int i = 0, n = nestMembersExperimental.size(); i < n; ++i) {
classVisitor.visitNestMemberExperimental(nestMembersExperimental.get(i));
}
}
// Visit the inner classes.
for (int i = 0, n = innerClasses.size(); i < n; ++i) {
innerClasses.get(i).accept(classVisitor);
......
......@@ -197,8 +197,8 @@ public class FieldNode extends FieldVisitor {
* that this node, and all its children recursively, do not contain elements that were introduced
* in more recent versions of the ASM API than the given version.
*
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or
* {@link Opcodes#ASM6}.
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5},
* {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
......
......@@ -92,7 +92,7 @@ public class LocalVariableAnnotationNode extends TypeAnnotationNode {
* Constructs a new {@link LocalVariableAnnotationNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
* @param start the fist instructions corresponding to the continuous ranges that make the scope
* of this local variable (inclusive).
......
......@@ -165,7 +165,7 @@ public class MethodNode extends MethodVisitor {
* Constructs an uninitialized {@link MethodNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public MethodNode(final int api) {
super(api);
......@@ -201,7 +201,7 @@ public class MethodNode extends MethodVisitor {
* Constructs a new {@link MethodNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if
* the method is synthetic and/or deprecated.
* @param name the method's name.
......@@ -603,8 +603,8 @@ public class MethodNode extends MethodVisitor {
* that this node, and all its children recursively, do not contain elements that were introduced
* in more recent versions of the ASM API than the given version.
*
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or
* {@link Opcodes#ASM6}.
* @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5},
* {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
*/
public void check(final int api) {
if (api == Opcodes.ASM4) {
......
......@@ -98,7 +98,8 @@ public class ModuleNode extends ModuleVisitor {
/**
* Constructs a {@link ModuleNode}.
*
* @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
* or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param name the fully qualified name (using dots) of the module.
* @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
* ACC_MANDATED}.
......
......@@ -69,7 +69,7 @@ public class TypeAnnotationNode extends AnnotationNode {
* Constructs a new {@link AnnotationNode}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
* @param typeRef a reference to the annotated type. See {@link org.objectweb.asm.TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
* static inner type within 'typeRef'. May be <tt>null</tt> if the annotation targets
......
......@@ -500,6 +500,12 @@ public class ClassNodeTest extends AsmTest implements Opcodes {
return null;
}
@Override
public void visitNestHostExperimental(final String nestHost) {}