8312491: Update Classfile API snippets and examples
Reviewed-by: jlahoda
This commit is contained in:
parent
69c9ec92d0
commit
744b3970f9
@ -72,6 +72,7 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* corresponding model type. Additionally, all attributes are accessible
|
||||
* directly from the corresponding model type through {@link
|
||||
* AttributedElement#findAttribute(AttributeMapper)}.
|
||||
* @param <A> the attribute type
|
||||
*/
|
||||
public sealed interface Attribute<A extends Attribute<A>>
|
||||
extends WritableElement<A>
|
||||
|
@ -33,6 +33,7 @@ package jdk.internal.classfile;
|
||||
* attributes, clients can define their own {@linkplain AttributeMapper}.
|
||||
* Classes that model nonstandard attributes should extend {@link
|
||||
* CustomAttribute}.
|
||||
* @param <A> the attribute type
|
||||
*/
|
||||
public interface AttributeMapper<A> {
|
||||
|
||||
|
@ -91,41 +91,113 @@ import jdk.internal.classfile.impl.StackMapDecoder;
|
||||
* @see AttributeMapper
|
||||
*/
|
||||
public class Attributes {
|
||||
|
||||
/** AnnotationDefault */
|
||||
public static final String NAME_ANNOTATION_DEFAULT = "AnnotationDefault";
|
||||
|
||||
/** BootstrapMethods */
|
||||
public static final String NAME_BOOTSTRAP_METHODS = "BootstrapMethods";
|
||||
|
||||
/** CharacterRangeTable */
|
||||
public static final String NAME_CHARACTER_RANGE_TABLE = "CharacterRangeTable";
|
||||
|
||||
/** Code */
|
||||
public static final String NAME_CODE = "Code";
|
||||
|
||||
/** CompilationID */
|
||||
public static final String NAME_COMPILATION_ID = "CompilationID";
|
||||
|
||||
/** ConstantValue */
|
||||
public static final String NAME_CONSTANT_VALUE = "ConstantValue";
|
||||
|
||||
/** Deprecated */
|
||||
public static final String NAME_DEPRECATED = "Deprecated";
|
||||
|
||||
/** EnclosingMethod */
|
||||
public static final String NAME_ENCLOSING_METHOD = "EnclosingMethod";
|
||||
|
||||
/** Exceptions */
|
||||
public static final String NAME_EXCEPTIONS = "Exceptions";
|
||||
|
||||
/** InnerClasses */
|
||||
public static final String NAME_INNER_CLASSES = "InnerClasses";
|
||||
|
||||
/** LineNumberTable */
|
||||
public static final String NAME_LINE_NUMBER_TABLE = "LineNumberTable";
|
||||
|
||||
/** LocalVariableTable */
|
||||
public static final String NAME_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
|
||||
|
||||
/** LocalVariableTypeTable */
|
||||
public static final String NAME_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
|
||||
|
||||
/** MethodParameters */
|
||||
public static final String NAME_METHOD_PARAMETERS = "MethodParameters";
|
||||
|
||||
/** Module */
|
||||
public static final String NAME_MODULE = "Module";
|
||||
|
||||
/** ModuleHashes */
|
||||
public static final String NAME_MODULE_HASHES = "ModuleHashes";
|
||||
|
||||
/** ModuleMainClass */
|
||||
public static final String NAME_MODULE_MAIN_CLASS = "ModuleMainClass";
|
||||
|
||||
/** ModulePackages */
|
||||
public static final String NAME_MODULE_PACKAGES = "ModulePackages";
|
||||
|
||||
/** ModuleResolution */
|
||||
public static final String NAME_MODULE_RESOLUTION = "ModuleResolution";
|
||||
|
||||
/** ModuleTarget */
|
||||
public static final String NAME_MODULE_TARGET = "ModuleTarget";
|
||||
|
||||
/** NestHost */
|
||||
public static final String NAME_NEST_HOST = "NestHost";
|
||||
|
||||
/** NestMembers */
|
||||
public static final String NAME_NEST_MEMBERS = "NestMembers";
|
||||
|
||||
/** PermittedSubclasses */
|
||||
public static final String NAME_PERMITTED_SUBCLASSES = "PermittedSubclasses";
|
||||
|
||||
/** Record */
|
||||
public static final String NAME_RECORD = "Record";
|
||||
|
||||
/** RuntimeInvisibleAnnotations */
|
||||
public static final String NAME_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
|
||||
|
||||
/** RuntimeInvisibleTypeAnnotations */
|
||||
public static final String NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
|
||||
|
||||
/** */
|
||||
public static final String NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations";
|
||||
|
||||
/** RuntimeVisibleAnnotations */
|
||||
public static final String NAME_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
|
||||
|
||||
/** RuntimeVisibleParameterAnnotations */
|
||||
public static final String NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
|
||||
|
||||
/** RuntimeVisibleTypeAnnotations */
|
||||
public static final String NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
|
||||
|
||||
/** Signature */
|
||||
public static final String NAME_SIGNATURE = "Signature";
|
||||
|
||||
/** SourceDebugExtension */
|
||||
public static final String NAME_SOURCE_DEBUG_EXTENSION = "SourceDebugExtension";
|
||||
|
||||
/** SourceFile */
|
||||
public static final String NAME_SOURCE_FILE = "SourceFile";
|
||||
|
||||
/** SourceID */
|
||||
public static final String NAME_SOURCE_ID = "SourceID";
|
||||
|
||||
/** StackMapTable */
|
||||
public static final String NAME_STACK_MAP_TABLE = "StackMapTable";
|
||||
|
||||
/** Synthetic */
|
||||
public static final String NAME_SYNTHETIC = "Synthetic";
|
||||
|
||||
private Attributes() {
|
||||
@ -712,7 +784,7 @@ public class Attributes {
|
||||
|
||||
/** Attribute mapper for the {@code Synthetic} attribute */
|
||||
public static final AttributeMapper<SyntheticAttribute>
|
||||
SYNTHETIC = new AbstractAttributeMapper<>(NAME_SYNTHETIC) {
|
||||
SYNTHETIC = new AbstractAttributeMapper<>(NAME_SYNTHETIC, true) {
|
||||
@Override
|
||||
public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
|
||||
return new BoundAttribute.BoundSyntheticAttribute(cf, this, p);
|
||||
|
@ -48,8 +48,8 @@ import static java.lang.constant.ConstantDescs.CD_Object;
|
||||
public interface ClassHierarchyResolver {
|
||||
|
||||
/**
|
||||
* Returns a default instance of {@linkplain ClassHierarchyResolver} that
|
||||
* gets {@link ClassHierarchyInfo} from system class loader with reflection.
|
||||
* {@return the default instance of {@linkplain ClassHierarchyResolver} that
|
||||
* gets {@link ClassHierarchyInfo} from system class loader with reflection}
|
||||
*/
|
||||
static ClassHierarchyResolver defaultResolver() {
|
||||
return ClassHierarchyImpl.DEFAULT_RESOLVER;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,8 @@ import jdk.internal.classfile.constantpool.ConstantPoolBuilder;
|
||||
* abstractly (by passing a {@link ClassfileElement} to {@link #with(ClassfileElement)}
|
||||
* or concretely by calling the various {@code withXxx} methods.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @param <B> the builder type
|
||||
* @see ClassfileTransform
|
||||
*/
|
||||
public sealed interface ClassfileBuilder<E extends ClassfileElement, B extends ClassfileBuilder<E, B>>
|
||||
|
@ -68,6 +68,9 @@ import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
|
||||
* <p>
|
||||
* Complex class instrumentation sample chaining multiple transformations:
|
||||
* {@snippet lang="java" class="PackageSnippets" region="classInstrumentation"}
|
||||
* @param <C> the transform type
|
||||
* @param <E> the element type
|
||||
* @param <B> the builder type
|
||||
*/
|
||||
public sealed interface ClassfileTransform<
|
||||
C extends ClassfileTransform<C, E, B>,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,7 @@ import java.util.stream.StreamSupport;
|
||||
* option to treat the element as a single entity (e.g., an entire method)
|
||||
* or to traverse the contents of that element with the methods in this class
|
||||
* (e.g., {@link #elements()}, {@link #forEachElement(Consumer)}, etc.)
|
||||
* @param <E> the element type
|
||||
*/
|
||||
public sealed interface CompoundElement<E extends ClassfileElement>
|
||||
extends ClassfileElement, Iterable<E>
|
||||
|
@ -31,6 +31,7 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* this class to provide an implementation class for non-standard attributes,
|
||||
* and provide an {@link AttributeMapper} to mediate between the classfile
|
||||
* format and the {@linkplain CustomAttribute} representation.
|
||||
* @param <T> the custom attribute type
|
||||
*/
|
||||
@SuppressWarnings("exports")
|
||||
public abstract non-sealed class CustomAttribute<T extends CustomAttribute<T>>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -176,7 +176,26 @@ public sealed interface Signature {
|
||||
* an upper bound, or a lower bound
|
||||
*/
|
||||
public enum WildcardIndicator {
|
||||
DEFAULT, UNBOUNDED, EXTENDS, SUPER;
|
||||
|
||||
/**
|
||||
* default bound wildcard (empty)
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
/**
|
||||
* unbounded indicator {@code *}
|
||||
*/
|
||||
UNBOUNDED,
|
||||
|
||||
/**
|
||||
* upper-bounded indicator {@code +}
|
||||
*/
|
||||
EXTENDS,
|
||||
|
||||
/**
|
||||
* lower-bounded indicator {@code -}
|
||||
*/
|
||||
SUPER;
|
||||
}
|
||||
|
||||
/** {@return the wildcard indicator} */
|
||||
|
@ -59,7 +59,7 @@ import static jdk.internal.classfile.Classfile.TAT_THROWS;
|
||||
import jdk.internal.classfile.impl.TemporaryConstantPool;
|
||||
|
||||
/**
|
||||
* Models an annotation on a type use.
|
||||
* Models an annotation on a type use, as defined in {@jvms 4.7.19} and {@jvms 4.7.20}.
|
||||
*
|
||||
* @see RuntimeVisibleTypeAnnotationsAttribute
|
||||
* @see RuntimeInvisibleTypeAnnotationsAttribute
|
||||
@ -69,7 +69,7 @@ public sealed interface TypeAnnotation
|
||||
permits UnboundAttribute.UnboundTypeAnnotation {
|
||||
|
||||
/**
|
||||
* The kind of target on which the annotation appears.
|
||||
* The kind of target on which the annotation appears, as defined in {@jvms 4.7.20.1}.
|
||||
*/
|
||||
public enum TargetType {
|
||||
/** For annotations on a class type parameter declaration. */
|
||||
@ -146,10 +146,16 @@ public sealed interface TypeAnnotation
|
||||
this.sizeIfFixed = sizeIfFixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the target type value}
|
||||
*/
|
||||
public int targetTypeValue() {
|
||||
return targetTypeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the size of the target type if fixed or -1 if variable}
|
||||
*/
|
||||
public int sizeIfFixed() {
|
||||
return sizeIfFixed;
|
||||
}
|
||||
@ -225,120 +231,269 @@ public sealed interface TypeAnnotation
|
||||
*/
|
||||
sealed interface TargetInfo {
|
||||
|
||||
/**
|
||||
* {@return the type of the target}
|
||||
*/
|
||||
TargetType targetType();
|
||||
|
||||
/**
|
||||
* {@return the size of the target info}
|
||||
*/
|
||||
default int size() {
|
||||
return targetType().sizeIfFixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on a class or method type parameter declaration}
|
||||
* @param targetType {@link TargetType#CLASS_TYPE_PARAMETER} or {@link TargetType#METHOD_TYPE_PARAMETER}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterTarget ofTypeParameter(TargetType targetType, int typeParameterIndex) {
|
||||
return new TargetInfoImpl.TypeParameterTargetImpl(targetType, typeParameterIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on a class type parameter declaration}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterTarget ofClassTypeParameter(int typeParameterIndex) {
|
||||
return ofTypeParameter(TargetType.CLASS_TYPE_PARAMETER, typeParameterIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on a method type parameter declaration}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterTarget ofMethodTypeParameter(int typeParameterIndex) {
|
||||
return ofTypeParameter(TargetType.METHOD_TYPE_PARAMETER, typeParameterIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type of an "extends" or "implements" clause}
|
||||
* @param supertypeIndex the index into the interfaces array or 65535 to indicate it is the superclass
|
||||
*/
|
||||
static SupertypeTarget ofClassExtends(int supertypeIndex) {
|
||||
return new TargetInfoImpl.SupertypeTargetImpl(supertypeIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th bound of the j'th type parameter declaration of
|
||||
* a generic class, interface, method, or constructor}
|
||||
* @param targetType {@link TargetType#CLASS_TYPE_PARAMETER_BOUND} or {@link TargetType#METHOD_TYPE_PARAMETER_BOUND}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
* @param boundIndex specifies which bound of the type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterBoundTarget ofTypeParameterBound(TargetType targetType, int typeParameterIndex, int boundIndex) {
|
||||
return new TargetInfoImpl.TypeParameterBoundTargetImpl(targetType, typeParameterIndex, boundIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th bound of the j'th type parameter declaration of
|
||||
* a generic class, or interface}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
* @param boundIndex specifies which bound of the type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterBoundTarget ofClassTypeParameterBound(int typeParameterIndex, int boundIndex) {
|
||||
return ofTypeParameterBound(TargetType.CLASS_TYPE_PARAMETER_BOUND, typeParameterIndex, boundIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th bound of the j'th type parameter declaration of
|
||||
* a generic method, or constructor}
|
||||
* @param typeParameterIndex specifies which type parameter declaration is annotated
|
||||
* @param boundIndex specifies which bound of the type parameter declaration is annotated
|
||||
*/
|
||||
static TypeParameterBoundTarget ofMethodTypeParameterBound(int typeParameterIndex, int boundIndex) {
|
||||
return ofTypeParameterBound(TargetType.METHOD_TYPE_PARAMETER_BOUND, typeParameterIndex, boundIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations}
|
||||
* @param targetType {@link TargetType#FIELD}, {@link TargetType#METHOD_RETURN} or {@link TargetType#METHOD_RECEIVER}
|
||||
*/
|
||||
static EmptyTarget of(TargetType targetType) {
|
||||
return new TargetInfoImpl.EmptyTargetImpl(targetType);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a field or record declaration}
|
||||
*/
|
||||
static EmptyTarget ofField() {
|
||||
return of(TargetType.FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the return type of a method or a newly constructed object}
|
||||
*/
|
||||
static EmptyTarget ofMethodReturn() {
|
||||
return of(TargetType.METHOD_RETURN);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the receiver type of a method or constructor}
|
||||
*/
|
||||
static EmptyTarget ofMethodReceiver() {
|
||||
return of(TargetType.METHOD_RECEIVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a formal parameter declaration of a method,
|
||||
* constructor, or lambda expression}
|
||||
* @param formalParameterIndex specifies which formal parameter declaration has an annotated type
|
||||
*/
|
||||
static FormalParameterTarget ofMethodFormalParameter(int formalParameterIndex) {
|
||||
return new TargetInfoImpl.FormalParameterTargetImpl(formalParameterIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type in the throws clause of a method or
|
||||
* constructor declaration}
|
||||
* @param throwsTargetIndex the index into the exception table of the Exceptions attribute of the method
|
||||
*/
|
||||
static ThrowsTarget ofThrows(int throwsTargetIndex) {
|
||||
return new TargetInfoImpl.ThrowsTargetImpl(throwsTargetIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a local variable declaration,
|
||||
* including a variable declared as a resource in a try-with-resources statement}
|
||||
* @param targetType {@link TargetType#LOCAL_VARIABLE} or {@link TargetType#RESOURCE_VARIABLE}
|
||||
* @param table the list of local variable targets
|
||||
*/
|
||||
static LocalVarTarget ofVariable(TargetType targetType, List<LocalVarTargetInfo> table) {
|
||||
return new TargetInfoImpl.LocalVarTargetImpl(targetType, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a local variable declaration}
|
||||
* @param table the list of local variable targets
|
||||
*/
|
||||
static LocalVarTarget ofLocalVariable(List<LocalVarTargetInfo> table) {
|
||||
return ofVariable(TargetType.LOCAL_VARIABLE, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a local variable declared
|
||||
* as a resource in a try-with-resources statement}
|
||||
* @param table the list of local variable targets
|
||||
*/
|
||||
static LocalVarTarget ofResourceVariable(List<LocalVarTargetInfo> table) {
|
||||
return ofVariable(TargetType.RESOURCE_VARIABLE, table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type in an exception parameter declaration}
|
||||
* @param exceptionTableIndex the index into the exception table of the Code attribute
|
||||
*/
|
||||
static CatchTarget ofExceptionParameter(int exceptionTableIndex) {
|
||||
return new TargetInfoImpl.CatchTargetImpl(exceptionTableIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in an instanceof expression or a new expression,
|
||||
* or the type before the :: in a method reference expression}
|
||||
* {@param targetType {@link TargetType#INSTANCEOF}, {@link TargetType#NEW},
|
||||
* {@link TargetType#CONSTRUCTOR_REFERENCE},
|
||||
* or {@link TargetType#METHOD_REFERENCE}}
|
||||
* @param target the code label corresponding to the instruction
|
||||
*/
|
||||
static OffsetTarget ofOffset(TargetType targetType, Label target) {
|
||||
return new TargetInfoImpl.OffsetTargetImpl(targetType, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in an instanceof expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
*/
|
||||
static OffsetTarget ofInstanceofExpr(Label target) {
|
||||
return ofOffset(TargetType.INSTANCEOF, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type in a new expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
*/
|
||||
static OffsetTarget ofNewExpr(Label target) {
|
||||
return ofOffset(TargetType.NEW, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type before the :: in a constructor reference expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
*/
|
||||
static OffsetTarget ofConstructorReference(Label target) {
|
||||
return ofOffset(TargetType.CONSTRUCTOR_REFERENCE, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the type before the :: in a method reference expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
*/
|
||||
static OffsetTarget ofMethodReference(Label target) {
|
||||
return ofOffset(TargetType.METHOD_REFERENCE, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type in a cast expression,
|
||||
* or on the i'th type argument in the explicit type argument list for any of the following:
|
||||
* a new expression, an explicit constructor invocation statement, a method invocation expression,
|
||||
* or a method reference expression}
|
||||
* {@param targetType {@link TargetType#CAST}, {@link TargetType#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
|
||||
* {@link TargetType#METHOD_INVOCATION_TYPE_ARGUMENT},
|
||||
* {@link TargetType#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT},
|
||||
* or {@link TargetType#METHOD_REFERENCE_TYPE_ARGUMENT}}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the cast operator or argument is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofTypeArgument(TargetType targetType, Label target, int typeArgumentIndex) {
|
||||
return new TargetInfoImpl.TypeArgumentTargetImpl(targetType, target, typeArgumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type in a cast expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the cast operator is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofCastExpr(Label target, int typeArgumentIndex) {
|
||||
return ofTypeArgument(TargetType.CAST, target, typeArgumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type argument in the explicit type argument list for
|
||||
* an explicit constructor invocation statement}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the argument is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofConstructorInvocationTypeArgument(Label target, int typeArgumentIndex) {
|
||||
return ofTypeArgument(TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, target, typeArgumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type argument in the explicit type argument list for
|
||||
* a method invocation expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the argument is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofMethodInvocationTypeArgument(Label target, int typeArgumentIndex) {
|
||||
return ofTypeArgument(TargetType.METHOD_INVOCATION_TYPE_ARGUMENT, target, typeArgumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type argument in the explicit type argument list for
|
||||
* a new expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the argument is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofConstructorReferenceTypeArgument(Label target, int typeArgumentIndex) {
|
||||
return ofTypeArgument(TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT, target, typeArgumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a target for annotations on the i'th type argument in the explicit type argument list for
|
||||
* a method reference expression}
|
||||
* @param target the code label corresponding to the instruction
|
||||
* @param typeArgumentIndex specifies which type in the argument is annotated
|
||||
*/
|
||||
static TypeArgumentTarget ofMethodReferenceTypeArgument(Label target, int typeArgumentIndex) {
|
||||
return ofTypeArgument(TargetType.METHOD_REFERENCE_TYPE_ARGUMENT, target, typeArgumentIndex);
|
||||
}
|
||||
@ -441,7 +596,7 @@ public sealed interface TypeAnnotation
|
||||
* Exceptions attribute of the method_info structure enclosing the
|
||||
* RuntimeVisibleTypeAnnotations attribute.
|
||||
*
|
||||
* @return index into the list jdk.internal.classfile.attribute.ExceptionsAttribute.exceptions()
|
||||
* @return the index into the list jdk.internal.classfile.attribute.ExceptionsAttribute.exceptions()
|
||||
*/
|
||||
int throwsTargetIndex();
|
||||
}
|
||||
@ -471,7 +626,7 @@ public sealed interface TypeAnnotation
|
||||
* The given local variable has a value at indices into the code array in the interval
|
||||
* [start_pc, start_pc + length), that is, between start_pc inclusive and start_pc + length exclusive.
|
||||
*
|
||||
* @return the start of the bytecode section.
|
||||
* @return the start of the bytecode section
|
||||
*/
|
||||
Label startLabel();
|
||||
|
||||
@ -480,7 +635,7 @@ public sealed interface TypeAnnotation
|
||||
* The given local variable has a value at indices into the code array in the interval
|
||||
* [start_pc, start_pc + length), that is, between start_pc inclusive and start_pc + length exclusive.
|
||||
*
|
||||
* @return
|
||||
* @return the end of the bytecode section
|
||||
*/
|
||||
Label endLabel();
|
||||
|
||||
@ -489,10 +644,16 @@ public sealed interface TypeAnnotation
|
||||
*
|
||||
* If the local variable at index is of type double or long, it occupies both index and index + 1.
|
||||
*
|
||||
* @return index into the local variables
|
||||
* @return the index into the local variables
|
||||
*/
|
||||
int index();
|
||||
|
||||
/**
|
||||
* {@return local variable target info}
|
||||
* @param startLabel the code label indicating start of an interval where variable has value
|
||||
* @param endLabel the code label indicating start of an interval where variable has value
|
||||
* @param index index into the local variables
|
||||
*/
|
||||
static LocalVarTargetInfo of(Label startLabel, Label endLabel, int index) {
|
||||
return new TargetInfoImpl.LocalVarTargetInfoImpl(startLabel, endLabel, index);
|
||||
}
|
||||
@ -526,7 +687,7 @@ public sealed interface TypeAnnotation
|
||||
* corresponding to the instanceof expression, the new bytecode instruction corresponding to the new
|
||||
* expression, or the bytecode instruction corresponding to the method reference expression.
|
||||
*
|
||||
* @return
|
||||
* @return the code label corresponding to the instruction
|
||||
*/
|
||||
Label target();
|
||||
}
|
||||
@ -547,7 +708,7 @@ public sealed interface TypeAnnotation
|
||||
* instruction corresponding to the method invocation expression, or the bytecode instruction corresponding to
|
||||
* the method reference expression.
|
||||
*
|
||||
* @return
|
||||
* @return the code label corresponding to the instruction
|
||||
*/
|
||||
Label target();
|
||||
|
||||
@ -567,31 +728,27 @@ public sealed interface TypeAnnotation
|
||||
}
|
||||
|
||||
/**
|
||||
* JVMS: Wherever a type is used in a declaration or expression, the type_path structure identifies which part of
|
||||
* the type is annotated. An annotation may appear on the type itself, but if the type is a reference type, then
|
||||
* there are additional locations where an annotation may appear:
|
||||
*
|
||||
* If an array type T[] is used in a declaration or expression, then an annotation may appear on any component type
|
||||
* of the array type, including the element type.
|
||||
*
|
||||
* If a nested type T1.T2 is used in a declaration or expression, then an annotation may appear on the name of the
|
||||
* innermost member type and any enclosing type for which a type annotation is admissible {@jls 9.7.4}.
|
||||
*
|
||||
* If a parameterized type {@literal T<A> or T<? extends A> or T<? super A>} is used in a declaration or expression, then an
|
||||
* annotation may appear on any type argument or on the bound of any wildcard type argument.
|
||||
*
|
||||
* JVMS: ... each entry in the path array represents an iterative, left-to-right step towards the precise location
|
||||
* of the annotation in an array type, nested type, or parameterized type. (In an array type, the iteration visits
|
||||
* the array type itself, then its component type, then the component type of that component type, and so on,
|
||||
* until the element type is reached.)
|
||||
* JVMS: Type_path structure identifies which part of the type is annotated,
|
||||
* as defined in {@jvms 4.7.20.2}
|
||||
*/
|
||||
sealed interface TypePathComponent
|
||||
permits UnboundAttribute.TypePathComponentImpl {
|
||||
|
||||
/**
|
||||
* Type path kind, as defined in {@jvms 4.7.20.2}
|
||||
*/
|
||||
public enum Kind {
|
||||
|
||||
/** Annotation is deeper in an array type */
|
||||
ARRAY(0),
|
||||
|
||||
/** Annotation is deeper in a nested type */
|
||||
INNER_TYPE(1),
|
||||
|
||||
/** Annotation is on the bound of a wildcard type argument of a parameterized type */
|
||||
WILDCARD(2),
|
||||
|
||||
/** Annotation is on a type argument of a parameterized type */
|
||||
TYPE_ARGUMENT(3);
|
||||
|
||||
private final int tag;
|
||||
@ -600,13 +757,21 @@ public sealed interface TypeAnnotation
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the type path kind value}
|
||||
*/
|
||||
public int tag() {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
/** static instance for annotation is deeper in an array type */
|
||||
TypePathComponent ARRAY = new UnboundAttribute.TypePathComponentImpl(Kind.ARRAY, 0);
|
||||
|
||||
/** static instance for annotation is deeper in a nested type */
|
||||
TypePathComponent INNER_TYPE = new UnboundAttribute.TypePathComponentImpl(Kind.INNER_TYPE, 0);
|
||||
|
||||
/** static instance for annotation is on the bound of a wildcard type argument of a parameterized type */
|
||||
TypePathComponent WILDCARD = new UnboundAttribute.TypePathComponentImpl(Kind.WILDCARD, 0);
|
||||
|
||||
|
||||
@ -629,6 +794,11 @@ public sealed interface TypeAnnotation
|
||||
*/
|
||||
int typeArgumentIndex();
|
||||
|
||||
/**
|
||||
* {@return type path component of an annotation}
|
||||
* @param typePathKind the kind of path element
|
||||
* @param typeArgumentIndex the type argument index
|
||||
*/
|
||||
static TypePathComponent of(Kind typePathKind, int typeArgumentIndex) {
|
||||
|
||||
return switch (typePathKind) {
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on methods of annotation types, and records the default value
|
||||
* {@jls 9.6.2} for the element corresponding to this method. Delivered as a
|
||||
* {@link MethodElement} when traversing the elements of a {@link MethodModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface AnnotationDefaultAttribute
|
||||
extends Attribute<AnnotationDefaultAttribute>, MethodElement
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* Models the {@code BootstrapMethods} attribute {@jvms 4.7.23}, which serves as
|
||||
* an extension to the constant pool of a classfile. Elements of the bootstrap
|
||||
* method table are accessed through {@link ConstantPool}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface BootstrapMethodsAttribute
|
||||
extends Attribute<BootstrapMethodsAttribute>
|
||||
|
@ -54,6 +54,8 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* several code index ranges, but there will be a smallest code index range, and
|
||||
* for each kind of range in which it is enclosed there will be a smallest code
|
||||
* index range. The character range entries may appear in any order.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface CharacterRangeTableAttribute
|
||||
extends Attribute<CharacterRangeTableAttribute>
|
||||
|
@ -35,6 +35,10 @@ import jdk.internal.classfile.impl.BoundAttribute;
|
||||
* non-abstract methods and contains the bytecode of the method body. Delivered
|
||||
* as a {@link jdk.internal.classfile.MethodElement} when traversing the elements of a
|
||||
* {@link jdk.internal.classfile.MethodModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface CodeAttribute extends Attribute<CodeAttribute>, CodeModel
|
||||
permits BoundAttribute.BoundCodeAttribute {
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes and records the compilation time of the class. Delivered
|
||||
* as a {@link jdk.internal.classfile.ClassElement} when traversing the elements of
|
||||
* a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface CompilationIDAttribute
|
||||
extends Attribute<CompilationIDAttribute>, ClassElement
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* fields and indicates that the field's value is a constant. Delivered as a
|
||||
* {@link jdk.internal.classfile.FieldElement} when traversing the elements of a
|
||||
* {@link jdk.internal.classfile.FieldModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ConstantValueAttribute
|
||||
extends Attribute<ConstantValueAttribute>, FieldElement
|
||||
|
@ -36,6 +36,8 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* classes, methods, and fields. Delivered as a {@link ClassElement},
|
||||
* {@link MethodElement}, or {@link FieldElement} when traversing the elements
|
||||
* of a corresponding model.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface DeprecatedAttribute
|
||||
extends Attribute<DeprecatedAttribute>,
|
||||
|
@ -43,6 +43,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
* on classes, and indicates that the class is a local or anonymous class.
|
||||
* Delivered as a {@link ClassElement} when traversing the elements of a {@link
|
||||
* jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface EnclosingMethodAttribute
|
||||
extends Attribute<EnclosingMethodAttribute>, ClassElement
|
||||
|
@ -40,6 +40,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
* methods, and records the exceptions declared to be thrown by this method.
|
||||
* Delivered as a {@link MethodElement} when traversing the elements of a
|
||||
* {@link jdk.internal.classfile.MethodModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ExceptionsAttribute
|
||||
extends Attribute<ExceptionsAttribute>, MethodElement
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes, and records which classes referenced by this classfile
|
||||
* are inner classes. Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface InnerClassesAttribute
|
||||
extends Attribute<InnerClassesAttribute>, ClassElement
|
||||
|
@ -37,6 +37,8 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* Delivered as a {@link jdk.internal.classfile.instruction.LineNumber} when traversing the
|
||||
* elements of a {@link jdk.internal.classfile.CodeModel}, according to the setting of the
|
||||
* {@link jdk.internal.classfile.Classfile.LineNumbersOption} option.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface LineNumberTableAttribute
|
||||
extends Attribute<LineNumberTableAttribute>
|
||||
|
@ -37,6 +37,8 @@ import java.util.List;
|
||||
* Delivered as a {@link jdk.internal.classfile.instruction.LocalVariable} when traversing the
|
||||
* elements of a {@link jdk.internal.classfile.CodeModel}, according to the setting of the
|
||||
* {@link jdk.internal.classfile.Classfile.DebugElementsOption} option.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface LocalVariableTableAttribute
|
||||
extends Attribute<LocalVariableTableAttribute>
|
||||
|
@ -38,6 +38,8 @@ import java.util.List;
|
||||
* Delivered as a {@link jdk.internal.classfile.instruction.LocalVariable} when traversing the
|
||||
* elements of a {@link jdk.internal.classfile.CodeModel}, according to the setting of the
|
||||
* {@link jdk.internal.classfile.Classfile.LineNumbersOption} option.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface LocalVariableTypeTableAttribute
|
||||
extends Attribute<LocalVariableTypeTableAttribute>
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on methods, and records optional information about the method's
|
||||
* parameters. Delivered as a {@link jdk.internal.classfile.MethodElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.MethodModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface MethodParametersAttribute
|
||||
extends Attribute<MethodParametersAttribute>, MethodElement
|
||||
|
@ -49,6 +49,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
* appear on classes that represent module descriptors.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
|
||||
public sealed interface ModuleAttribute
|
||||
@ -72,12 +76,17 @@ public sealed interface ModuleAttribute
|
||||
return AccessFlag.maskToAccessFlags(moduleFlagsMask(), AccessFlag.Location.MODULE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests presence of module flag
|
||||
* @param flag the module flag
|
||||
* @return true if the flag is set
|
||||
*/
|
||||
default boolean has(AccessFlag flag) {
|
||||
return Util.has(AccessFlag.Location.MODULE, moduleFlagsMask(), flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return version of the module, if present}
|
||||
* {@return the version of the module, if present}
|
||||
*/
|
||||
Optional<Utf8Entry> moduleVersion();
|
||||
|
||||
@ -155,40 +164,156 @@ public sealed interface ModuleAttribute
|
||||
return mb.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for module attributes.
|
||||
*/
|
||||
public sealed interface ModuleAttributeBuilder
|
||||
permits ModuleAttributeBuilderImpl {
|
||||
|
||||
/**
|
||||
* Sets the module name
|
||||
* @param moduleName the module name
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder moduleName(ModuleDesc moduleName);
|
||||
|
||||
/**
|
||||
* Sets the module flags
|
||||
* @param flagsMask the module flags
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder moduleFlags(int flagsMask);
|
||||
|
||||
/**
|
||||
* Sets the module flags
|
||||
* @param moduleFlags the module flags
|
||||
* @return this builder
|
||||
*/
|
||||
default ModuleAttributeBuilder moduleFlags(AccessFlag... moduleFlags) {
|
||||
return moduleFlags(Util.flagsToBits(AccessFlag.Location.MODULE, moduleFlags));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the module flags
|
||||
* @param version the module version
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder moduleVersion(String version);
|
||||
|
||||
/**
|
||||
* Adds module requirement
|
||||
* @param module the required module
|
||||
* @param requiresFlagsMask the requires flags
|
||||
* @param version the required module version
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder requires(ModuleDesc module, int requiresFlagsMask, String version);
|
||||
|
||||
/**
|
||||
* Adds module requirement
|
||||
* @param module the required module
|
||||
* @param requiresFlags the requires flags
|
||||
* @param version the required module version
|
||||
* @return this builder
|
||||
*/
|
||||
default ModuleAttributeBuilder requires(ModuleDesc module, Collection<AccessFlag> requiresFlags, String version) {
|
||||
return requires(module, Util.flagsToBits(AccessFlag.Location.MODULE_REQUIRES, requiresFlags), version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds module requirement
|
||||
* @param requires the module require info
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder requires(ModuleRequireInfo requires);
|
||||
|
||||
/**
|
||||
* Adds exported package
|
||||
* @param pkge the exported package
|
||||
* @param exportsFlagsMask the export flags
|
||||
* @param exportsToModules the modules to export to
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder exports(PackageDesc pkge, int exportsFlagsMask, ModuleDesc... exportsToModules);
|
||||
|
||||
/**
|
||||
* Adds exported package
|
||||
* @param pkge the exported package
|
||||
* @param exportsFlags the export flags
|
||||
* @param exportsToModules the modules to export to
|
||||
* @return this builder
|
||||
*/
|
||||
default ModuleAttributeBuilder exports(PackageDesc pkge, Collection<AccessFlag> exportsFlags, ModuleDesc... exportsToModules) {
|
||||
return exports(pkge, Util.flagsToBits(AccessFlag.Location.MODULE_EXPORTS, exportsFlags), exportsToModules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds exported package
|
||||
* @param exports the module export info
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder exports(ModuleExportInfo exports);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pkge the opened package
|
||||
* @param opensFlagsMask the open package flags
|
||||
* @param opensToModules the modules to open to
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder opens(PackageDesc pkge, int opensFlagsMask, ModuleDesc... opensToModules);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pkge the opened package
|
||||
* @param opensFlags the open package flags
|
||||
* @param opensToModules the modules to open to
|
||||
* @return this builder
|
||||
*/
|
||||
default ModuleAttributeBuilder opens(PackageDesc pkge, Collection<AccessFlag> opensFlags, ModuleDesc... opensToModules) {
|
||||
return opens(pkge, Util.flagsToBits(AccessFlag.Location.MODULE_OPENS, opensFlags), opensToModules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens package
|
||||
* @param opens the module open info
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder opens(ModuleOpenInfo opens);
|
||||
|
||||
/**
|
||||
* Declares use of a service
|
||||
* @param service the service class used
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder uses(ClassDesc service);
|
||||
|
||||
/**
|
||||
* Declares use of a service
|
||||
* @param uses the service class used
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder uses(ClassEntry uses);
|
||||
|
||||
/**
|
||||
* Declares provision of a service
|
||||
* @param service the service class provided
|
||||
* @param implClasses the implementation classes
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder provides(ClassDesc service, ClassDesc... implClasses);
|
||||
|
||||
/**
|
||||
* Declares provision of a service
|
||||
* @param provides the module provides info
|
||||
* @return this builder
|
||||
*/
|
||||
ModuleAttributeBuilder provides(ModuleProvideInfo provides);
|
||||
|
||||
/**
|
||||
* Builds module attribute.
|
||||
* @return the module attribute
|
||||
*/
|
||||
ModuleAttribute build();
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
*
|
||||
* }
|
||||
* } </pre>
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ModuleHashesAttribute
|
||||
extends Attribute<ModuleHashesAttribute>, ClassElement
|
||||
|
@ -38,6 +38,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes that represent module descriptors.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ModuleMainClassAttribute
|
||||
extends Attribute<ModuleMainClassAttribute>, ClassElement
|
||||
|
@ -56,6 +56,9 @@ public sealed interface ModuleOpenInfo
|
||||
*/
|
||||
int opensFlagsMask();
|
||||
|
||||
/**
|
||||
* {@return the access flags}
|
||||
*/
|
||||
default Set<AccessFlag> opensFlags() {
|
||||
return AccessFlag.maskToAccessFlags(opensFlagsMask(), AccessFlag.Location.MODULE_OPENS);
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes that represent module descriptors.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ModulePackagesAttribute
|
||||
extends Attribute<ModulePackagesAttribute>, ClassElement
|
||||
|
@ -56,6 +56,9 @@ public sealed interface ModuleRequireInfo
|
||||
*/
|
||||
int requiresFlagsMask();
|
||||
|
||||
/**
|
||||
* {@return the access flags}
|
||||
*/
|
||||
default Set<AccessFlag> requiresFlags() {
|
||||
return AccessFlag.maskToAccessFlags(requiresFlagsMask(), AccessFlag.Location.MODULE_REQUIRES);
|
||||
}
|
||||
|
@ -56,6 +56,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* 0x0008 (WARN_INCUBATING)
|
||||
* }
|
||||
* } </pre>
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ModuleResolutionAttribute
|
||||
extends Attribute<ModuleResolutionAttribute>, ClassElement
|
||||
@ -72,6 +76,7 @@ public sealed interface ModuleResolutionAttribute
|
||||
* 0x0002 (WARN_DEPRECATED)
|
||||
* 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
|
||||
* 0x0008 (WARN_INCUBATING)
|
||||
* @return the module resolution flags
|
||||
*/
|
||||
int resolutionFlags();
|
||||
|
||||
|
@ -51,6 +51,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* u2 target_platform_index;
|
||||
* }
|
||||
* } </pre>
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface ModuleTargetAttribute
|
||||
extends Attribute<ModuleTargetAttribute>, ClassElement
|
||||
|
@ -38,6 +38,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes to indicate that this class is a member of a nest.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface NestHostAttribute extends Attribute<NestHostAttribute>, ClassElement
|
||||
permits BoundAttribute.BoundNestHostAttribute,
|
||||
|
@ -40,6 +40,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
* appear on classes to indicate that this class is the host of a nest.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface NestMembersAttribute extends Attribute<NestMembersAttribute>, ClassElement
|
||||
permits BoundAttribute.BoundNestMembersAttribute, UnboundAttribute.UnboundNestMembersAttribute {
|
||||
|
@ -40,6 +40,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
* appear on classes to indicate which classes may extend this class.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface PermittedSubclassesAttribute
|
||||
extends Attribute<PermittedSubclassesAttribute>, ClassElement
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* appear on classes to indicate that this class is a record class.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing the elements of a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RecordAttribute extends Attribute<RecordAttribute>, ClassElement
|
||||
permits BoundAttribute.BoundRecordAttribute, UnboundAttribute.UnboundRecordAttribute {
|
||||
|
@ -36,6 +36,10 @@ import java.util.List;
|
||||
* can appear on classes, methods, and fields. Delivered as a
|
||||
* {@link jdk.internal.classfile.ClassElement}, {@link jdk.internal.classfile.FieldElement}, or
|
||||
* {@link jdk.internal.classfile.MethodElement} when traversing the corresponding model type.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeInvisibleAnnotationsAttribute
|
||||
extends Attribute<RuntimeInvisibleAnnotationsAttribute>,
|
||||
|
@ -38,6 +38,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* Models the {@code RuntimeInvisibleParameterAnnotations} attribute
|
||||
* {@jvms 4.7.19}, which can appear on methods. Delivered as a {@link
|
||||
* jdk.internal.classfile.MethodElement} when traversing a {@link MethodModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeInvisibleParameterAnnotationsAttribute
|
||||
extends Attribute<RuntimeInvisibleParameterAnnotationsAttribute>, MethodElement
|
||||
|
@ -42,6 +42,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* {@link jdk.internal.classfile.ClassElement}, {@link jdk.internal.classfile.FieldElement},
|
||||
* {@link jdk.internal.classfile.MethodElement}, or {@link CodeElement} when traversing
|
||||
* the corresponding model type.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeInvisibleTypeAnnotationsAttribute
|
||||
extends Attribute<RuntimeInvisibleTypeAnnotationsAttribute>,
|
||||
|
@ -36,6 +36,10 @@ import java.util.List;
|
||||
* can appear on classes, methods, and fields. Delivered as a
|
||||
* {@link jdk.internal.classfile.ClassElement}, {@link jdk.internal.classfile.FieldElement}, or
|
||||
* {@link jdk.internal.classfile.MethodElement} when traversing the corresponding model type.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeVisibleAnnotationsAttribute
|
||||
extends Attribute<RuntimeVisibleAnnotationsAttribute>,
|
||||
|
@ -38,6 +38,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* Models the {@code RuntimeVisibleParameterAnnotations} attribute {@jvms 4.7.18}, which
|
||||
* can appear on methods. Delivered as a {@link jdk.internal.classfile.MethodElement}
|
||||
* when traversing a {@link MethodModel}.
|
||||
*
|
||||
* @apiNote The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeVisibleParameterAnnotationsAttribute
|
||||
extends Attribute<RuntimeVisibleParameterAnnotationsAttribute>, MethodElement
|
||||
|
@ -42,6 +42,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* {@link jdk.internal.classfile.ClassElement}, {@link jdk.internal.classfile.FieldElement},
|
||||
* {@link jdk.internal.classfile.MethodElement}, or {@link CodeElement} when traversing
|
||||
* the corresponding model type.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface RuntimeVisibleTypeAnnotationsAttribute
|
||||
extends Attribute<RuntimeVisibleTypeAnnotationsAttribute>,
|
||||
|
@ -43,6 +43,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* {@link jdk.internal.classfile.ClassElement}, {@link jdk.internal.classfile.FieldElement}, or
|
||||
* {@link jdk.internal.classfile.MethodElement} when traversing
|
||||
* the corresponding model type.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface SignatureAttribute
|
||||
extends Attribute<SignatureAttribute>,
|
||||
|
@ -31,9 +31,13 @@ import jdk.internal.classfile.impl.BoundAttribute;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
|
||||
/**
|
||||
* Models the {@code SourceDebugExtension} attribute (@@@ need reference).
|
||||
* Models the {@code SourceDebugExtension} attribute.
|
||||
* Delivered as a {@link jdk.internal.classfile.ClassElement} when traversing the elements of
|
||||
* a {@link jdk.internal.classfile.ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface SourceDebugExtensionAttribute
|
||||
extends Attribute<SourceDebugExtensionAttribute>, ClassElement
|
||||
|
@ -37,6 +37,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* Models the {@code SourceFile} attribute {@jvms 4.7.10}, which
|
||||
* can appear on classes. Delivered as a {@link jdk.internal.classfile.ClassElement}
|
||||
* when traversing a {@link ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface SourceFileAttribute
|
||||
extends Attribute<SourceFileAttribute>, ClassElement
|
||||
@ -47,10 +51,18 @@ public sealed interface SourceFileAttribute
|
||||
*/
|
||||
Utf8Entry sourceFile();
|
||||
|
||||
/**
|
||||
* {@return a source file attribute}
|
||||
* @param sourceFile the source file name
|
||||
*/
|
||||
static SourceFileAttribute of(String sourceFile) {
|
||||
return of(TemporaryConstantPool.INSTANCE.utf8Entry(sourceFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a source file attribute}
|
||||
* @param sourceFile the source file name
|
||||
*/
|
||||
static SourceFileAttribute of(Utf8Entry sourceFile) {
|
||||
return new UnboundAttribute.UnboundSourceFileAttribute(sourceFile);
|
||||
}
|
||||
|
@ -34,9 +34,13 @@ import jdk.internal.classfile.impl.TemporaryConstantPool;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
|
||||
/**
|
||||
* Models the {@code SourceID} attribute (@@@ reference needed), which can
|
||||
* Models the {@code SourceID} attribute, which can
|
||||
* appear on classes. Delivered as a {@link jdk.internal.classfile.ClassElement} when
|
||||
* traversing a {@link ClassModel}.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface SourceIDAttribute
|
||||
extends Attribute<SourceIDAttribute>, ClassElement
|
||||
|
@ -40,11 +40,32 @@ import static jdk.internal.classfile.Classfile.*;
|
||||
public sealed interface StackMapFrameInfo
|
||||
permits StackMapDecoder.StackMapFrameImpl {
|
||||
|
||||
/**
|
||||
* {@return the frame compact form type}
|
||||
*/
|
||||
int frameType();
|
||||
|
||||
/**
|
||||
* {@return the frame target label}
|
||||
*/
|
||||
Label target();
|
||||
|
||||
/**
|
||||
* {@return the expanded local variable types}
|
||||
*/
|
||||
List<VerificationTypeInfo> locals();
|
||||
|
||||
/**
|
||||
* {@return the expanded stack types}
|
||||
*/
|
||||
List<VerificationTypeInfo> stack();
|
||||
|
||||
/**
|
||||
* {@return a new stack map frame}
|
||||
* @param target the location of the frame
|
||||
* @param locals the complete list of frame locals
|
||||
* @param stack the complete frame stack
|
||||
*/
|
||||
public static StackMapFrameInfo of(Label target,
|
||||
List<VerificationTypeInfo> locals,
|
||||
List<VerificationTypeInfo> stack) {
|
||||
@ -56,6 +77,10 @@ public sealed interface StackMapFrameInfo
|
||||
* The type of a stack value.
|
||||
*/
|
||||
sealed interface VerificationTypeInfo {
|
||||
|
||||
/**
|
||||
* {@return the tag of the type info}
|
||||
*/
|
||||
int tag();
|
||||
}
|
||||
|
||||
@ -63,12 +88,26 @@ public sealed interface StackMapFrameInfo
|
||||
* A simple stack value.
|
||||
*/
|
||||
public enum SimpleVerificationTypeInfo implements VerificationTypeInfo {
|
||||
|
||||
/** verification type top */
|
||||
ITEM_TOP(VT_TOP),
|
||||
|
||||
/** verification type int */
|
||||
ITEM_INTEGER(VT_INTEGER),
|
||||
|
||||
/** verification type float */
|
||||
ITEM_FLOAT(VT_FLOAT),
|
||||
|
||||
/** verification type double */
|
||||
ITEM_DOUBLE(VT_DOUBLE),
|
||||
|
||||
/** verification type long */
|
||||
ITEM_LONG(VT_LONG),
|
||||
|
||||
/** verification type null */
|
||||
ITEM_NULL(VT_NULL),
|
||||
|
||||
/** verification type uninitializedThis */
|
||||
ITEM_UNINITIALIZED_THIS(VT_UNINITIALIZED_THIS);
|
||||
|
||||
|
||||
@ -90,19 +129,30 @@ public sealed interface StackMapFrameInfo
|
||||
sealed interface ObjectVerificationTypeInfo extends VerificationTypeInfo
|
||||
permits StackMapDecoder.ObjectVerificationTypeInfoImpl {
|
||||
|
||||
/**
|
||||
* {@return a new object verification type info}
|
||||
* @param className the class of the object
|
||||
*/
|
||||
public static ObjectVerificationTypeInfo of(ClassEntry className) {
|
||||
return new StackMapDecoder.ObjectVerificationTypeInfoImpl(className);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a new object verification type info}
|
||||
* @param classDesc the class of the object
|
||||
*/
|
||||
public static ObjectVerificationTypeInfo of(ClassDesc classDesc) {
|
||||
return of(TemporaryConstantPool.INSTANCE.classEntry(classDesc));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the class of the value}
|
||||
* {@return the class of the object}
|
||||
*/
|
||||
ClassEntry className();
|
||||
|
||||
/**
|
||||
* {@return the class of the object}
|
||||
*/
|
||||
default ClassDesc classSymbol() {
|
||||
return className().asSymbol();
|
||||
}
|
||||
@ -113,8 +163,16 @@ public sealed interface StackMapFrameInfo
|
||||
*/
|
||||
sealed interface UninitializedVerificationTypeInfo extends VerificationTypeInfo
|
||||
permits StackMapDecoder.UninitializedVerificationTypeInfoImpl {
|
||||
|
||||
/**
|
||||
* {@return the {@code new} instruction position that creates this unitialized object}
|
||||
*/
|
||||
Label newTarget();
|
||||
|
||||
/**
|
||||
* {@return an unitialized verification type info}
|
||||
* @param newTarget the {@code new} instruction position that creates this unitialized object
|
||||
*/
|
||||
public static UninitializedVerificationTypeInfo of(Label newTarget) {
|
||||
return new StackMapDecoder.UninitializedVerificationTypeInfoImpl(newTarget);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
/**
|
||||
* Models the {@code StackMapTable} attribute {@jvms 4.7.4}, which can appear
|
||||
* on a {@code Code} attribute.
|
||||
* <p>
|
||||
* The attribute does not permit multiple instances in a given location.
|
||||
* Subsequent occurrence of the attribute takes precedence during the attributed
|
||||
* element build or transformation.
|
||||
*/
|
||||
public sealed interface StackMapTableAttribute
|
||||
extends Attribute<StackMapTableAttribute>, CodeElement
|
||||
@ -45,6 +49,10 @@ public sealed interface StackMapTableAttribute
|
||||
*/
|
||||
List<StackMapFrameInfo> entries();
|
||||
|
||||
/**
|
||||
* {@return a stack map table attribute}
|
||||
* @param entries the stack map frames
|
||||
*/
|
||||
public static StackMapTableAttribute of(List<StackMapFrameInfo> entries) {
|
||||
return new UnboundAttribute.UnboundStackMapTableAttribute(entries);
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
* classes, methods, and fields. Delivered as a {@link ClassElement},
|
||||
* {@link MethodElement}, or {@link FieldElement} when traversing the elements
|
||||
* of a corresponding model.
|
||||
* <p>
|
||||
* The attribute permits multiple instances in a given location.
|
||||
*/
|
||||
public sealed interface SyntheticAttribute
|
||||
extends Attribute<SyntheticAttribute>,
|
||||
|
@ -51,6 +51,7 @@ public sealed interface BranchInstruction extends Instruction
|
||||
*
|
||||
* @param op the opcode for the specific type of branch instruction,
|
||||
* which must be of kind {@link Opcode.Kind#BRANCH}
|
||||
* @param target the target of the branch
|
||||
*/
|
||||
static BranchInstruction of(Opcode op, Label target) {
|
||||
Util.checkKind(op, Opcode.Kind.BRANCH);
|
||||
|
@ -39,5 +39,9 @@ import jdk.internal.classfile.impl.LabelImpl;
|
||||
*/
|
||||
public sealed interface LabelTarget extends PseudoInstruction
|
||||
permits LabelImpl {
|
||||
|
||||
/**
|
||||
* {@return the label corresponding to this target}
|
||||
*/
|
||||
Label label();
|
||||
}
|
||||
|
@ -42,8 +42,15 @@ import jdk.internal.classfile.impl.Util;
|
||||
public sealed interface LoadInstruction extends Instruction
|
||||
permits AbstractInstruction.BoundLoadInstruction,
|
||||
AbstractInstruction.UnboundLoadInstruction {
|
||||
|
||||
/**
|
||||
* {@return the local variable slot to load from}
|
||||
*/
|
||||
int slot();
|
||||
|
||||
/**
|
||||
* {@return the type of the value to be loaded}
|
||||
*/
|
||||
TypeKind typeKind();
|
||||
|
||||
/**
|
||||
|
@ -80,6 +80,12 @@ public sealed interface LocalVariable extends PseudoInstruction
|
||||
*/
|
||||
Label endScope();
|
||||
|
||||
/**
|
||||
* Writes the local variable to the specified writer
|
||||
*
|
||||
* @param buf the writer
|
||||
* @return true if the variable has been written
|
||||
*/
|
||||
boolean writeTo(BufWriter buf);
|
||||
|
||||
/**
|
||||
|
@ -77,6 +77,12 @@ public sealed interface LocalVariableType extends PseudoInstruction
|
||||
*/
|
||||
Label endScope();
|
||||
|
||||
/**
|
||||
* Writes the local variable to the specified writer
|
||||
*
|
||||
* @param buf the writer
|
||||
* @return true if the variable has been written
|
||||
*/
|
||||
boolean writeTo(BufWriter buf);
|
||||
|
||||
/**
|
||||
|
@ -41,6 +41,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
*/
|
||||
public sealed interface ReturnInstruction extends Instruction
|
||||
permits AbstractInstruction.UnboundReturnInstruction {
|
||||
|
||||
/**
|
||||
* {@return the type of the return instruction}
|
||||
*/
|
||||
TypeKind typeKind();
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,15 @@ import jdk.internal.classfile.impl.Util;
|
||||
*/
|
||||
public sealed interface StoreInstruction extends Instruction
|
||||
permits AbstractInstruction.BoundStoreInstruction, AbstractInstruction.UnboundStoreInstruction {
|
||||
|
||||
/**
|
||||
* {@return the local variable slot to store to}
|
||||
*/
|
||||
int slot();
|
||||
|
||||
/**
|
||||
* {@return the type of the value to be stored}
|
||||
*/
|
||||
TypeKind typeKind();
|
||||
|
||||
/**
|
||||
|
@ -43,6 +43,10 @@ import jdk.internal.classfile.impl.Util;
|
||||
public sealed interface TypeCheckInstruction extends Instruction
|
||||
permits AbstractInstruction.BoundTypeCheckInstruction,
|
||||
AbstractInstruction.UnboundTypeCheckInstruction {
|
||||
|
||||
/**
|
||||
* {@return the type against which the instruction checks or casts}
|
||||
*/
|
||||
ClassEntry type();
|
||||
|
||||
/**
|
||||
|
@ -211,7 +211,12 @@
|
||||
* builders for the constructor and {@code main} method, and in turn use the
|
||||
* method builders to create a {@code Code} attribute and use the code builders
|
||||
* to generate the instructions:
|
||||
* {@snippet lang="java" class="PackageSnippets" region="helloWorld"}
|
||||
* {@snippet lang="java" class="PackageSnippets" region="helloWorld1"}
|
||||
* <p>
|
||||
* The convenience methods {@code ClassBuilder.buildMethodBody} allows us to ask
|
||||
* {@link ClassBuilder} to create code builders to build method bodies directly,
|
||||
* skipping the method builder custom lambda:
|
||||
* {@snippet lang="java" class="PackageSnippets" region="helloWorld2"}
|
||||
* <p>
|
||||
* Builders often support multiple ways of expressing the same entity at
|
||||
* different levels of abstraction. For example, the {@code invokevirtual}
|
||||
@ -276,9 +281,13 @@
|
||||
* builder and an element, and an implementation "flatMap"s elements
|
||||
* into the builder. We could express the above as:
|
||||
* {@snippet lang="java" class="PackageSnippets" region="stripDebugMethods2"}
|
||||
* <p>
|
||||
* {@code ClassTransform.dropping} convenience method allow us to simplify the same
|
||||
* transformation construction and express the above as:
|
||||
* {@snippet lang="java" class="PackageSnippets" region="stripDebugMethods3"}
|
||||
*
|
||||
* <h3>Lifting transforms</h3>
|
||||
* While the second example is only slightly shorter than the first, the
|
||||
* While the example using transformations are only slightly shorter, the
|
||||
* advantage of expressing transformation in this way is that the transform
|
||||
* operations can be more easily combined. Suppose we want to redirect
|
||||
* invocations of static methods on {@code Foo} to the corresponding method on
|
||||
@ -301,6 +310,11 @@
|
||||
* ClassTransform ct = ClassTransform.transformingMethods(mt);
|
||||
* }
|
||||
* <p>
|
||||
* or lift the code transform into the class transform directly:
|
||||
* {@snippet lang=java :
|
||||
* ClassTransform ct = ClassTransform.transformingMethodBodiess(fooToBar);
|
||||
* }
|
||||
* <p>
|
||||
* and then transform the classfile:
|
||||
* {@snippet lang=java :
|
||||
* var cc = Classfile.of();
|
||||
|
@ -132,28 +132,41 @@ class PackageSnippets {
|
||||
private static final MethodTypeDesc MTD_void_StringArray = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String.arrayType());
|
||||
private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String);
|
||||
|
||||
void writeHelloWorld() {
|
||||
// @start region="helloWorld"
|
||||
byte[] bytes = Classfile.of().build(CD_Hello, cb -> {
|
||||
cb.withFlags(AccessFlag.PUBLIC);
|
||||
cb.withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC,
|
||||
mb -> mb.withCode(
|
||||
b -> b.aload(0)
|
||||
.invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME,
|
||||
ConstantDescs.MTD_void)
|
||||
.returnInstruction(TypeKind.VoidType)
|
||||
)
|
||||
)
|
||||
.withMethod("main", MTD_void_StringArray,
|
||||
Classfile.ACC_PUBLIC,
|
||||
mb -> mb.withFlags(AccessFlag.STATIC, AccessFlag.PUBLIC)
|
||||
.withCode(
|
||||
b -> b.getstatic(CD_System, "out", CD_PrintStream)
|
||||
.constantInstruction(Opcode.LDC, "Hello World")
|
||||
.invokevirtual(CD_PrintStream, "println", MTD_void_String)
|
||||
.returnInstruction(TypeKind.VoidType)
|
||||
));
|
||||
});
|
||||
void writeHelloWorld1() {
|
||||
// @start region="helloWorld1"
|
||||
byte[] bytes = Classfile.of().build(CD_Hello,
|
||||
clb -> clb.withFlags(Classfile.ACC_PUBLIC)
|
||||
.withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void,
|
||||
Classfile.ACC_PUBLIC,
|
||||
mb -> mb.withCode(
|
||||
cob -> cob.aload(0)
|
||||
.invokespecial(ConstantDescs.CD_Object,
|
||||
ConstantDescs.INIT_NAME, ConstantDescs.MTD_void)
|
||||
.return_()))
|
||||
.withMethod("main", MTD_void_StringArray, Classfile.ACC_PUBLIC + Classfile.ACC_STATIC,
|
||||
mb -> mb.withCode(
|
||||
cob -> cob.getstatic(CD_System, "out", CD_PrintStream)
|
||||
.ldc("Hello World")
|
||||
.invokevirtual(CD_PrintStream, "println", MTD_void_String)
|
||||
.return_())));
|
||||
// @end
|
||||
}
|
||||
|
||||
void writeHelloWorld2() {
|
||||
// @start region="helloWorld2"
|
||||
byte[] bytes = Classfile.of().build(CD_Hello,
|
||||
clb -> clb.withFlags(Classfile.ACC_PUBLIC)
|
||||
.withMethodBody(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void,
|
||||
Classfile.ACC_PUBLIC,
|
||||
cob -> cob.aload(0)
|
||||
.invokespecial(ConstantDescs.CD_Object,
|
||||
ConstantDescs.INIT_NAME, ConstantDescs.MTD_void)
|
||||
.return_())
|
||||
.withMethodBody("main", MTD_void_StringArray, Classfile.ACC_PUBLIC + Classfile.ACC_STATIC,
|
||||
cob -> cob.getstatic(CD_System, "out", CD_PrintStream)
|
||||
.ldc("Hello World")
|
||||
.invokevirtual(CD_PrintStream, "println", MTD_void_String)
|
||||
.return_()));
|
||||
// @end
|
||||
}
|
||||
|
||||
@ -161,13 +174,14 @@ class PackageSnippets {
|
||||
// @start region="stripDebugMethods1"
|
||||
ClassModel classModel = Classfile.of().parse(bytes);
|
||||
byte[] newBytes = Classfile.of().build(classModel.thisClass().asSymbol(),
|
||||
classBuilder -> {
|
||||
for (ClassElement ce : classModel) {
|
||||
if (!(ce instanceof MethodModel mm
|
||||
&& mm.methodName().stringValue().startsWith("debug")))
|
||||
classBuilder.with(ce);
|
||||
}
|
||||
});
|
||||
classBuilder -> {
|
||||
for (ClassElement ce : classModel) {
|
||||
if (!(ce instanceof MethodModel mm
|
||||
&& mm.methodName().stringValue().startsWith("debug"))) {
|
||||
classBuilder.with(ce);
|
||||
}
|
||||
}
|
||||
});
|
||||
// @end
|
||||
}
|
||||
|
||||
@ -182,6 +196,14 @@ class PackageSnippets {
|
||||
// @end
|
||||
}
|
||||
|
||||
void stripDebugMethods3(byte[] bytes) {
|
||||
// @start region="stripDebugMethods3"
|
||||
ClassTransform ct = ClassTransform.dropping(
|
||||
element -> element instanceof MethodModel mm
|
||||
&& mm.methodName().stringValue().startsWith("debug"));
|
||||
// @end
|
||||
}
|
||||
|
||||
void fooToBarTransform() {
|
||||
// @start region="fooToBarTransform"
|
||||
CodeTransform fooToBar = (b, e) -> {
|
||||
@ -199,7 +221,7 @@ class PackageSnippets {
|
||||
CodeTransform instrumentCalls = (b, e) -> {
|
||||
if (e instanceof InvokeInstruction i) {
|
||||
b.getstatic(CD_System, "out", CD_PrintStream)
|
||||
.constantInstruction(Opcode.LDC, i.name().stringValue())
|
||||
.ldc(i.name().stringValue())
|
||||
.invokevirtual(CD_PrintStream, "println", MTD_void_String);
|
||||
}
|
||||
b.with(e);
|
||||
|
Loading…
Reference in New Issue
Block a user