Commit 8486f103 authored by Eric Bruneton's avatar Eric Bruneton

Merge branch 'restrict-preview-check-bypass'

parents db802e6e 1b694a89
Pipeline #6814 passed with stage
in 11 minutes and 14 seconds
...@@ -83,9 +83,7 @@ public class AnnotationRemapper extends AnnotationVisitor { ...@@ -83,9 +83,7 @@ public class AnnotationRemapper extends AnnotationVisitor {
if (annotationVisitor == null) { if (annotationVisitor == null) {
return null; return null;
} else { } else {
return annotationVisitor == av return annotationVisitor == av ? this : createAnnotationRemapper(annotationVisitor);
? this
: new AnnotationRemapper(api, annotationVisitor, remapper);
} }
} }
...@@ -95,9 +93,18 @@ public class AnnotationRemapper extends AnnotationVisitor { ...@@ -95,9 +93,18 @@ public class AnnotationRemapper extends AnnotationVisitor {
if (annotationVisitor == null) { if (annotationVisitor == null) {
return null; return null;
} else { } else {
return annotationVisitor == av return annotationVisitor == av ? this : createAnnotationRemapper(annotationVisitor);
? this
: new AnnotationRemapper(api, annotationVisitor, remapper);
} }
} }
/**
* Constructs a new remapper for annotations. The default implementation of this method returns a
* new {@link AnnotationRemapper}.
*
* @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
* @return the newly created remapper.
*/
protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapper(api, annotationVisitor, remapper);
}
} }
...@@ -72,9 +72,7 @@ public class FieldRemapper extends FieldVisitor { ...@@ -72,9 +72,7 @@ public class FieldRemapper extends FieldVisitor {
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
AnnotationVisitor annotationVisitor = AnnotationVisitor annotationVisitor =
super.visitAnnotation(remapper.mapDesc(descriptor), visible); super.visitAnnotation(remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor);
? null
: new AnnotationRemapper(api, annotationVisitor, remapper);
} }
@Override @Override
...@@ -82,8 +80,17 @@ public class FieldRemapper extends FieldVisitor { ...@@ -82,8 +80,17 @@ public class FieldRemapper extends FieldVisitor {
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
AnnotationVisitor annotationVisitor = AnnotationVisitor annotationVisitor =
super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor);
? null }
: new AnnotationRemapper(api, annotationVisitor, remapper);
/**
* Constructs a new remapper for annotations. The default implementation of this method returns a
* new {@link AnnotationRemapper}.
*
* @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
* @return the newly created remapper.
*/
protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapper(api, annotationVisitor, remapper);
} }
} }
...@@ -76,7 +76,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -76,7 +76,7 @@ public class MethodRemapper extends MethodVisitor {
AnnotationVisitor annotationVisitor = super.visitAnnotationDefault(); AnnotationVisitor annotationVisitor = super.visitAnnotationDefault();
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -85,7 +85,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -85,7 +85,7 @@ public class MethodRemapper extends MethodVisitor {
super.visitAnnotation(remapper.mapDesc(descriptor), visible); super.visitAnnotation(remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -95,7 +95,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -95,7 +95,7 @@ public class MethodRemapper extends MethodVisitor {
super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); super.visitTypeAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -105,7 +105,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -105,7 +105,7 @@ public class MethodRemapper extends MethodVisitor {
super.visitParameterAnnotation(parameter, remapper.mapDesc(descriptor), visible); super.visitParameterAnnotation(parameter, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -209,7 +209,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -209,7 +209,7 @@ public class MethodRemapper extends MethodVisitor {
super.visitInsnAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); super.visitInsnAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -225,7 +225,7 @@ public class MethodRemapper extends MethodVisitor { ...@@ -225,7 +225,7 @@ public class MethodRemapper extends MethodVisitor {
super.visitTryCatchAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible); super.visitTryCatchAnnotation(typeRef, typePath, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
} }
@Override @Override
...@@ -259,6 +259,17 @@ public class MethodRemapper extends MethodVisitor { ...@@ -259,6 +259,17 @@ public class MethodRemapper extends MethodVisitor {
typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible); typeRef, typePath, start, end, index, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null
? annotationVisitor ? annotationVisitor
: new AnnotationRemapper(api, annotationVisitor, remapper); : createAnnotationRemapper(annotationVisitor);
}
/**
* Constructs a new remapper for annotations. The default implementation of this method returns a
* new {@link AnnotationRemapper}.
*
* @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
* @return the newly created remapper.
*/
protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapper(api, annotationVisitor, remapper);
} }
} }
...@@ -53,8 +53,7 @@ public class RecordComponentRemapper extends RecordComponentVisitor { ...@@ -53,8 +53,7 @@ public class RecordComponentRemapper extends RecordComponentVisitor {
*/ */
public RecordComponentRemapper( public RecordComponentRemapper(
final RecordComponentVisitor recordComponentVisitor, final Remapper remapper) { final RecordComponentVisitor recordComponentVisitor, final Remapper remapper) {
// TODO: add 'latest api =' comment when no longer experimental. this(/* latest api = */ Opcodes.ASM7, recordComponentVisitor, remapper);
this(Opcodes.ASM8_EXPERIMENTAL, recordComponentVisitor, remapper);
} }
/** /**
...@@ -76,9 +75,7 @@ public class RecordComponentRemapper extends RecordComponentVisitor { ...@@ -76,9 +75,7 @@ public class RecordComponentRemapper extends RecordComponentVisitor {
final String descriptor, final boolean visible) { final String descriptor, final boolean visible) {
AnnotationVisitor annotationVisitor = AnnotationVisitor annotationVisitor =
super.visitAnnotationExperimental(remapper.mapDesc(descriptor), visible); super.visitAnnotationExperimental(remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor);
? null
: new AnnotationRemapper(api, annotationVisitor, remapper);
} }
@Override @Override
...@@ -87,8 +84,17 @@ public class RecordComponentRemapper extends RecordComponentVisitor { ...@@ -87,8 +84,17 @@ public class RecordComponentRemapper extends RecordComponentVisitor {
AnnotationVisitor annotationVisitor = AnnotationVisitor annotationVisitor =
super.visitTypeAnnotationExperimental( super.visitTypeAnnotationExperimental(
typeRef, typePath, remapper.mapDesc(descriptor), visible); typeRef, typePath, remapper.mapDesc(descriptor), visible);
return annotationVisitor == null return annotationVisitor == null ? null : createAnnotationRemapper(annotationVisitor);
? null }
: new AnnotationRemapper(api, annotationVisitor, remapper);
/**
* Constructs a new remapper for annotations. The default implementation of this method returns a
* new {@link AnnotationRemapper}.
*
* @param annotationVisitor the AnnotationVisitor the remapper must delegate to.
* @return the newly created remapper.
*/
protected AnnotationVisitor createAnnotationRemapper(final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapper(api, annotationVisitor, remapper);
} }
} }
...@@ -38,12 +38,17 @@ import org.junit.jupiter.api.Test; ...@@ -38,12 +38,17 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.ConstantDynamic; import org.objectweb.asm.ConstantDynamic;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Handle; import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.ModuleVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.RecordComponentVisitor;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.test.AsmTest; import org.objectweb.asm.test.AsmTest;
import org.objectweb.asm.test.ClassFile; import org.objectweb.asm.test.ClassFile;
...@@ -149,7 +154,7 @@ public class ClassRemapperTest extends AsmTest { ...@@ -149,7 +154,7 @@ public class ClassRemapperTest extends AsmTest {
ClassNode classNode = new ClassNode(); ClassNode classNode = new ClassNode();
ClassRemapper classRemapper = ClassRemapper classRemapper =
new ClassRemapper( new ClassRemapper(
/* latest */ Opcodes.ASM8_EXPERIMENTAL, Opcodes.ASM7,
classNode, classNode,
new Remapper() { new Remapper() {
@Override @Override
...@@ -194,7 +199,7 @@ public class ClassRemapperTest extends AsmTest { ...@@ -194,7 +199,7 @@ public class ClassRemapperTest extends AsmTest {
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName()); UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName());
ClassRemapper classRemapper = ClassRemapper classRemapper =
new ClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper); newClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper);
Executable accept = () -> classReader.accept(classRemapper, 0); Executable accept = () -> classReader.accept(classRemapper, 0);
...@@ -225,7 +230,7 @@ public class ClassRemapperTest extends AsmTest { ...@@ -225,7 +230,7 @@ public class ClassRemapperTest extends AsmTest {
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName()); UpperCaseRemapper upperCaseRemapper = new UpperCaseRemapper(classParameter.getInternalName());
ClassRemapper classRemapper = ClassRemapper classRemapper =
new ClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper); newClassRemapper(apiParameter.value(), classWriter, upperCaseRemapper);
Executable accept = () -> classNode.accept(classRemapper); Executable accept = () -> classNode.accept(classRemapper);
...@@ -256,6 +261,81 @@ public class ClassRemapperTest extends AsmTest { ...@@ -256,6 +261,81 @@ public class ClassRemapperTest extends AsmTest {
checkMethodAdapter.visitFieldInsn(Opcodes.GETFIELD, internalName, "name", "I"); checkMethodAdapter.visitFieldInsn(Opcodes.GETFIELD, internalName, "name", "I");
} }
ClassRemapper newClassRemapper(
final int api, final ClassVisitor classVisitor, final Remapper remapper) {
// TODO: remove this test and the associated classes when no longer experimental.
if (api == Opcodes.ASM8_EXPERIMENTAL) {
return new ClassRemapperExperimental(classVisitor, remapper);
}
return new ClassRemapper(api, classVisitor, remapper);
}
static class ClassRemapperExperimental extends ClassRemapper {
ClassRemapperExperimental(final ClassVisitor classVisitor, final Remapper remapper) {
super(Opcodes.ASM8_EXPERIMENTAL, classVisitor, remapper);
}
@Override
protected RecordComponentVisitor createRecordComponentRemapper(
final RecordComponentVisitor recordComponentVisitor) {
return new RecordComponentRemapper(api, recordComponentVisitor, remapper) {
@Override
protected AnnotationVisitor createAnnotationRemapper(
final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapperExperimental(annotationVisitor, remapper);
}
};
}
@Override
protected FieldVisitor createFieldRemapper(final FieldVisitor fieldVisitor) {
return new FieldRemapper(api, fieldVisitor, remapper) {
@Override
protected AnnotationVisitor createAnnotationRemapper(
final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapperExperimental(annotationVisitor, remapper);
}
};
}
@Override
protected MethodVisitor createMethodRemapper(final MethodVisitor methodVisitor) {
return new MethodRemapper(api, methodVisitor, remapper) {
@Override
protected AnnotationVisitor createAnnotationRemapper(
final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapperExperimental(annotationVisitor, remapper);
}
};
}
@Override
protected AnnotationVisitor createAnnotationRemapper(
final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapperExperimental(annotationVisitor, remapper);
}
@Override
protected ModuleVisitor createModuleRemapper(final ModuleVisitor moduleVisitor) {
return new ModuleRemapper(api, moduleVisitor, remapper) {};
}
}
static class AnnotationRemapperExperimental extends AnnotationRemapper {
AnnotationRemapperExperimental(
final AnnotationVisitor annotationVisitor, final Remapper remapper) {
super(Opcodes.ASM8_EXPERIMENTAL, annotationVisitor, remapper);
}
@Override
protected AnnotationVisitor createAnnotationRemapper(
final AnnotationVisitor annotationVisitor) {
return new AnnotationRemapperExperimental(annotationVisitor, remapper);
}
}
static class UpperCaseRemapper extends Remapper { static class UpperCaseRemapper extends Remapper {
private static final Locale LOCALE = Locale.ENGLISH; private static final Locale LOCALE = Locale.ENGLISH;
......
...@@ -852,7 +852,7 @@ public class GeneratorAdapterTest { ...@@ -852,7 +852,7 @@ public class GeneratorAdapterTest {
new TraceMethodVisitor(textifier), new TraceMethodVisitor(textifier),
access, access,
name, name,
descriptor); descriptor) {};
} }
public String push(final boolean value) { public String push(final boolean value) {
......
...@@ -1534,7 +1534,7 @@ public class JsrInlinerAdapterTest extends AsmTest { ...@@ -1534,7 +1534,7 @@ public class JsrInlinerAdapterTest extends AsmTest {
MethodVisitor methodVisitor = MethodVisitor methodVisitor =
super.visitMethod(access, name, descriptor, signature, exceptions); super.visitMethod(access, name, descriptor, signature, exceptions);
return new JSRInlinerAdapter( return new JSRInlinerAdapter(
api, methodVisitor, access, name, descriptor, signature, exceptions); api, methodVisitor, access, name, descriptor, signature, exceptions) {};
} }
} }
} }
...@@ -240,7 +240,7 @@ public class LocalVariablesSorterTest extends AsmTest { ...@@ -240,7 +240,7 @@ public class LocalVariablesSorterTest extends AsmTest {
final String[] exceptions) { final String[] exceptions) {
MethodVisitor methodVisitor = MethodVisitor methodVisitor =
super.visitMethod(access, name, descriptor, signature, exceptions); super.visitMethod(access, name, descriptor, signature, exceptions);
return new LocalVariablesSorter(api, access, descriptor, methodVisitor); return new LocalVariablesSorter(api, access, descriptor, methodVisitor) {};
} }
} }
} }
...@@ -123,7 +123,7 @@ public class SerialVersionUidAdderTest extends AsmTest { ...@@ -123,7 +123,7 @@ public class SerialVersionUidAdderTest extends AsmTest {
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
classReader.accept( classReader.accept(
new SerialVersionUIDAdder(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classWriter), 0); new SerialVersionUIDAdder(/* latest */ Opcodes.ASM8_EXPERIMENTAL, classWriter) {}, 0);
if ((classReader.getAccess() & Opcodes.ACC_ENUM) == 0) { if ((classReader.getAccess() & Opcodes.ACC_ENUM) == 0) {
assertTrue(new ClassFile(classWriter.toByteArray()).toString().contains("serialVersionUID")); assertTrue(new ClassFile(classWriter.toByteArray()).toString().contains("serialVersionUID"));
......
...@@ -83,7 +83,7 @@ public class ClassNodeTest extends AsmTest { ...@@ -83,7 +83,7 @@ public class ClassNodeTest extends AsmTest {
@ParameterizedTest @ParameterizedTest
@MethodSource(ALL_CLASSES_AND_ALL_APIS) @MethodSource(ALL_CLASSES_AND_ALL_APIS)
public void testCheck(final PrecompiledClass classParameter, final Api apiParameter) { public void testCheck(final PrecompiledClass classParameter, final Api apiParameter) {
ClassNode classNode = new ClassNode(apiParameter.value()); ClassNode classNode = new ClassNode(apiParameter.value()) {};
new ClassReader(classParameter.getBytes()).accept(classNode, attributes(), 0); new ClassReader(classParameter.getBytes()).accept(classNode, attributes(), 0);
Executable check = () -> classNode.check(apiParameter.value()); Executable check = () -> classNode.check(apiParameter.value());
...@@ -101,7 +101,7 @@ public class ClassNodeTest extends AsmTest { ...@@ -101,7 +101,7 @@ public class ClassNodeTest extends AsmTest {
public void testVisitAndAccept(final PrecompiledClass classParameter, final Api apiParameter) { public void testVisitAndAccept(final PrecompiledClass classParameter, final Api apiParameter) {
byte[] classFile = classParameter.getBytes(); byte[] classFile = classParameter.getBytes();
ClassReader classReader = new ClassReader(classFile); ClassReader classReader = new ClassReader(classFile);
ClassNode classNode = new ClassNode(apiParameter.value()); ClassNode classNode = new ClassNode(apiParameter.value()) {};
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
classReader.accept(classNode, attributes(), 0); classReader.accept(classNode, attributes(), 0);
...@@ -120,7 +120,7 @@ public class ClassNodeTest extends AsmTest { ...@@ -120,7 +120,7 @@ public class ClassNodeTest extends AsmTest {
final PrecompiledClass classParameter, final Api apiParameter) { final PrecompiledClass classParameter, final Api apiParameter) {
byte[] classFile = classParameter.getBytes(); byte[] classFile = classParameter.getBytes();
ClassReader classReader = new ClassReader(classFile); ClassReader classReader = new ClassReader(classFile);
ClassNode classNode = new ClassNode(apiParameter.value()); ClassNode classNode = new ClassNode(apiParameter.value()) {};
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
classReader.accept(classNode, attributes(), 0); classReader.accept(classNode, attributes(), 0);
...@@ -139,7 +139,7 @@ public class ClassNodeTest extends AsmTest { ...@@ -139,7 +139,7 @@ public class ClassNodeTest extends AsmTest {
final PrecompiledClass classParameter, final Api apiParameter) { final PrecompiledClass classParameter, final Api apiParameter) {
byte[] classFile = classParameter.getBytes(); byte[] classFile = classParameter.getBytes();
ClassReader classReader = new ClassReader(classFile); ClassReader classReader = new ClassReader(classFile);
ClassNode classNode = new ClassNode(apiParameter.value()); ClassNode classNode = new ClassNode(apiParameter.value()) {};
ClassWriter classWriter = new ClassWriter(0); ClassWriter classWriter = new ClassWriter(0);
classReader.accept(classNode, attributes(), 0); classReader.accept(classNode, attributes(), 0);
......
...@@ -57,7 +57,7 @@ public class ModuleNodeTest extends AsmTest { ...@@ -57,7 +57,7 @@ public class ModuleNodeTest extends AsmTest {
null, null,
null, null,
null, null,
null); null) {};
assertEquals("module1", moduleNode1.name); assertEquals("module1", moduleNode1.name);
assertEquals(123, moduleNode1.access); assertEquals(123, moduleNode1.access);
......
...@@ -26,7 +26,9 @@ public final class SignaturesProviders { ...@@ -26,7 +26,9 @@ public final class SignaturesProviders {
static { static {
AsmTest.allClassesAndLatestApi() AsmTest.allClassesAndLatestApi()
.forEach(argument -> collectSignatures((PrecompiledClass) argument.get()[0])); .map(argument -> (PrecompiledClass) argument.get()[0])
.filter(precompiledClass -> !precompiledClass.isMoreRecentThan(AsmTest.Api.ASM7))
.forEach(precompiledClass -> collectSignatures(precompiledClass));
assertFalse(CLASS_SIGNATURES.isEmpty()); assertFalse(CLASS_SIGNATURES.isEmpty());
assertFalse(FIELD_SIGNATURES.isEmpty()); assertFalse(FIELD_SIGNATURES.isEmpty());
assertFalse(METHOD_SIGNATURES.isEmpty()); assertFalse(METHOD_SIGNATURES.isEmpty());
...@@ -37,7 +39,7 @@ public final class SignaturesProviders { ...@@ -37,7 +39,7 @@ public final class SignaturesProviders {
private static void collectSignatures(final PrecompiledClass classParameter) { private static void collectSignatures(final PrecompiledClass classParameter) {
ClassReader classReader = new ClassReader(classParameter.getBytes()); ClassReader classReader = new ClassReader(classParameter.getBytes());
classReader.accept( classReader.accept(
new ClassVisitor(/* latest */ Opcodes.ASM8_EXPERIMENTAL) { new ClassVisitor(Opcodes.ASM7) {
@Override @Override
public void visit( public void visit(
final int version, final int version,
......
...@@ -30,6 +30,7 @@ package org.objectweb.asm; ...@@ -30,6 +30,7 @@ package org.objectweb.asm;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.regex.Pattern;
/** /**
* Defines additional JVM opcodes, access flags and constants which are not part of the ASM public * Defines additional JVM opcodes, access flags and constants which are not part of the ASM public
...@@ -183,20 +184,34 @@ final class Constants implements Opcodes { ...@@ -183,20 +184,34 @@ final class Constants implements Opcodes {
static void checkAsm8Experimental(final Object caller) { static void checkAsm8Experimental(final Object caller) {
Class<?> callerClass = caller.getClass(); Class<?> callerClass = caller.getClass();
if (callerClass.getName().startsWith("org.objectweb.asm.")) { String internalName = callerClass.getName().replace('.', '/');
return; if (!isWhitelisted(internalName)) {
checkIsPreview(callerClass.getClassLoader().getResourceAsStream(internalName + ".class"));
} }
String callerClassResource = callerClass.getName().replace('.', '/') + ".class"; }
InputStream inputStream = callerClass.getClassLoader().getResourceAsStream(callerClassResource);
if (inputStream == null) { static boolean isWhitelisted(final String internalName) {
if (!internalName.startsWith("org/objectweb/asm/")) {
return false;
}
String member = "(Annotation|Class|Field|Method|Module|RecordComponent|Signature)";
return internalName.contains("Test$")
|| Pattern.matches(
"org/objectweb/asm/util/Trace" + member + "Visitor(\\$.*)?", internalName)
|| Pattern.matches(
"org/objectweb/asm/util/Check" + member + "Adapter(\\$.*)?", internalName);
}
static void checkIsPreview(final InputStream classInputStream) {
if (classInputStream == null) {
throw new IllegalStateException("Bytecode not available, can't check class version"); throw new IllegalStateException("Bytecode not available, can't check class version");
} }
int minorVersion; int minorVersion;
try (DataInputStream callerClassStream = new DataInputStream(inputStream); ) { try (DataInputStream callerClassStream = new DataInputStream(classInputStream); ) {
callerClassStream.readInt(); callerClassStream.readInt();
minorVersion = callerClassStream.readUnsignedShort(); minorVersion = callerClassStream.readUnsignedShort();
} catch (IOException ioe) { } catch (IOException ioe) {
throw new IllegalStateException("i/O error, can't check class version", ioe); throw new IllegalStateException("I/O error, can't check class version", ioe);
} }
if (minorVersion != 0xFFFF) { if (minorVersion != 0xFFFF) {
throw new IllegalStateException( throw new IllegalStateException(
......
...@@ -103,8 +103,7 @@ final class RecordComponentWriter extends RecordComponentVisitor { ...@@ -103,8 +103,7 @@ final class RecordComponentWriter extends RecordComponentVisitor {
final String name, final String name,
final String descriptor, final String descriptor,
final String signature) { final String signature) {
// TODO: add 'latest api =' comment when no longer experimental. super(/* latest api = */ Opcodes.ASM7);
super(Opcodes.ASM8_EXPERIMENTAL);
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.accessFlags = accessFlags; this.accessFlags = accessFlags;
this.nameIndex = symbolTable.addConstantUtf8(name); this.nameIndex = symbolTable.addConstantUtf8(name);
......
...@@ -27,14 +27,21 @@ ...@@ -27,14 +27,21 @@
// THE POSSIBILITY OF SUCH DAMAGE. // THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm; package org.objectweb.asm;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
/** /**
* Unit tests for {@link Constants}. * Unit tests for {@link Constants}.
...@@ -161,6 +168,52 @@ public class ConstantsTest { ...@@ -161,6 +168,52 @@ public class ConstantsTest {
} }
} }
@Test
public void testIsWhitelisted() {
assertFalse(Constants.isWhitelisted("org/jacoco/core/internal/flow/ClassProbesVisitor"));
assertFalse(Constants.isWhitelisted("org/objectweb/asm/ClassWriter"));
assertFalse(Constants.isWhitelisted("org/objectweb/asm/util/CheckClassVisitor"));
assertFalse(Constants.isWhitelisted("org/objectweb/asm/ClassWriterTest"));
assertTrue(Constants.isWhitelisted("org/objectweb/asm/ClassWriterTest$DeadCodeInserter"));
assertTrue(Constants.isWhitelisted("org/objectweb/asm/util/TraceClassVisitor"));
assertTrue(Constants.isWhitelisted("org/objectweb/asm/util/CheckClassAdapter"));