8321248: ClassFile API ClassModel::verify is inconsistent with the rest of the API

Reviewed-by: jlahoda, mcimadamore
This commit is contained in:
Adam Sotona 2023-12-06 15:32:24 +00:00
parent 7fbfb3b74a
commit 0217b5ac8b
11 changed files with 62 additions and 50 deletions

View file

@ -43,6 +43,7 @@ import java.lang.classfile.attribute.CharacterRangeInfo;
import java.lang.classfile.attribute.LocalVariableInfo;
import java.lang.classfile.attribute.LocalVariableTypeInfo;
import java.lang.classfile.instruction.ExceptionCatch;
import java.util.List;
import static java.util.Objects.requireNonNull;
import jdk.internal.javac.PreviewFeature;
@ -481,6 +482,33 @@ public sealed interface ClassFile
*/
byte[] transform(ClassModel model, ClassEntry newClassName, ClassTransform transform);
/**
* Verify a classfile. Any verification errors found will be returned.
* @param model the class model to verify
* @return a list of verification errors, or an empty list if no errors are
* found
*/
List<VerifyError> verify(ClassModel model);
/**
* Verify a classfile. Any verification errors found will be returned.
* @param bytes the classfile bytes to verify
* @return a list of verification errors, or an empty list if no errors are
* found
*/
List<VerifyError> verify(byte[] bytes);
/**
* Verify a classfile. Any verification errors found will be returned.
* @param path the classfile path to verify
* @return a list of verification errors, or an empty list if no errors are
* found
* @throws java.io.IOException if an I/O error occurs
*/
default List<VerifyError> verify(Path path) throws IOException {
return verify(Files.readAllBytes(path));
}
/** 0xCAFEBABE */
int MAGIC_NUMBER = 0xCAFEBABE;

View file

@ -78,29 +78,4 @@ public sealed interface ClassModel
/** {@return whether this class is a module descriptor} */
boolean isModuleInfo();
/**
* Verify this classfile. Any verification errors found will be returned.
*
* @param debugOutput handler to receive debug information
* @return a list of verification errors, or an empty list if no errors are
* found
*/
default List<VerifyError> verify(Consumer<String> debugOutput) {
return VerifierImpl.verify(this, debugOutput);
}
/**
* Verify this classfile. Any verification errors found will be returned.
*
* @param debugOutput handler to receive debug information
* @param classHierarchyResolver class hierarchy resolver to provide
* additional information about the class hierarchy
* @return a list of verification errors, or an empty list if no errors are
* found
*/
default List<VerifyError> verify(ClassHierarchyResolver classHierarchyResolver,
Consumer<String> debugOutput) {
return VerifierImpl.verify(this, classHierarchyResolver, debugOutput);
}
}

View file

@ -277,8 +277,8 @@
* constantPoolBuilder.utf8Entry("mypackage.MyClass"));
* }
* <p>
* More complex verification of a classfile can be achieved by explicit invocation
* of {@link java.lang.classfile.ClassModel#verify}.
* More complex verification of a classfile can be achieved by invocation of
* {@link java.lang.classfile.ClassFile#verify}.
*
* <h2>Transforming classfiles</h2>
* ClassFile Processing APIs are most frequently used to combine reading and

View file

@ -39,6 +39,7 @@ import java.lang.classfile.ClassTransform;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.verifier.VerifierImpl;
public record ClassFileImpl(StackMapsOption stackMapsOption,
DebugElementsOption debugElementsOption,
@ -128,6 +129,21 @@ public record ClassFileImpl(StackMapsOption stackMapsOption,
}
});
}
@Override
public List<VerifyError> verify(ClassModel model) {
return VerifierImpl.verify(model, classHierarchyResolverOption().classHierarchyResolver(), null);
}
@Override
public List<VerifyError> verify(byte[] bytes) {
try {
return verify(parse(bytes));
} catch (IllegalArgumentException parsingError) {
return List.of(new VerifyError(parsingError.getMessage()));
}
}
public record AttributeMapperOptionImpl(Function<Utf8Entry, AttributeMapper<?>> attributeMapper)
implements AttributeMapperOption {
}

View file

@ -212,7 +212,7 @@ public class BindingSpecializer {
}
if (PERFORM_VERIFICATION) {
List<VerifyError> errors = ClassFile.of().parse(bytes).verify(null);
List<VerifyError> errors = ClassFile.of().verify(bytes);
if (!errors.isEmpty()) {
errors.forEach(System.err::println);
throw new IllegalStateException("Verification error(s)");