8308753: Class-File API transition to Preview

Reviewed-by: ihse, mchung, vromero
This commit is contained in:
Adam Sotona 2023-12-04 07:07:57 +00:00
parent b9df827adc
commit 2b00ac0d02
681 changed files with 7518 additions and 6502 deletions

View file

@ -52,13 +52,13 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.classfile.AccessFlags;
import jdk.internal.classfile.Attribute;
import jdk.internal.classfile.ClassModel;
import jdk.internal.classfile.ClassTransform;
import jdk.internal.classfile.Classfile;
import jdk.internal.classfile.attribute.ModuleAttribute;
import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.AccessFlags;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassModel;
import java.lang.classfile.ClassTransform;
import java.lang.classfile.ClassFile;
import java.lang.classfile.attribute.ModuleAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import jdk.internal.javac.PreviewFeature;
import jdk.internal.loader.BuiltinClassLoader;
@ -1591,7 +1591,7 @@ public final class Module implements AnnotatedElement {
*/
private Class<?> loadModuleInfoClass(InputStream in) throws IOException {
final String MODULE_INFO = "module-info";
var cc = Classfile.of(Classfile.ConstantPoolSharingOption.NEW_POOL);
var cc = ClassFile.of(ClassFile.ConstantPoolSharingOption.NEW_POOL);
byte[] bytes = cc.transform(cc.parse(in.readAllBytes()), (clb, cle) -> {
switch (cle) {
case AccessFlags af -> clb.withFlags(AccessFlag.INTERFACE,

View file

@ -0,0 +1,115 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.Set;
import jdk.internal.classfile.impl.AccessFlagsImpl;
import java.lang.reflect.AccessFlag;
import jdk.internal.javac.PreviewFeature;
/**
* Models the access flags for a class, method, or field. Delivered as a
* {@link ClassElement}, {@link FieldElement}, or {@link MethodElement}
* when traversing the corresponding model type.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface AccessFlags
extends ClassElement, MethodElement, FieldElement
permits AccessFlagsImpl {
/**
* {@return the access flags, as a bit mask}
*/
int flagsMask();
/**
* {@return the access flags}
*/
Set<AccessFlag> flags();
/**
* {@return whether the specified flag is present} The specified flag
* should be a valid flag for the classfile location associated with this
* element otherwise false is returned.
* @param flag the flag to test
*/
boolean has(AccessFlag flag);
/**
* {@return the classfile location for this element, which is either class,
* method, or field}
*/
AccessFlag.Location location();
/**
* {@return an {@linkplain AccessFlags} for a class}
* @param mask the flags to be set, as a bit mask
*/
static AccessFlags ofClass(int mask) {
return new AccessFlagsImpl(AccessFlag.Location.CLASS, mask);
}
/**
* {@return an {@linkplain AccessFlags} for a class}
* @param flags the flags to be set
*/
static AccessFlags ofClass(AccessFlag... flags) {
return new AccessFlagsImpl(AccessFlag.Location.CLASS, flags);
}
/**
* {@return an {@linkplain AccessFlags} for a field}
* @param mask the flags to be set, as a bit mask
*/
static AccessFlags ofField(int mask) {
return new AccessFlagsImpl(AccessFlag.Location.FIELD, mask);
}
/**
* {@return an {@linkplain AccessFlags} for a field}
* @param flags the flags to be set
*/
static AccessFlags ofField(AccessFlag... flags) {
return new AccessFlagsImpl(AccessFlag.Location.FIELD, flags);
}
/**
* {@return an {@linkplain AccessFlags} for a method}
* @param mask the flags to be set, as a bit mask
*/
static AccessFlags ofMethod(int mask) {
return new AccessFlagsImpl(AccessFlag.Location.METHOD, mask);
}
/**
* {@return an {@linkplain AccessFlags} for a method}
* @param flags the flags to be set
*/
static AccessFlags ofMethod(AccessFlag... flags) {
return new AccessFlagsImpl(AccessFlag.Location.METHOD, flags);
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.AnnotationImpl;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import java.lang.constant.ClassDesc;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models an annotation on a declaration.
*
* @see AnnotationElement
* @see AnnotationValue
* @see RuntimeVisibleAnnotationsAttribute
* @see RuntimeInvisibleAnnotationsAttribute
* @see RuntimeVisibleParameterAnnotationsAttribute
* @see RuntimeInvisibleParameterAnnotationsAttribute
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Annotation
extends WritableElement<Annotation>
permits TypeAnnotation, AnnotationImpl {
/**
* {@return the class of the annotation}
*/
Utf8Entry className();
/**
* {@return the class of the annotation, as a symbolic descriptor}
*/
default ClassDesc classSymbol() {
return ClassDesc.ofDescriptor(className().stringValue());
}
/**
* {@return the elements of the annotation}
*/
List<AnnotationElement> elements();
/**
* {@return an annotation}
* @param annotationClass the class of the annotation
* @param elements the elements of the annotation
*/
static Annotation of(Utf8Entry annotationClass,
List<AnnotationElement> elements) {
return new AnnotationImpl(annotationClass, elements);
}
/**
* {@return an annotation}
* @param annotationClass the class of the annotation
* @param elements the elements of the annotation
*/
static Annotation of(Utf8Entry annotationClass,
AnnotationElement... elements) {
return of(annotationClass, List.of(elements));
}
/**
* {@return an annotation}
* @param annotationClass the class of the annotation
* @param elements the elements of the annotation
*/
static Annotation of(ClassDesc annotationClass,
List<AnnotationElement> elements) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(annotationClass.descriptorString()), elements);
}
/**
* {@return an annotation}
* @param annotationClass the class of the annotation
* @param elements the elements of the annotation
*/
static Annotation of(ClassDesc annotationClass,
AnnotationElement... elements) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(annotationClass.descriptorString()), elements);
}
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.AnnotationImpl;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.javac.PreviewFeature;
/**
* Models a key-value pair of an annotation.
*
* @see Annotation
* @see AnnotationValue
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface AnnotationElement
extends WritableElement<AnnotationElement>
permits AnnotationImpl.AnnotationElementImpl {
/**
* {@return the element name}
*/
Utf8Entry name();
/**
* {@return the element value}
*/
AnnotationValue value();
/**
* {@return an annotation key-value pair}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement of(Utf8Entry name,
AnnotationValue value) {
return new AnnotationImpl.AnnotationElementImpl(name, value);
}
/**
* {@return an annotation key-value pair}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement of(String name,
AnnotationValue value) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(name), value);
}
/**
* {@return an annotation key-value pair for a class-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofClass(String name,
ClassDesc value) {
return of(name, AnnotationValue.ofClass(value));
}
/**
* {@return an annotation key-value pair for a string-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofString(String name,
String value) {
return of(name, AnnotationValue.ofString(value));
}
/**
* {@return an annotation key-value pair for a long-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofLong(String name,
long value) {
return of(name, AnnotationValue.ofLong(value));
}
/**
* {@return an annotation key-value pair for an int-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofInt(String name,
int value) {
return of(name, AnnotationValue.ofInt(value));
}
/**
* {@return an annotation key-value pair for a char-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofChar(String name,
char value) {
return of(name, AnnotationValue.ofChar(value));
}
/**
* {@return an annotation key-value pair for a short-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofShort(String name,
short value) {
return of(name, AnnotationValue.ofShort(value));
}
/**
* {@return an annotation key-value pair for a byte-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofByte(String name,
byte value) {
return of(name, AnnotationValue.ofByte(value));
}
/**
* {@return an annotation key-value pair for a boolean-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofBoolean(String name,
boolean value) {
return of(name, AnnotationValue.ofBoolean(value));
}
/**
* {@return an annotation key-value pair for a double-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofDouble(String name,
double value) {
return of(name, AnnotationValue.ofDouble(value));
}
/**
* {@return an annotation key-value pair for a float-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofFloat(String name,
float value) {
return of(name, AnnotationValue.ofFloat(value));
}
/**
* {@return an annotation key-value pair for an annotation-valued annotation}
* @param name the name of the key
* @param value the associated value
*/
static AnnotationElement ofAnnotation(String name,
Annotation value) {
return of(name, AnnotationValue.ofAnnotation(value));
}
/**
* {@return an annotation key-value pair for an array-valued annotation}
* @param name the name of the key
* @param values the associated values
*/
static AnnotationElement ofArray(String name,
AnnotationValue... values) {
return of(name, AnnotationValue.ofArray(values));
}
}

View file

@ -0,0 +1,545 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.constantpool.AnnotationConstantValueEntry;
import java.lang.classfile.constantpool.DoubleEntry;
import java.lang.classfile.constantpool.FloatEntry;
import java.lang.classfile.constantpool.IntegerEntry;
import java.lang.classfile.constantpool.LongEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.AnnotationImpl;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDesc;
import java.util.ArrayList;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models the value of a key-value pair of an annotation.
*
* @see Annotation
* @see AnnotationElement
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface AnnotationValue extends WritableElement<AnnotationValue>
permits AnnotationValue.OfAnnotation, AnnotationValue.OfArray,
AnnotationValue.OfConstant, AnnotationValue.OfClass,
AnnotationValue.OfEnum {
/**
* Models an annotation-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfAnnotation extends AnnotationValue
permits AnnotationImpl.OfAnnotationImpl {
/** {@return the annotation} */
Annotation annotation();
}
/**
* Models an array-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfArray extends AnnotationValue
permits AnnotationImpl.OfArrayImpl {
/** {@return the values} */
List<AnnotationValue> values();
}
/**
* Models a constant-valued element
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfConstant extends AnnotationValue
permits AnnotationValue.OfString, AnnotationValue.OfDouble,
AnnotationValue.OfFloat, AnnotationValue.OfLong,
AnnotationValue.OfInteger, AnnotationValue.OfShort,
AnnotationValue.OfCharacter, AnnotationValue.OfByte,
AnnotationValue.OfBoolean, AnnotationImpl.OfConstantImpl {
/** {@return the constant} */
AnnotationConstantValueEntry constant();
/** {@return the constant} */
ConstantDesc constantValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfString extends AnnotationValue.OfConstant
permits AnnotationImpl.OfStringImpl {
/** {@return the constant} */
String stringValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfDouble extends AnnotationValue.OfConstant
permits AnnotationImpl.OfDoubleImpl {
/** {@return the constant} */
double doubleValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfFloat extends AnnotationValue.OfConstant
permits AnnotationImpl.OfFloatImpl {
/** {@return the constant} */
float floatValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfLong extends AnnotationValue.OfConstant
permits AnnotationImpl.OfLongImpl {
/** {@return the constant} */
long longValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfInteger extends AnnotationValue.OfConstant
permits AnnotationImpl.OfIntegerImpl {
/** {@return the constant} */
int intValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfShort extends AnnotationValue.OfConstant
permits AnnotationImpl.OfShortImpl {
/** {@return the constant} */
short shortValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfCharacter extends AnnotationValue.OfConstant
permits AnnotationImpl.OfCharacterImpl {
/** {@return the constant} */
char charValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfByte extends AnnotationValue.OfConstant
permits AnnotationImpl.OfByteImpl {
/** {@return the constant} */
byte byteValue();
}
/**
* Models a constant-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfBoolean extends AnnotationValue.OfConstant
permits AnnotationImpl.OfBooleanImpl {
/** {@return the constant} */
boolean booleanValue();
}
/**
* Models a class-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfClass extends AnnotationValue
permits AnnotationImpl.OfClassImpl {
/** {@return the class name} */
Utf8Entry className();
/** {@return the class symbol} */
default ClassDesc classSymbol() {
return ClassDesc.ofDescriptor(className().stringValue());
}
}
/**
* Models an enum-valued element
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OfEnum extends AnnotationValue
permits AnnotationImpl.OfEnumImpl {
/** {@return the enum class name} */
Utf8Entry className();
/** {@return the enum class symbol} */
default ClassDesc classSymbol() {
return ClassDesc.ofDescriptor(className().stringValue());
}
/** {@return the enum constant name} */
Utf8Entry constantName();
}
/**
* {@return the tag character for this type as per {@jvms 4.7.16.1}}
*/
char tag();
/**
* {@return an annotation element for a enum-valued element}
* @param className the name of the enum class
* @param constantName the name of the enum constant
*/
static OfEnum ofEnum(Utf8Entry className,
Utf8Entry constantName) {
return new AnnotationImpl.OfEnumImpl(className, constantName);
}
/**
* {@return an annotation element for a enum-valued element}
* @param className the name of the enum class
* @param constantName the name of the enum constant
*/
static OfEnum ofEnum(ClassDesc className, String constantName) {
return ofEnum(TemporaryConstantPool.INSTANCE.utf8Entry(className.descriptorString()),
TemporaryConstantPool.INSTANCE.utf8Entry(constantName));
}
/**
* {@return an annotation element for a class-valued element}
* @param className the name of the enum class
*/
static OfClass ofClass(Utf8Entry className) {
return new AnnotationImpl.OfClassImpl(className);
}
/**
* {@return an annotation element for a class-valued element}
* @param className the name of the enum class
*/
static OfClass ofClass(ClassDesc className) {
return ofClass(TemporaryConstantPool.INSTANCE.utf8Entry(className.descriptorString()));
}
/**
* {@return an annotation element for a string-valued element}
* @param value the string
*/
static OfConstant ofString(Utf8Entry value) {
return new AnnotationImpl.OfStringImpl(value);
}
/**
* {@return an annotation element for a string-valued element}
* @param value the string
*/
static OfConstant ofString(String value) {
return ofString(TemporaryConstantPool.INSTANCE.utf8Entry(value));
}
/**
* {@return an annotation element for a double-valued element}
* @param value the double value
*/
static OfConstant ofDouble(DoubleEntry value) {
return new AnnotationImpl.OfDoubleImpl(value);
}
/**
* {@return an annotation element for a double-valued element}
* @param value the double value
*/
static OfConstant ofDouble(double value) {
return ofDouble(TemporaryConstantPool.INSTANCE.doubleEntry(value));
}
/**
* {@return an annotation element for a float-valued element}
* @param value the float value
*/
static OfConstant ofFloat(FloatEntry value) {
return new AnnotationImpl.OfFloatImpl(value);
}
/**
* {@return an annotation element for a float-valued element}
* @param value the float value
*/
static OfConstant ofFloat(float value) {
return ofFloat(TemporaryConstantPool.INSTANCE.floatEntry(value));
}
/**
* {@return an annotation element for a long-valued element}
* @param value the long value
*/
static OfConstant ofLong(LongEntry value) {
return new AnnotationImpl.OfLongImpl(value);
}
/**
* {@return an annotation element for a long-valued element}
* @param value the long value
*/
static OfConstant ofLong(long value) {
return ofLong(TemporaryConstantPool.INSTANCE.longEntry(value));
}
/**
* {@return an annotation element for an int-valued element}
* @param value the int value
*/
static OfConstant ofInt(IntegerEntry value) {
return new AnnotationImpl.OfIntegerImpl(value);
}
/**
* {@return an annotation element for an int-valued element}
* @param value the int value
*/
static OfConstant ofInt(int value) {
return ofInt(TemporaryConstantPool.INSTANCE.intEntry(value));
}
/**
* {@return an annotation element for a short-valued element}
* @param value the short value
*/
static OfConstant ofShort(IntegerEntry value) {
return new AnnotationImpl.OfShortImpl(value);
}
/**
* {@return an annotation element for a short-valued element}
* @param value the short value
*/
static OfConstant ofShort(short value) {
return ofShort(TemporaryConstantPool.INSTANCE.intEntry(value));
}
/**
* {@return an annotation element for a char-valued element}
* @param value the char value
*/
static OfConstant ofChar(IntegerEntry value) {
return new AnnotationImpl.OfCharacterImpl(value);
}
/**
* {@return an annotation element for a char-valued element}
* @param value the char value
*/
static OfConstant ofChar(char value) {
return ofChar(TemporaryConstantPool.INSTANCE.intEntry(value));
}
/**
* {@return an annotation element for a byte-valued element}
* @param value the byte value
*/
static OfConstant ofByte(IntegerEntry value) {
return new AnnotationImpl.OfByteImpl(value);
}
/**
* {@return an annotation element for a byte-valued element}
* @param value the byte value
*/
static OfConstant ofByte(byte value) {
return ofByte(TemporaryConstantPool.INSTANCE.intEntry(value));
}
/**
* {@return an annotation element for a boolean-valued element}
* @param value the boolean value
*/
static OfConstant ofBoolean(IntegerEntry value) {
return new AnnotationImpl.OfBooleanImpl(value);
}
/**
* {@return an annotation element for a boolean-valued element}
* @param value the boolean value
*/
static OfConstant ofBoolean(boolean value) {
int i = value ? 1 : 0;
return ofBoolean(TemporaryConstantPool.INSTANCE.intEntry(i));
}
/**
* {@return an annotation element for an annotation-valued element}
* @param value the annotation
*/
static OfAnnotation ofAnnotation(Annotation value) {
return new AnnotationImpl.OfAnnotationImpl(value);
}
/**
* {@return an annotation element for an array-valued element}
* @param values the values
*/
static OfArray ofArray(List<AnnotationValue> values) {
return new AnnotationImpl.OfArrayImpl(values);
}
/**
* {@return an annotation element for an array-valued element}
* @param values the values
*/
static OfArray ofArray(AnnotationValue... values) {
return ofArray(List.of(values));
}
/**
* {@return an annotation element} The {@code value} parameter must be
* a primitive, a wrapper of primitive, a String, a ClassDesc, an enum
* constant, or an array of one of these.
*
* @param value the annotation value
* @throws IllegalArgumentException when the {@code value} parameter is not
* a primitive, a wrapper of primitive, a String, a ClassDesc,
* an enum constant, or an array of one of these.
*/
static AnnotationValue of(Object value) {
if (value instanceof String s) {
return ofString(s);
} else if (value instanceof Byte b) {
return ofByte(b);
} else if (value instanceof Boolean b) {
return ofBoolean(b);
} else if (value instanceof Short s) {
return ofShort(s);
} else if (value instanceof Character c) {
return ofChar(c);
} else if (value instanceof Integer i) {
return ofInt(i);
} else if (value instanceof Long l) {
return ofLong(l);
} else if (value instanceof Float f) {
return ofFloat(f);
} else if (value instanceof Double d) {
return ofDouble(d);
} else if (value instanceof ClassDesc clsDesc) {
return ofClass(clsDesc);
} else if (value instanceof byte[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofByte(el));
}
return ofArray(els);
} else if (value instanceof boolean[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofBoolean(el));
}
return ofArray(els);
} else if (value instanceof short[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofShort(el));
}
return ofArray(els);
} else if (value instanceof char[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofChar(el));
}
return ofArray(els);
} else if (value instanceof int[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofInt(el));
}
return ofArray(els);
} else if (value instanceof long[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofLong(el));
}
return ofArray(els);
} else if (value instanceof float[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofFloat(el));
}
return ofArray(els);
} else if (value instanceof double[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(ofDouble(el));
}
return ofArray(els);
} else if (value instanceof Object[] arr) {
var els = new ArrayList<AnnotationValue>(arr.length);
for (var el : arr) {
els.add(of(el));
}
return ofArray(els);
} else if (value instanceof Enum<?> e) {
return ofEnum(ClassDesc.ofDescriptor(e.getDeclaringClass().descriptorString()), e.name());
}
throw new IllegalArgumentException("Illegal annotation constant value type " + (value == null ? null : value.getClass()));
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.AnnotationDefaultAttribute;
import java.lang.classfile.attribute.BootstrapMethodsAttribute;
import java.lang.classfile.attribute.CharacterRangeTableAttribute;
import java.lang.classfile.attribute.CodeAttribute;
import java.lang.classfile.attribute.CompilationIDAttribute;
import java.lang.classfile.attribute.ConstantValueAttribute;
import java.lang.classfile.attribute.DeprecatedAttribute;
import java.lang.classfile.attribute.EnclosingMethodAttribute;
import java.lang.classfile.attribute.ExceptionsAttribute;
import java.lang.classfile.attribute.InnerClassesAttribute;
import java.lang.classfile.attribute.LineNumberTableAttribute;
import java.lang.classfile.attribute.LocalVariableTableAttribute;
import java.lang.classfile.attribute.LocalVariableTypeTableAttribute;
import java.lang.classfile.attribute.MethodParametersAttribute;
import java.lang.classfile.attribute.ModuleAttribute;
import java.lang.classfile.attribute.ModuleHashesAttribute;
import java.lang.classfile.attribute.ModuleMainClassAttribute;
import java.lang.classfile.attribute.ModulePackagesAttribute;
import java.lang.classfile.attribute.ModuleResolutionAttribute;
import java.lang.classfile.attribute.ModuleTargetAttribute;
import java.lang.classfile.attribute.NestHostAttribute;
import java.lang.classfile.attribute.NestMembersAttribute;
import java.lang.classfile.attribute.PermittedSubclassesAttribute;
import java.lang.classfile.attribute.RecordAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.classfile.attribute.SourceDebugExtensionAttribute;
import java.lang.classfile.attribute.SourceFileAttribute;
import java.lang.classfile.attribute.SourceIDAttribute;
import java.lang.classfile.attribute.StackMapTableAttribute;
import java.lang.classfile.attribute.SyntheticAttribute;
import java.lang.classfile.attribute.UnknownAttribute;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a classfile attribute {@jvms 4.7}. Many, though not all, subtypes of
* {@linkplain Attribute} will implement {@link ClassElement}, {@link
* MethodElement}, {@link FieldElement}, or {@link CodeElement}; attributes that
* are also elements will be delivered when traversing the elements of the
* corresponding model type. Additionally, all attributes are accessible
* directly from the corresponding model type through {@link
* AttributedElement#findAttribute(AttributeMapper)}.
* @param <A> the attribute type
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Attribute<A extends Attribute<A>>
extends WritableElement<A>
permits AnnotationDefaultAttribute, BootstrapMethodsAttribute,
CharacterRangeTableAttribute, CodeAttribute, CompilationIDAttribute,
ConstantValueAttribute, DeprecatedAttribute, EnclosingMethodAttribute,
ExceptionsAttribute, InnerClassesAttribute, LineNumberTableAttribute,
LocalVariableTableAttribute, LocalVariableTypeTableAttribute,
MethodParametersAttribute, ModuleAttribute, ModuleHashesAttribute,
ModuleMainClassAttribute, ModulePackagesAttribute, ModuleResolutionAttribute,
ModuleTargetAttribute, NestHostAttribute, NestMembersAttribute,
PermittedSubclassesAttribute,
RecordAttribute, RuntimeInvisibleAnnotationsAttribute,
RuntimeInvisibleParameterAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute,
RuntimeVisibleAnnotationsAttribute, RuntimeVisibleParameterAnnotationsAttribute,
RuntimeVisibleTypeAnnotationsAttribute, SignatureAttribute,
SourceDebugExtensionAttribute, SourceFileAttribute, SourceIDAttribute,
StackMapTableAttribute, SyntheticAttribute,
UnknownAttribute, BoundAttribute, UnboundAttribute, CustomAttribute {
/**
* {@return the name of the attribute}
*/
String attributeName();
/**
* {@return the {@link AttributeMapper} associated with this attribute}
*/
AttributeMapper<A> attributeMapper();
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.javac.PreviewFeature;
/**
* Bidirectional mapper between the classfile representation of an attribute and
* how that attribute is modeled in the API. The attribute mapper is used
* to parse the classfile representation into a model, and to write the model
* representation back to a classfile. For each standard attribute, there is a
* predefined attribute mapper defined in {@link Attributes}. For nonstandard
* attributes, clients can define their own {@linkplain AttributeMapper}.
* Classes that model nonstandard attributes should extend {@link
* CustomAttribute}.
* @param <A> the attribute type
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public interface AttributeMapper<A> {
/**
* Attribute stability indicator
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
enum AttributeStability {
/**
* The attribute contains only pure data, such as timestamps, and can always be bulk-copied.
*/
STATELESS,
/**
* The attribute contains only pure data and CP refs, so can be bulk-copied when CP sharing is in effect,
* and need to be exploded and rewritten when CP sharing is not in effect.
*/
CP_REFS,
/**
* The attribute may contain labels, so need to be exploded and rewritten when the Code array is perturbed.
*/
LABELS,
/**
* The attribute may contain indexes into structured not managed by the library (type variable lists, etc)
* and so we consult the {@link ClassFile.AttributesProcessingOption} option to determine whether to preserve
* or drop it during transformation.
*/
UNSTABLE,
/**
* The attribute is completely unknown and so we consult the {@link ClassFile.AttributesProcessingOption} option
* to determine whether to preserve or drop it during transformation.
*/
UNKNOWN
}
/**
* {@return the name of the attribute}
*/
String name();
/**
* Create an {@link Attribute} instance from a classfile.
*
* @param enclosing The class, method, field, or code attribute in which
* this attribute appears
* @param cf The {@link ClassReader} describing the classfile to read from
* @param pos The offset into the classfile at which the attribute starts
* @return the new attribute
*/
A readAttribute(AttributedElement enclosing, ClassReader cf, int pos);
/**
* Write an {@link Attribute} instance to a classfile.
*
* @param buf The {@link BufWriter} to which the attribute should be written
* @param attr The attribute to write
*/
void writeAttribute(BufWriter buf, A attr);
/**
* {@return whether this attribute may appear more than once in a given location}
*
* @implSpec The default implementation returns {@code false}
*/
default boolean allowMultiple() {
return false;
}
/**
* {@return attribute stability indicator}
*/
AttributeStability stability();
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.lang.classfile.attribute.RecordComponentInfo;
import jdk.internal.classfile.impl.AbstractUnboundModel;
import jdk.internal.javac.PreviewFeature;
/**
* A {@link ClassFileElement} describing an entity that has attributes, such
* as a class, field, method, code attribute, or record component.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface AttributedElement extends ClassFileElement
permits ClassModel, CodeModel, FieldModel, MethodModel,
RecordComponentInfo, AbstractUnboundModel {
/**
* {@return the attributes of this element}
*/
List<Attribute<?>> attributes();
/**
* Finds an attribute by name.
* @param attr the attribute mapper
* @param <T> the type of the attribute
* @return the attribute, or an empty {@linkplain Optional} if the attribute
* is not present
*/
default <T extends Attribute<T>> Optional<T> findAttribute(AttributeMapper<T> attr) {
for (Attribute<?> la : attributes()) {
if (la.attributeMapper() == attr) {
@SuppressWarnings("unchecked")
var res = Optional.of((T) la);
return res;
}
}
return Optional.empty();
}
/**
* Finds one or more attributes by name.
* @param attr the attribute mapper
* @param <T> the type of the attribute
* @return the attributes, or an empty {@linkplain List} if the attribute
* is not present
*/
default <T extends Attribute<T>> List<T> findAttributes(AttributeMapper<T> attr) {
var list = new ArrayList<T>();
for (var a : attributes()) {
if (a.attributeMapper() == attr) {
@SuppressWarnings("unchecked")
T t = (T)a;
list.add(t);
}
}
return list;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.List;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.LoadableConstantEntry;
import java.lang.classfile.constantpool.MethodHandleEntry;
import jdk.internal.classfile.impl.BootstrapMethodEntryImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models an entry in the bootstrap method table. The bootstrap method table
* is stored in the {@code BootstrapMethods} attribute, but is modeled by
* the {@link ConstantPool}, since the bootstrap method table is logically
* part of the constant pool.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface BootstrapMethodEntry
extends WritableElement<BootstrapMethodEntry>
permits BootstrapMethodEntryImpl {
/**
* {@return the constant pool associated with this entry}
*/
ConstantPool constantPool();
/**
* {@return the index into the bootstrap method table corresponding to this entry}
*/
int bsmIndex();
/**
* {@return the bootstrap method}
*/
MethodHandleEntry bootstrapMethod();
/**
* {@return the bootstrap arguments}
*/
List<LoadableConstantEntry> arguments();
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.nio.ByteBuffer;
import java.util.List;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.PoolEntry;
import jdk.internal.classfile.impl.BufWriterImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Supports writing portions of a classfile to a growable buffer. Methods
* are provided to write various standard entities (e.g., {@code u2}, {@code u4})
* to the end of the buffer, as well as to create constant pool entries.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface BufWriter
permits BufWriterImpl {
/** {@return the constant pool builder associated with this buffer} */
ConstantPoolBuilder constantPool();
/**
* {@return whether the provided constant pool is index-compatible with this
* one} This may be because they are the same constant pool, or because this
* constant pool was copied from the other.
*
* @param other the other constant pool
*/
boolean canWriteDirect(ConstantPool other);
/**
* Ensure that the buffer has at least {@code freeBytes} bytes of unused space
* @param freeBytes the number of bytes to reserve
*/
void reserveSpace(int freeBytes);
/**
* Write an unsigned byte to the buffer
*
* @param x the byte value
*/
void writeU1(int x);
/**
* Write an unsigned short to the buffer
*
* @param x the short value
*/
void writeU2(int x);
/**
* Write a signed int to the buffer
*
* @param x the int value
*/
void writeInt(int x);
/**
* Write a float value to the buffer
*
* @param x the float value
*/
void writeFloat(float x);
/**
* Write a long value to the buffer
*
* @param x the long value
*/
void writeLong(long x);
/**
* Write a double value to the buffer
*
* @param x the int value
*/
void writeDouble(double x);
/**
* Write the contents of a byte array to the buffer
*
* @param arr the byte array
*/
void writeBytes(byte[] arr);
/**
* Write the contents of another {@link BufWriter} to the buffer
*
* @param other the other {@linkplain BufWriter}
*/
void writeBytes(BufWriter other);
/**
* Write a range of a byte array to the buffer
*
* @param arr the byte array
* @param start the offset within the byte array of the range
* @param length the length of the range
*/
void writeBytes(byte[] arr, int start, int length);
/**
* Patch a previously written integer value. Depending on the specified
* size, the entire value, or the low 1 or 2 bytes, may be written.
*
* @param offset the offset at which to patch
* @param size the size of the integer value being written, in bytes
* @param value the integer value
*/
void patchInt(int offset, int size, int value);
/**
* Write a 1, 2, 4, or 8 byte integer value to the buffer. Depending on
* the specified size, the entire value, or the low 1, 2, or 4 bytes, may
* be written.
*
* @param intSize the size of the integer value being written, in bytes
* @param intValue the integer value
*/
void writeIntBytes(int intSize, long intValue);
/**
* Write the index of the specified constant pool entry, as a {@code u2},
* to the buffer
*
* @param entry the constant pool entry
* @throws NullPointerException if the entry is null
*/
void writeIndex(PoolEntry entry);
/**
* Write the index of the specified constant pool entry, as a {@code u2},
* to the buffer, or zero if the entry is null
*
* @param entry the constant pool entry
*/
void writeIndexOrZero(PoolEntry entry);
/**
* Write a list of entities to the buffer. The length of the list is
* written as a {@code u2}, followed by the bytes corresponding to each
* element in the list. Writing of the entities is delegated to the entry.
*
* @param list the entities
* @param <T> the type of entity
*/
<T extends WritableElement<?>> void writeList(List<T> list);
/**
* Write a list of constant pool entry indexes to the buffer. The length
* of the list is written as a {@code u2}, followed by a {@code u2} for each
* entry in the list.
*
* @param list the list of entries
*/
void writeListIndices(List<? extends PoolEntry> list);
/**
* {@return the number of bytes that have been written to the buffer}
*/
int size();
/**
* {@return a {@link java.nio.ByteBuffer ByteBuffer} view of the bytes in the buffer}
*/
ByteBuffer asByteBuffer();
/**
* Copy the contents of the buffer into a byte array.
*
* @param array the byte array
* @param bufferOffset the offset into the array at which to write the
* contents of the buffer
*/
void copyTo(byte[] array, int bufferOffset);
}

View file

@ -0,0 +1,304 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.ChainedClassBuilder;
import jdk.internal.classfile.impl.DirectClassBuilder;
import jdk.internal.classfile.impl.Util;
import java.lang.reflect.AccessFlag;
import java.lang.classfile.attribute.CodeAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A builder for classfiles. Builders are not created directly; they are passed
* to handlers by methods such as {@link ClassFile#build(ClassDesc, Consumer)}
* or to class transforms. The elements of a classfile can be specified
* abstractly (by passing a {@link ClassElement} to {@link #with(ClassFileElement)})
* or concretely by calling the various {@code withXxx} methods.
*
* @see ClassTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassBuilder
extends ClassFileBuilder<ClassElement, ClassBuilder>
permits ChainedClassBuilder, DirectClassBuilder {
/**
* {@return the {@link ClassModel} representing the class being transformed,
* if this class builder represents the transformation of some {@link ClassModel}}
*/
Optional<ClassModel> original();
/**
* Sets the classfile version.
* @param major the major version number
* @param minor the minor version number
* @return this builder
*/
default ClassBuilder withVersion(int major, int minor) {
return with(ClassFileVersion.of(major, minor));
}
/**
* Sets the classfile access flags.
* @param flags the access flags, as a bit mask
* @return this builder
*/
default ClassBuilder withFlags(int flags) {
return with(AccessFlags.ofClass(flags));
}
/**
* Sets the classfile access flags.
* @param flags the access flags
* @return this builder
*/
default ClassBuilder withFlags(AccessFlag... flags) {
return with(AccessFlags.ofClass(flags));
}
/**
* Sets the superclass of this class.
* @param superclassEntry the superclass
* @return this builder
*/
default ClassBuilder withSuperclass(ClassEntry superclassEntry) {
return with(Superclass.of(superclassEntry));
}
/**
* Sets the superclass of this class.
* @param desc the superclass
* @return this builder
* @throws IllegalArgumentException if {@code desc} represents a primitive type
*/
default ClassBuilder withSuperclass(ClassDesc desc) {
return withSuperclass(constantPool().classEntry(desc));
}
/**
* Sets the interfaces of this class.
* @param interfaces the interfaces
* @return this builder
*/
default ClassBuilder withInterfaces(List<ClassEntry> interfaces) {
return with(Interfaces.of(interfaces));
}
/**
* Sets the interfaces of this class.
* @param interfaces the interfaces
* @return this builder
*/
default ClassBuilder withInterfaces(ClassEntry... interfaces) {
return withInterfaces(List.of(interfaces));
}
/**
* Sets the interfaces of this class.
* @param interfaces the interfaces
* @return this builder
*/
default ClassBuilder withInterfaceSymbols(List<ClassDesc> interfaces) {
return withInterfaces(Util.entryList(interfaces));
}
/**
* Sets the interfaces of this class.
* @param interfaces the interfaces
* @return this builder
*/
default ClassBuilder withInterfaceSymbols(ClassDesc... interfaces) {
// List view, since ref to interfaces is temporary
return withInterfaceSymbols(Arrays.asList(interfaces));
}
/**
* Adds a field.
* @param name the name of the field
* @param descriptor the field descriptor
* @param handler handler which receives a {@link FieldBuilder} which can
* further define the contents of the field
* @return this builder
*/
ClassBuilder withField(Utf8Entry name,
Utf8Entry descriptor,
Consumer<? super FieldBuilder> handler);
/**
* Adds a field.
* @param name the name of the field
* @param descriptor the field descriptor
* @param flags the access flags for this field
* @return this builder
*/
default ClassBuilder withField(Utf8Entry name,
Utf8Entry descriptor,
int flags) {
return withField(name, descriptor, fb -> fb.withFlags(flags));
}
/**
* Adds a field.
* @param name the name of the field
* @param descriptor the field descriptor
* @param handler handler which receives a {@link FieldBuilder} which can
* further define the contents of the field
* @return this builder
*/
default ClassBuilder withField(String name,
ClassDesc descriptor,
Consumer<? super FieldBuilder> handler) {
return withField(constantPool().utf8Entry(name),
constantPool().utf8Entry(descriptor),
handler);
}
/**
* Adds a field.
* @param name the name of the field
* @param descriptor the field descriptor
* @param flags the access flags for this field
* @return this builder
*/
default ClassBuilder withField(String name,
ClassDesc descriptor,
int flags) {
return withField(name, descriptor, fb -> fb.withFlags(flags));
}
/**
* Adds a field by transforming a field from another class.
*
* @implNote
* <p>This method behaves as if:
* {@snippet lang=java :
* withField(field.fieldName(), field.fieldType(),
* b -> b.transformField(field, transform));
* }
*
* @param field the field to be transformed
* @param transform the transform to apply to the field
* @return this builder
*/
ClassBuilder transformField(FieldModel field, FieldTransform transform);
/**
* Adds a method.
* @param name the name of the method
* @param descriptor the method descriptor
* @param methodFlags the access flags
* @param handler handler which receives a {@link MethodBuilder} which can
* further define the contents of the method
* @return this builder
*/
ClassBuilder withMethod(Utf8Entry name,
Utf8Entry descriptor,
int methodFlags,
Consumer<? super MethodBuilder> handler);
/**
* Adds a method, with only a {@code Code} attribute.
*
* @param name the name of the method
* @param descriptor the method descriptor
* @param methodFlags the access flags
* @param handler handler which receives a {@link CodeBuilder} which can
* define the contents of the method body
* @return this builder
*/
default ClassBuilder withMethodBody(Utf8Entry name,
Utf8Entry descriptor,
int methodFlags,
Consumer<? super CodeBuilder> handler) {
return withMethod(name, descriptor, methodFlags, mb -> mb.withCode(handler));
}
/**
* Adds a method.
* @param name the name of the method
* @param descriptor the method descriptor
* @param methodFlags the access flags
* @param handler handler which receives a {@link MethodBuilder} which can
* further define the contents of the method
* @return this builder
*/
default ClassBuilder withMethod(String name,
MethodTypeDesc descriptor,
int methodFlags,
Consumer<? super MethodBuilder> handler) {
return withMethod(constantPool().utf8Entry(name),
constantPool().utf8Entry(descriptor),
methodFlags,
handler);
}
/**
* Adds a method, with only a {@link CodeAttribute}.
* @param name the name of the method
* @param descriptor the method descriptor
* @param methodFlags the access flags
* @param handler handler which receives a {@link CodeBuilder} which can
* define the contents of the method body
* @return this builder
*/
default ClassBuilder withMethodBody(String name,
MethodTypeDesc descriptor,
int methodFlags,
Consumer<? super CodeBuilder> handler) {
return withMethodBody(constantPool().utf8Entry(name),
constantPool().utf8Entry(descriptor),
methodFlags,
handler);
}
/**
* Adds a method by transforming a method from another class.
*
* @implNote
* <p>This method behaves as if:
* {@snippet lang=java :
* withMethod(method.methodName(), method.methodType(),
* b -> b.transformMethod(method, transform));
* }
* @param method the method to be transformed
* @param transform the transform to apply to the method
* @return this builder
*/
ClassBuilder transformMethod(MethodModel method, MethodTransform transform);
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.CompilationIDAttribute;
import java.lang.classfile.attribute.DeprecatedAttribute;
import java.lang.classfile.attribute.EnclosingMethodAttribute;
import java.lang.classfile.attribute.InnerClassesAttribute;
import java.lang.classfile.attribute.ModuleAttribute;
import java.lang.classfile.attribute.ModuleHashesAttribute;
import java.lang.classfile.attribute.ModuleMainClassAttribute;
import java.lang.classfile.attribute.ModulePackagesAttribute;
import java.lang.classfile.attribute.ModuleResolutionAttribute;
import java.lang.classfile.attribute.ModuleTargetAttribute;
import java.lang.classfile.attribute.NestHostAttribute;
import java.lang.classfile.attribute.NestMembersAttribute;
import java.lang.classfile.attribute.PermittedSubclassesAttribute;
import java.lang.classfile.attribute.RecordAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.classfile.attribute.SourceDebugExtensionAttribute;
import java.lang.classfile.attribute.SourceFileAttribute;
import java.lang.classfile.attribute.SourceIDAttribute;
import java.lang.classfile.attribute.SyntheticAttribute;
import java.lang.classfile.attribute.UnknownAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A marker interface for elements that can appear when traversing
* a {@link ClassModel} or be presented to a {@link ClassBuilder}.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassElement extends ClassFileElement
permits AccessFlags, Superclass, Interfaces, ClassFileVersion,
FieldModel, MethodModel,
CustomAttribute, CompilationIDAttribute, DeprecatedAttribute,
EnclosingMethodAttribute, InnerClassesAttribute,
ModuleAttribute, ModuleHashesAttribute, ModuleMainClassAttribute,
ModulePackagesAttribute, ModuleResolutionAttribute, ModuleTargetAttribute,
NestHostAttribute, NestMembersAttribute, PermittedSubclassesAttribute,
RecordAttribute,
RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute,
RuntimeVisibleAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute,
SignatureAttribute, SourceDebugExtensionAttribute,
SourceFileAttribute, SourceIDAttribute, SyntheticAttribute, UnknownAttribute {
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.util.function.Consumer;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import jdk.internal.javac.PreviewFeature;
/**
* A builder for a classfile or portion of a classfile. Builders are rarely
* created directly; they are passed to handlers by methods such as
* {@link ClassFile#build(ClassDesc, Consumer)} or to transforms.
* Elements of the newly built entity can be specified
* 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
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassFileBuilder<E extends ClassFileElement, B extends ClassFileBuilder<E, B>>
extends Consumer<E> permits ClassBuilder, FieldBuilder, MethodBuilder, CodeBuilder {
/**
* Integrate the {@link ClassFileElement} into the entity being built.
* @param e the element
*/
@Override
default void accept(E e) {
with(e);
}
/**
* Integrate the {@link ClassFileElement} into the entity being built.
* @param e the element
* @return this builder
*/
B with(E e);
/**
* {@return the constant pool builder associated with this builder}
*/
ConstantPoolBuilder constantPool();
/**
* {@return whether the provided constant pool is compatible with this builder}
* @param source the constant pool to test compatibility with
*/
default boolean canWriteDirect(ConstantPool source) {
return constantPool().canWriteDirect(source);
}
/**
* Apply a transform to a model, directing results to this builder.
* @param model the model to transform
* @param transform the transform to apply
*/
default void transform(CompoundElement<E> model, ClassFileTransform<?, E, B> transform) {
@SuppressWarnings("unchecked")
B builder = (B) this;
var resolved = transform.resolve(builder);
resolved.startHandler().run();
model.forEachElement(resolved.consumer());
resolved.endHandler().run();
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.javac.PreviewFeature;
/**
* Immutable model for a portion of (or the entirety of) a classfile. Elements
* that model parts of the classfile that have attributes will implement {@link
* AttributedElement}; elements that model complex parts of the classfile that
* themselves contain their own child elements will implement {@link
* CompoundElement}. Elements specific to various locations in the classfile
* will implement {@link ClassElement}, {@link MethodElement}, etc.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassFileElement
permits AttributedElement, CompoundElement, WritableElement,
ClassElement, CodeElement, FieldElement, MethodElement {
}

View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A transformation on streams of elements. Transforms are used during
* transformation of classfile entities; a transform is provided to a method like
* {@link ClassFile#transform(ClassModel, ClassTransform)}, and the elements of the class,
* along with a builder, are presented to the transform.
*
* <p>The subtypes of {@linkplain
* ClassFileTransform} (e.g., {@link ClassTransform}) are functional interfaces
* that accept an element and a corresponding builder. Since any element can be
* reproduced on the builder via {@link ClassBuilder#with(ClassFileElement)}, a
* transform can easily leave elements in place, remove them, replace them, or
* augment them with other elements. This enables localized transforms to be
* represented concisely.
*
* <p>Transforms also have an {@link #atEnd(ClassFileBuilder)} method, for
* which the default implementation does nothing, so that a transform can
* perform additional building after the stream of elements is exhausted.
*
* <p>Transforms can be chained together via the {@link
* #andThen(ClassFileTransform)} method, so that the output of one becomes the
* input to another. This allows smaller units of transformation to be captured
* and reused.
*
* <p>Some transforms are stateful; for example, a transform that injects an
* annotation on a class may watch for the {@link RuntimeVisibleAnnotationsAttribute}
* element and transform it if found, but if it is not found, will generate a
* {@linkplain RuntimeVisibleAnnotationsAttribute} element containing the
* injected annotation from the {@linkplain #atEnd(ClassFileBuilder)} handler.
* To do this, the transform must accumulate some state during the traversal so
* that the end handler knows what to do. If such a transform is to be reused,
* its state must be reset for each traversal; this will happen automatically if
* the transform is created with {@link ClassTransform#ofStateful(Supplier)} (or
* corresponding methods for other classfile locations.)
* <p>
* Class transformation sample where code transformation is stateful:
* {@snippet lang="java" class="PackageSnippets" region="codeRelabeling"}
* <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
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassFileTransform<
C extends ClassFileTransform<C, E, B>,
E extends ClassFileElement,
B extends ClassFileBuilder<E, B>>
permits ClassTransform, FieldTransform, MethodTransform, CodeTransform {
/**
* Transform an element by taking the appropriate actions on the builder.
* Used when transforming a classfile entity (class, method, field, method
* body.) If no transformation is desired, the element can be presented to
* {@link B#with(ClassFileElement)}. If the element is to be dropped, no
* action is required.
*
* @param builder the builder for the new entity
* @param element the element
*/
void accept(B builder, E element);
/**
* Take any final action during transformation of a classfile entity. Called
* after all elements of the class are presented to {@link
* #accept(ClassFileBuilder, ClassFileElement)}.
*
* @param builder the builder for the new entity
* @implSpec The default implementation does nothing.
*/
default void atEnd(B builder) {
}
/**
* Take any preliminary action during transformation of a classfile entity.
* Called before any elements of the class are presented to {@link
* #accept(ClassFileBuilder, ClassFileElement)}.
*
* @param builder the builder for the new entity
* @implSpec The default implementation does nothing.
*/
default void atStart(B builder) {
}
/**
* Chain this transform with another; elements presented to the builder of
* this transform will become the input to the next transform.
*
* @param next the downstream transform
* @return the chained transform
*/
C andThen(C next);
/**
* The result of binding a transform to a builder. Used primarily within
* the implementation to perform transformation.
*
* @param <E> the element type
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
interface ResolvedTransform<E extends ClassFileElement> {
/**
* {@return a {@link Consumer} to receive elements}
*/
Consumer<E> consumer();
/**
* {@return an action to call at the end of transformation}
*/
Runnable endHandler();
/**
* {@return an action to call at the start of transformation}
*/
Runnable startHandler();
}
/**
* Bind a transform to a builder. If the transform is chained, intermediate
* builders are created for each chain link. If the transform is stateful
* (see, e.g., {@link ClassTransform#ofStateful(Supplier)}), the supplier is
* invoked to get a fresh transform object.
*
* <p>This method is a low-level method that should rarely be used by
* user code; most of the time, user code should prefer
* {@link ClassFileBuilder#transform(CompoundElement, ClassFileTransform)},
* which resolves the transform and executes it on the current builder.
*
* @param builder the builder to bind to
* @return the bound result
*/
ResolvedTransform<E> resolve(B builder);
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.classfile.impl.ClassFileVersionImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models the classfile version information for a class. Delivered as a {@link
* java.lang.classfile.ClassElement} when traversing the elements of a {@link
* ClassModel}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassFileVersion
extends ClassElement
permits ClassFileVersionImpl {
/**
* {@return the major classfile version}
*/
int majorVersion();
/**
* {@return the minor classfile version}
*/
int minorVersion();
/**
* {@return a {@link ClassFileVersion} element}
* @param majorVersion the major classfile version
* @param minorVersion the minor classfile version
*/
static ClassFileVersion of(int majorVersion, int minorVersion) {
return new ClassFileVersionImpl(majorVersion, minorVersion);
}
}

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.io.InputStream;
import java.lang.constant.ClassDesc;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import jdk.internal.classfile.impl.ClassHierarchyImpl;
import jdk.internal.classfile.impl.ClassHierarchyImpl.ClassLoadingClassHierarchyResolver;
import jdk.internal.classfile.impl.ClassHierarchyImpl.StaticClassHierarchyResolver;
import jdk.internal.classfile.impl.Util;
import static java.lang.constant.ConstantDescs.CD_Object;
import jdk.internal.javac.PreviewFeature;
/**
* Provides class hierarchy information for generating correct stack maps
* during code building.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
@FunctionalInterface
public interface ClassHierarchyResolver {
/**
* {@return the default instance of {@linkplain ClassHierarchyResolver} that
* gets {@link ClassHierarchyInfo} from system class loader with reflection}
*/
static ClassHierarchyResolver defaultResolver() {
return ClassHierarchyImpl.DEFAULT_RESOLVER;
}
/**
* {@return the {@link ClassHierarchyInfo} for a given class name, or null
* if the name is unknown to the resolver}
* @param classDesc descriptor of the class
* @throws IllegalArgumentException if a class shouldn't be queried for hierarchy
*/
ClassHierarchyInfo getClassInfo(ClassDesc classDesc);
/**
* Information about a resolved class.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface ClassHierarchyInfo permits ClassHierarchyImpl.ClassHierarchyInfoImpl {
/**
* Indicates that a class is a declared class, with the specific given super class.
*
* @param superClass descriptor of the super class, may be {@code null}
* @return the info indicating the super class
*/
static ClassHierarchyInfo ofClass(ClassDesc superClass) {
return new ClassHierarchyImpl.ClassHierarchyInfoImpl(superClass, false);
}
/**
* Indicates that a class is an interface.
*
* @return the info indicating an interface
*/
static ClassHierarchyInfo ofInterface() {
return new ClassHierarchyImpl.ClassHierarchyInfoImpl(CD_Object, true);
}
}
/**
* Chains this {@linkplain ClassHierarchyResolver} with another to be
* consulted if this resolver does not know about the specified class.
*
* @param other the other resolver
* @return the chained resolver
*
* @implSpec The default implementation returns resolver implemented to ask
* other resolver in cases where this resolver returns {@code null}.
*/
default ClassHierarchyResolver orElse(ClassHierarchyResolver other) {
return new ClassHierarchyResolver() {
@Override
public ClassHierarchyInfo getClassInfo(ClassDesc classDesc) {
var chi = ClassHierarchyResolver.this.getClassInfo(classDesc);
if (chi == null)
return other.getClassInfo(classDesc);
return chi;
}
};
}
/**
* Returns a ClassHierarchyResolver that caches class hierarchy information from this
* resolver. The returned resolver will not update if delegate resolver returns differently.
* The thread safety of the returned resolver depends on the thread safety of the map
* returned by the {@code cacheFactory}.
*
* @param cacheFactory the factory for the cache
* @return the ClassHierarchyResolver with caching
*
* @implSpec The default implementation returns resolver holding an instance
* of the cache map provided by the {@code cacheFactory}. It asks
* the cache map always first and fills the cache map with all
* resolved and also unresolved class info. The cache map may refuse
* {@code null} keys and values.
*/
default ClassHierarchyResolver cached(Supplier<Map<ClassDesc, ClassHierarchyInfo>> cacheFactory) {
return new ClassHierarchyImpl.CachedClassHierarchyResolver(this, cacheFactory.get());
}
/**
* Returns a ClassHierarchyResolver that caches class hierarchy information from this
* resolver. The returned resolver will not update if delegate resolver returns differently.
* The returned resolver is not thread-safe.
* {@snippet file="PackageSnippets.java" region="lookup-class-hierarchy-resolver"}
*
* @return the ClassHierarchyResolver
*
* @implSpec The default implementation calls {@link #cached(Supplier)} with
* {@link HashMap} supplier as {@code cacheFactory}.
*/
default ClassHierarchyResolver cached() {
record Factory() implements Supplier<Map<ClassDesc, ClassHierarchyInfo>> {
// uses a record as we cannot declare a local class static
static final Factory INSTANCE = new Factory();
@Override
public Map<ClassDesc, ClassHierarchyInfo> get() {
return new HashMap<>();
}
}
return cached(Factory.INSTANCE);
}
/**
* Returns a {@linkplain ClassHierarchyResolver} that extracts class hierarchy
* information from classfiles located by a mapping function. The mapping function
* should return null if it cannot provide a mapping for a classfile. Any IOException
* from the provided input stream is rethrown as an UncheckedIOException.
*
* @param classStreamResolver maps class descriptors to classfile input streams
* @return the {@linkplain ClassHierarchyResolver}
*/
static ClassHierarchyResolver ofResourceParsing(Function<ClassDesc, InputStream> classStreamResolver) {
return new ClassHierarchyImpl.ResourceParsingClassHierarchyResolver(classStreamResolver);
}
/**
* Returns a {@linkplain ClassHierarchyResolver} that extracts class hierarchy
* information from classfiles located by a class loader.
*
* @param loader the class loader, to find class files
* @return the {@linkplain ClassHierarchyResolver}
*/
static ClassHierarchyResolver ofResourceParsing(ClassLoader loader) {
return ofResourceParsing(new Function<>() {
@Override
public InputStream apply(ClassDesc classDesc) {
return loader.getResourceAsStream(Util.toInternalName(classDesc) + ".class");
}
});
}
/**
* Returns a {@linkplain ClassHierarchyResolver} that extracts class hierarchy
* information from collections of class hierarchy metadata
*
* @param interfaces a collection of classes known to be interfaces
* @param classToSuperClass a map from classes to their super classes
* @return the {@linkplain ClassHierarchyResolver}
*/
static ClassHierarchyResolver of(Collection<ClassDesc> interfaces,
Map<ClassDesc, ClassDesc> classToSuperClass) {
return new StaticClassHierarchyResolver(interfaces, classToSuperClass);
}
/**
* Returns a ClassHierarchyResolver that extracts class hierarchy information via
* the Reflection API with a {@linkplain ClassLoader}.
*
* @param loader the class loader
* @return the class hierarchy resolver
*/
static ClassHierarchyResolver ofClassLoading(ClassLoader loader) {
return new ClassLoadingClassHierarchyResolver(new Function<>() {
@Override
public Class<?> apply(ClassDesc cd) {
try {
return Class.forName(Util.toBinaryName(cd), false, loader);
} catch (ClassNotFoundException ex) {
return null;
}
}
});
}
/**
* Returns a ClassHierarchyResolver that extracts class hierarchy information via
* the Reflection API with a {@linkplain MethodHandles.Lookup Lookup}. If the class
* resolved is inaccessible to the given lookup, it throws {@link
* IllegalArgumentException} instead of returning {@code null}.
*
* @param lookup the lookup, must be able to access classes to resolve
* @return the class hierarchy resolver
*/
static ClassHierarchyResolver ofClassLoading(MethodHandles.Lookup lookup) {
return new ClassLoadingClassHierarchyResolver(new Function<>() {
@Override
public Class<?> apply(ClassDesc cd) {
try {
return cd.resolveConstantDesc(lookup);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
} catch (ReflectiveOperationException ex) {
return null;
}
}
});
}
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantPool;
import jdk.internal.classfile.impl.ClassImpl;
import jdk.internal.classfile.impl.verifier.VerifierImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models a classfile. The contents of the classfile can be traversed via
* a streaming view (e.g., {@link #elements()}), or via random access (e.g.,
* {@link #flags()}), or by freely mixing the two.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassModel
extends CompoundElement<ClassElement>, AttributedElement
permits ClassImpl {
/**
* {@return the constant pool for this class}
*/
ConstantPool constantPool();
/** {@return the access flags} */
AccessFlags flags();
/** {@return the constant pool entry describing the name of this class} */
ClassEntry thisClass();
/** {@return the major classfile version} */
int majorVersion();
/** {@return the minor classfile version} */
int minorVersion();
/** {@return the fields of this class} */
List<FieldModel> fields();
/** {@return the methods of this class} */
List<MethodModel> methods();
/** {@return the superclass of this class, if there is one} */
Optional<ClassEntry> superclass();
/** {@return the interfaces implemented by this class} */
List<ClassEntry> interfaces();
/** {@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

@ -0,0 +1,279 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.ConstantPoolException;
import java.lang.classfile.constantpool.MethodHandleEntry;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.NameAndTypeEntry;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.classfile.constantpool.PoolEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.ClassReaderImpl;
import java.util.Optional;
import java.util.function.Function;
import jdk.internal.javac.PreviewFeature;
/**
* Supports reading from a classfile. Methods are provided to read data of
* various numeric types (e.g., {@code u2}, {@code u4}) at a given offset within
* the classfile, copying raw bytes, and reading constant pool entries.
* Encapsulates additional reading context such as mappers for custom attributes
* and processing options.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassReader extends ConstantPool
permits ClassReaderImpl {
// Processing context
/**
* {@return the table of custom attribute mappers} This is derived from
* the processing option {@link ClassFile.AttributeMapperOption}.
*/
Function<Utf8Entry, AttributeMapper<?>> customAttributes();
// Class context
/** {@return the access flags for the class, as a bit mask } */
int flags();
/** {@return the constant pool entry describing the name of class} */
ClassEntry thisClassEntry();
/** {@return the constant pool entry describing the name of the superclass, if any} */
Optional<ClassEntry> superclassEntry();
/** {@return the offset into the classfile of the {@code this_class} field} */
int thisClassPos();
/** {@return the length of the classfile, in bytes} */
int classfileLength();
// Buffer related
/**
* {@return the offset following the block of attributes starting at the
* specified position}
* @param offset the offset into the classfile at which the attribute block
* starts
*/
int skipAttributeHolder(int offset);
// Constant pool
/**
* {@return the UTF8 constant pool entry at the given index of the constant
* pool} The given index must correspond to a valid constant pool index
* whose slot holds a UTF8 constant.
* @param index the index into the constant pool
*/
Utf8Entry utf8EntryByIndex(int index);
/**
* {@return the constant pool entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero
*/
PoolEntry readEntry(int offset);
/**
* {@return the constant pool entry of a given type whose index is given
* at the specified offset within the classfile}
* @param <T> the entry type
* @param offset the offset of the index within the classfile
* @param cls the entry type
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the entry is not of the given type
*/
<T extends PoolEntry> T readEntry(int offset, Class<T> cls);
/**
* {@return the constant pool entry whose index is given at the specified
* offset within the classfile, or null if the index at the specified
* offset is zero}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size
*/
PoolEntry readEntryOrNull(int offset);
/**
* {@return the UTF8 entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a UTF8 entry
*/
Utf8Entry readUtf8Entry(int offset);
/**
* {@return the UTF8 entry whose index is given at the specified
* offset within the classfile, or null if the index at the specified
* offset is zero}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or the index does not correspond to
* a UTF8 entry
*/
Utf8Entry readUtf8EntryOrNull(int offset);
/**
* {@return the module entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a module entry
*/
ModuleEntry readModuleEntry(int offset);
/**
* {@return the package entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a package entry
*/
PackageEntry readPackageEntry(int offset);
/**
* {@return the class entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a class entry
*/
ClassEntry readClassEntry(int offset);
/**
* {@return the name-and-type entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a name-and-type entry
*/
NameAndTypeEntry readNameAndTypeEntry(int offset);
/**
* {@return the method handle entry whose index is given at the specified
* offset within the classfile}
* @param offset the offset of the index within the classfile
* @throws ConstantPoolException if the index is out of range of the
* constant pool size, or zero, or the index does not correspond to
* a method handle entry
*/
MethodHandleEntry readMethodHandleEntry(int offset);
/**
* {@return the unsigned byte at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
int readU1(int offset);
/**
* {@return the unsigned short at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
int readU2(int offset);
/**
* {@return the signed byte at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
int readS1(int offset);
/**
* {@return the signed byte at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
int readS2(int offset);
/**
* {@return the signed int at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
int readInt(int offset);
/**
* {@return the signed long at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
long readLong(int offset);
/**
* {@return the float value at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
float readFloat(int offset);
/**
* {@return the double value at the specified offset within the classfile}
* @param offset the offset within the classfile
*/
double readDouble(int offset);
/**
* {@return a copy of the bytes at the specified range in the classfile}
* @param offset the offset within the classfile
* @param len the length of the range
*/
byte[] readBytes(int offset, int len);
/**
* Copy a range of bytes from the classfile to a {@link BufWriter}
*
* @param buf the {@linkplain BufWriter}
* @param offset the offset within the classfile
* @param len the length of the range
*/
void copyBytesTo(BufWriter buf, int offset, int len);
/**
* Compare a range of bytes from the classfile to a range of bytes within
* a {@link BufWriter}.
*
* @param bufWriter the {@linkplain BufWriter}
* @param bufWriterOffset the offset within the {@linkplain BufWriter}
* @param classReaderOffset the offset within the classfile
* @param length the length of the range
* @return whether the two ranges were identical
*/
boolean compare(BufWriter bufWriter,
int bufWriterOffset,
int classReaderOffset,
int length);
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.List;
import jdk.internal.classfile.impl.SignaturesImpl;
import static java.util.Objects.requireNonNull;
import jdk.internal.javac.PreviewFeature;
/**
* Models the generic signature of a class file, as defined by {@jvms 4.7.9}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassSignature
permits SignaturesImpl.ClassSignatureImpl {
/** {@return the type parameters of this class} */
List<Signature.TypeParam> typeParameters();
/** {@return the instantiation of the superclass in this signature} */
Signature.RefTypeSig superclassSignature();
/** {@return the instantiation of the interfaces in this signature} */
List<Signature.RefTypeSig> superinterfaceSignatures();
/** {@return the raw signature string} */
String signatureString();
/**
* {@return a class signature}
* @param superclassSignature the superclass
* @param superinterfaceSignatures the interfaces
*/
public static ClassSignature of(Signature.RefTypeSig superclassSignature,
Signature.RefTypeSig... superinterfaceSignatures) {
return of(List.of(), superclassSignature, superinterfaceSignatures);
}
/**
* {@return a class signature}
* @param typeParameters the type parameters
* @param superclassSignature the superclass
* @param superinterfaceSignatures the interfaces
*/
public static ClassSignature of(List<Signature.TypeParam> typeParameters,
Signature.RefTypeSig superclassSignature,
Signature.RefTypeSig... superinterfaceSignatures) {
return new SignaturesImpl.ClassSignatureImpl(
requireNonNull(typeParameters),
requireNonNull(superclassSignature),
List.of(superinterfaceSignatures));
}
/**
* Parses a raw class signature string into a {@linkplain Signature}
* @param classSignature the raw class signature string
* @return class signature
*/
public static ClassSignature parseFrom(String classSignature) {
return new SignaturesImpl().parseClassSignature(requireNonNull(classSignature));
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.lang.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.impl.TransformImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A transformation on streams of {@link ClassElement}.
*
* @see ClassFileTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
@FunctionalInterface
public non-sealed interface ClassTransform
extends ClassFileTransform<ClassTransform, ClassElement, ClassBuilder> {
/**
* A class transform that sends all elements to the builder.
*/
static final ClassTransform ACCEPT_ALL = new ClassTransform() {
@Override
public void accept(ClassBuilder builder, ClassElement element) {
builder.with(element);
}
};
/**
* Create a stateful class transform from a {@link Supplier}. The supplier
* will be invoked for each transformation.
*
* @param supplier a {@link Supplier} that produces a fresh transform object
* for each traversal
* @return the stateful class transform
*/
static ClassTransform ofStateful(Supplier<ClassTransform> supplier) {
return new TransformImpl.SupplierClassTransform(supplier);
}
/**
* Create a class transform that passes each element through to the builder,
* and calls the specified function when transformation is complete.
*
* @param finisher the function to call when transformation is complete
* @return the class transform
*/
static ClassTransform endHandler(Consumer<ClassBuilder> finisher) {
return new ClassTransform() {
@Override
public void accept(ClassBuilder builder, ClassElement element) {
builder.with(element);
}
@Override
public void atEnd(ClassBuilder builder) {
finisher.accept(builder);
}
};
}
/**
* Create a class transform that passes each element through to the builder,
* except for those that the supplied {@link Predicate} is true for.
*
* @param filter the predicate that determines which elements to drop
* @return the class transform
*/
static ClassTransform dropping(Predicate<ClassElement> filter) {
return (b, e) -> {
if (!filter.test(e))
b.with(e);
};
}
/**
* Create a class transform that transforms {@link MethodModel} elements
* with the supplied method transform.
*
* @param filter a predicate that determines which methods to transform
* @param xform the method transform
* @return the class transform
*/
static ClassTransform transformingMethods(Predicate<MethodModel> filter,
MethodTransform xform) {
return new TransformImpl.ClassMethodTransform(xform, filter);
}
/**
* Create a class transform that transforms {@link MethodModel} elements
* with the supplied method transform.
*
* @param xform the method transform
* @return the class transform
*/
static ClassTransform transformingMethods(MethodTransform xform) {
return transformingMethods(mm -> true, xform);
}
/**
* Create a class transform that transforms the {@link CodeAttribute} (method body)
* of {@link MethodModel} elements with the supplied code transform.
*
* @param filter a predicate that determines which methods to transform
* @param xform the code transform
* @return the class transform
*/
static ClassTransform transformingMethodBodies(Predicate<MethodModel> filter,
CodeTransform xform) {
return transformingMethods(filter, MethodTransform.transformingCode(xform));
}
/**
* Create a class transform that transforms the {@link CodeAttribute} (method body)
* of {@link MethodModel} elements with the supplied code transform.
*
* @param xform the code transform
* @return the class transform
*/
static ClassTransform transformingMethodBodies(CodeTransform xform) {
return transformingMethods(MethodTransform.transformingCode(xform));
}
/**
* Create a class transform that transforms {@link FieldModel} elements
* with the supplied field transform.
*
* @param xform the field transform
* @return the class transform
*/
static ClassTransform transformingFields(FieldTransform xform) {
return new TransformImpl.ClassFieldTransform(xform, f -> true);
}
/**
* @implSpec
* The default implementation returns this class transform chained with another
* class transform from the argument. Chaining of two transforms requires to
* involve a chained builder serving as a target builder for this transform
* and also as a source of elements for the downstream transform.
*/
@Override
default ClassTransform andThen(ClassTransform t) {
return new TransformImpl.ChainedClassTransform(this, t);
}
/**
* @implSpec The default implementation returns a resolved transform bound
* to the given class builder.
*/
@Override
default ResolvedTransform<ClassElement> resolve(ClassBuilder builder) {
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
() -> atEnd(builder),
() -> atStart(builder));
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.StackMapTableAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A marker interface for elements that can appear when traversing
* a {@link CodeModel} or be presented to a {@link CodeBuilder}. Code elements
* are either an {@link Instruction}, which models an instruction in the body
* of a method, or a {@link PseudoInstruction}, which models metadata from
* the code attribute, such as line number metadata, local variable metadata,
* exception metadata, label target metadata, etc.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CodeElement extends ClassFileElement
permits Instruction, PseudoInstruction,
CustomAttribute, RuntimeVisibleTypeAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute,
StackMapTableAttribute {
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.List;
import java.util.Optional;
import java.lang.classfile.attribute.CodeAttribute;
import jdk.internal.classfile.impl.BufferedCodeBuilder;
import jdk.internal.classfile.impl.CodeImpl;
import java.lang.classfile.instruction.ExceptionCatch;
import jdk.internal.javac.PreviewFeature;
/**
* Models the body of a method (the {@code Code} attribute). The instructions
* of the method body are accessed via a streaming view (e.g., {@link
* #elements()}).
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CodeModel
extends CompoundElement<CodeElement>, AttributedElement, MethodElement
permits CodeAttribute, BufferedCodeBuilder.Model, CodeImpl {
/**
* {@return the maximum size of the local variable table}
*/
int maxLocals();
/**
* {@return the maximum size of the operand stack}
*/
int maxStack();
/**
* {@return the enclosing method, if known}
*/
Optional<MethodModel> parent();
/**
* {@return the exception table of the method} The exception table is also
* modeled by {@link ExceptionCatch} elements in the streaming view.
*/
List<ExceptionCatch> exceptionHandlers();
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.function.Consumer;
import java.util.function.Supplier;
import jdk.internal.classfile.impl.TransformImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A transformation on streams of {@link CodeElement}.
*
* @see ClassFileTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
@FunctionalInterface
public non-sealed interface CodeTransform
extends ClassFileTransform<CodeTransform, CodeElement, CodeBuilder> {
/**
* A code transform that sends all elements to the builder.
*/
CodeTransform ACCEPT_ALL = new CodeTransform() {
@Override
public void accept(CodeBuilder builder, CodeElement element) {
builder.with(element);
}
};
/**
* Create a stateful code transform from a {@link Supplier}. The supplier
* will be invoked for each transformation.
*
* @param supplier a {@link Supplier} that produces a fresh transform object
* for each traversal
* @return the stateful code transform
*/
static CodeTransform ofStateful(Supplier<CodeTransform> supplier) {
return new TransformImpl.SupplierCodeTransform(supplier);
}
/**
* Create a code transform that passes each element through to the builder,
* and calls the specified function when transformation is complete.
*
* @param finisher the function to call when transformation is complete
* @return the code transform
*/
static CodeTransform endHandler(Consumer<CodeBuilder> finisher) {
return new CodeTransform() {
@Override
public void accept(CodeBuilder builder, CodeElement element) {
builder.with(element);
}
@Override
public void atEnd(CodeBuilder builder) {
finisher.accept(builder);
}
};
}
/**
* @implSpec
* The default implementation returns this code transform chained with another
* code transform from the argument. Chaining of two transforms requires to
* involve a chained builder serving as a target builder for this transform
* and also as a source of elements for the downstream transform.
*/
@Override
default CodeTransform andThen(CodeTransform t) {
return new TransformImpl.ChainedCodeTransform(this, t);
}
/**
* @implSpec The default implementation returns a resolved transform bound
* to the given code builder.
*/
@Override
default ResolvedTransform<CodeElement> resolve(CodeBuilder builder) {
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
() -> atEnd(builder),
() -> atStart(builder));
}
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.javac.PreviewFeature;
/**
* A {@link ClassFileElement} that has complex structure defined in terms of
* other classfile elements, such as a method, field, method body, or entire
* class. When encountering a {@linkplain CompoundElement}, clients have the
* 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
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CompoundElement<E extends ClassFileElement>
extends ClassFileElement, Iterable<E>
permits ClassModel, CodeModel, FieldModel, MethodModel, jdk.internal.classfile.impl.AbstractUnboundModel {
/**
* Invoke the provided handler with each element contained in this
* compound element
* @param consumer the handler
*/
void forEachElement(Consumer<E> consumer);
/**
* {@return an {@link Iterable} describing all the elements contained in this
* compound element}
*/
default Iterable<E> elements() {
return elementList();
}
/**
* {@return an {@link Iterator} describing all the elements contained in this
* compound element}
*/
@Override
default Iterator<E> iterator() {
return elements().iterator();
}
/**
* {@return a {@link Stream} containing all the elements contained in this
* compound element}
*/
default Stream<E> elementStream() {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator(),
Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED),
false);
}
/**
* {@return an {@link List} containing all the elements contained in this
* compound element}
*/
default List<E> elementList() {
List<E> list = new ArrayList<>();
forEachElement(new Consumer<>() {
@Override
public void accept(E e) {
list.add(e);
}
});
return list;
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.javac.PreviewFeature;
/**
* Models a non-standard attribute of a classfile. Clients should extend
* 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
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public abstract non-sealed class CustomAttribute<T extends CustomAttribute<T>>
implements Attribute<T>, CodeElement, ClassElement, MethodElement, FieldElement {
private final AttributeMapper<T> mapper;
/**
* Construct a {@linkplain CustomAttribute}.
* @param mapper the attribute mapper
*/
protected CustomAttribute(AttributeMapper<T> mapper) {
this.mapper = mapper;
}
@Override
public final AttributeMapper<T> attributeMapper() {
return mapper;
}
@Override
public final String attributeName() {
return mapper.name();
}
@Override
@SuppressWarnings("unchecked")
public final void writeTo(BufWriter buf) {
mapper.writeAttribute(buf, (T) this);
}
@Override
public String toString() {
return String.format("CustomAttribute[name=%s]", mapper.name());
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.ChainedFieldBuilder;
import jdk.internal.classfile.impl.TerminalFieldBuilder;
import java.lang.reflect.AccessFlag;
import java.util.Optional;
import java.util.function.Consumer;
import jdk.internal.javac.PreviewFeature;
/**
* A builder for fields. Builders are not created directly; they are passed
* to handlers by methods such as {@link ClassBuilder#withField(Utf8Entry, Utf8Entry, Consumer)}
* or to field transforms. The elements of a field can be specified
* abstractly (by passing a {@link FieldElement} to {@link #with(ClassFileElement)}
* or concretely by calling the various {@code withXxx} methods.
*
* @see FieldTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface FieldBuilder
extends ClassFileBuilder<FieldElement, FieldBuilder>
permits TerminalFieldBuilder, ChainedFieldBuilder {
/**
* Sets the field access flags.
* @param flags the access flags, as a bit mask
* @return this builder
*/
default FieldBuilder withFlags(int flags) {
return with(AccessFlags.ofField(flags));
}
/**
* Sets the field access flags.
* @param flags the access flags, as a bit mask
* @return this builder
*/
default FieldBuilder withFlags(AccessFlag... flags) {
return with(AccessFlags.ofField(flags));
}
/**
* {@return the {@link FieldModel} representing the field being transformed,
* if this field builder represents the transformation of some {@link FieldModel}}
*/
Optional<FieldModel> original();
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.ConstantValueAttribute;
import java.lang.classfile.attribute.DeprecatedAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.classfile.attribute.SyntheticAttribute;
import java.lang.classfile.attribute.UnknownAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A marker interface for elements that can appear when traversing
* a {@link FieldModel} or be presented to a {@link FieldBuilder}.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface FieldElement extends ClassFileElement
permits AccessFlags,
CustomAttribute, ConstantValueAttribute, DeprecatedAttribute,
RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute,
RuntimeVisibleAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute,
SignatureAttribute, SyntheticAttribute, UnknownAttribute {
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.util.Optional;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BufferedFieldBuilder;
import jdk.internal.classfile.impl.FieldImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models a field. The contents of the field can be traversed via
* a streaming view (e.g., {@link #elements()}), or via random access (e.g.,
* {@link #flags()}), or by freely mixing the two.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface FieldModel
extends WritableElement<FieldModel>, CompoundElement<FieldElement>, AttributedElement, ClassElement
permits BufferedFieldBuilder.Model, FieldImpl {
/** {@return the access flags} */
AccessFlags flags();
/** {@return the class model this field is a member of, if known} */
Optional<ClassModel> parent();
/** {@return the name of this field} */
Utf8Entry fieldName();
/** {@return the field descriptor of this field} */
Utf8Entry fieldType();
/** {@return the field descriptor of this field, as a symbolic descriptor} */
default ClassDesc fieldTypeSymbol() {
return ClassDesc.ofDescriptor(fieldType().stringValue());
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import jdk.internal.classfile.impl.TransformImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A transformation on streams of {@link FieldElement}.
*
* @see ClassFileTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
@FunctionalInterface
public non-sealed interface FieldTransform
extends ClassFileTransform<FieldTransform, FieldElement, FieldBuilder> {
/**
* A field transform that sends all elements to the builder.
*/
FieldTransform ACCEPT_ALL = new FieldTransform() {
@Override
public void accept(FieldBuilder builder, FieldElement element) {
builder.with(element);
}
};
/**
* Create a stateful field transform from a {@link Supplier}. The supplier
* will be invoked for each transformation.
*
* @param supplier a {@link Supplier} that produces a fresh transform object
* for each traversal
* @return the stateful field transform
*/
static FieldTransform ofStateful(Supplier<FieldTransform> supplier) {
return new TransformImpl.SupplierFieldTransform(supplier);
}
/**
* Create a field transform that passes each element through to the builder,
* and calls the specified function when transformation is complete.
*
* @param finisher the function to call when transformation is complete
* @return the field transform
*/
static FieldTransform endHandler(Consumer<FieldBuilder> finisher) {
return new FieldTransform() {
@Override
public void accept(FieldBuilder builder, FieldElement element) {
builder.with(element);
}
@Override
public void atEnd(FieldBuilder builder) {
finisher.accept(builder);
}
};
}
/**
* Create a field transform that passes each element through to the builder,
* except for those that the supplied {@link Predicate} is true for.
*
* @param filter the predicate that determines which elements to drop
* @return the field transform
*/
static FieldTransform dropping(Predicate<FieldElement> filter) {
return (b, e) -> {
if (!filter.test(e))
b.with(e);
};
}
/**
* @implSpec
* The default implementation returns this field transform chained with another
* field transform from the argument. Chaining of two transforms requires to
* involve a chained builder serving as a target builder for this transform
* and also as a source of elements for the downstream transform.
*/
@Override
default FieldTransform andThen(FieldTransform t) {
return new TransformImpl.ChainedFieldTransform(this, t);
}
/**
* @implSpec The default implementation returns a resolved transform bound
* to the given field builder.
*/
@Override
default ResolvedTransform<FieldElement> resolve(FieldBuilder builder) {
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
() -> atEnd(builder),
() -> atStart(builder));
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.classfile.impl.AbstractInstruction;
import java.lang.classfile.instruction.ArrayLoadInstruction;
import java.lang.classfile.instruction.ArrayStoreInstruction;
import java.lang.classfile.instruction.BranchInstruction;
import java.lang.classfile.instruction.ConstantInstruction;
import java.lang.classfile.instruction.ConvertInstruction;
import java.lang.classfile.instruction.DiscontinuedInstruction;
import java.lang.classfile.instruction.FieldInstruction;
import java.lang.classfile.instruction.IncrementInstruction;
import java.lang.classfile.instruction.InvokeDynamicInstruction;
import java.lang.classfile.instruction.InvokeInstruction;
import java.lang.classfile.instruction.LoadInstruction;
import java.lang.classfile.instruction.LookupSwitchInstruction;
import java.lang.classfile.instruction.MonitorInstruction;
import java.lang.classfile.instruction.NewMultiArrayInstruction;
import java.lang.classfile.instruction.NewObjectInstruction;
import java.lang.classfile.instruction.NewPrimitiveArrayInstruction;
import java.lang.classfile.instruction.NewReferenceArrayInstruction;
import java.lang.classfile.instruction.NopInstruction;
import java.lang.classfile.instruction.OperatorInstruction;
import java.lang.classfile.instruction.ReturnInstruction;
import java.lang.classfile.instruction.StackInstruction;
import java.lang.classfile.instruction.StoreInstruction;
import java.lang.classfile.instruction.TableSwitchInstruction;
import java.lang.classfile.instruction.ThrowInstruction;
import java.lang.classfile.instruction.TypeCheckInstruction;
import jdk.internal.javac.PreviewFeature;
/**
* Models an executable instruction in a method body.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Instruction extends CodeElement
permits ArrayLoadInstruction, ArrayStoreInstruction, BranchInstruction,
ConstantInstruction, ConvertInstruction, DiscontinuedInstruction,
FieldInstruction, InvokeDynamicInstruction, InvokeInstruction,
LoadInstruction, StoreInstruction, IncrementInstruction,
LookupSwitchInstruction, MonitorInstruction, NewMultiArrayInstruction,
NewObjectInstruction, NewPrimitiveArrayInstruction, NewReferenceArrayInstruction,
NopInstruction, OperatorInstruction, ReturnInstruction,
StackInstruction, TableSwitchInstruction,
ThrowInstruction, TypeCheckInstruction, AbstractInstruction {
/**
* {@return the opcode of this instruction}
*/
Opcode opcode();
/**
* {@return the size in bytes of this instruction}
*/
int sizeInBytes();
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.InterfacesImpl;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the interfaces of a class. Delivered as a {@link
* java.lang.classfile.ClassElement} when traversing a {@link ClassModel}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Interfaces
extends ClassElement
permits InterfacesImpl {
/** {@return the interfaces of this class} */
List<ClassEntry> interfaces();
/**
* {@return an {@linkplain Interfaces} element}
* @param interfaces the interfaces
*/
static Interfaces of(List<ClassEntry> interfaces) {
return new InterfacesImpl(interfaces);
}
/**
* {@return an {@linkplain Interfaces} element}
* @param interfaces the interfaces
*/
static Interfaces of(ClassEntry... interfaces) {
return of(List.of(interfaces));
}
/**
* {@return an {@linkplain Interfaces} element}
* @param interfaces the interfaces
*/
static Interfaces ofSymbols(List<ClassDesc> interfaces) {
return of(Util.entryList(interfaces));
}
/**
* {@return an {@linkplain Interfaces} element}
* @param interfaces the interfaces
*/
static Interfaces ofSymbols(ClassDesc... interfaces) {
return ofSymbols(Arrays.asList(interfaces));
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import jdk.internal.classfile.impl.LabelImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A marker for a position within the instructions of a method body. The
* association between a label's identity and the position it represents is
* managed by the entity managing the method body (a {@link CodeModel} or {@link
* CodeBuilder}), not the label itself; this allows the same label to have a
* meaning both in an existing method (as managed by a {@linkplain CodeModel})
* and in the transformation of that method (as managed by a {@linkplain
* CodeBuilder}), while corresponding to different positions in each. When
* traversing the elements of a {@linkplain CodeModel}, {@linkplain Label}
* markers will be delivered at the position to which they correspond. A label
* can be bound to the current position within a {@linkplain CodeBuilder} via
* {@link CodeBuilder#labelBinding(Label)} or {@link CodeBuilder#with(ClassFileElement)}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Label
permits LabelImpl {
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.Optional;
import java.util.function.Consumer;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.ChainedMethodBuilder;
import jdk.internal.classfile.impl.TerminalMethodBuilder;
import java.lang.reflect.AccessFlag;
import jdk.internal.javac.PreviewFeature;
/**
* A builder for methods. Builders are not created directly; they are passed
* to handlers by methods such as {@link ClassBuilder#withMethod(Utf8Entry, Utf8Entry, int, Consumer)}
* or to method transforms. The elements of a method can be specified
* abstractly (by passing a {@link MethodElement} to {@link #with(ClassFileElement)}
* or concretely by calling the various {@code withXxx} methods.
*
* @see MethodTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodBuilder
extends ClassFileBuilder<MethodElement, MethodBuilder>
permits ChainedMethodBuilder, TerminalMethodBuilder {
/**
* {@return the {@link MethodModel} representing the method being transformed,
* if this method builder represents the transformation of some {@link MethodModel}}
*/
Optional<MethodModel> original();
/**
* Sets the method access flags.
* @param flags the access flags, as a bit mask
* @return this builder
*/
default MethodBuilder withFlags(int flags) {
return with(AccessFlags.ofMethod(flags));
}
/**
* Sets the method access flags.
* @param flags the access flags, as a bit mask
* @return this builder
*/
default MethodBuilder withFlags(AccessFlag... flags) {
return with(AccessFlags.ofMethod(flags));
}
/**
* Build the method body for this method.
* @param code a handler receiving a {@link CodeBuilder}
* @return this builder
*/
MethodBuilder withCode(Consumer<? super CodeBuilder> code);
/**
* Build the method body for this method by transforming the body of another
* method.
*
* @implNote
* <p>This method behaves as if:
* {@snippet lang=java :
* withCode(b -> b.transformCode(code, transform));
* }
*
* @param code the method body to be transformed
* @param transform the transform to apply to the method body
* @return this builder
*/
MethodBuilder transformCode(CodeModel code, CodeTransform transform);
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.AnnotationDefaultAttribute;
import java.lang.classfile.attribute.DeprecatedAttribute;
import java.lang.classfile.attribute.ExceptionsAttribute;
import java.lang.classfile.attribute.MethodParametersAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.classfile.attribute.SyntheticAttribute;
import java.lang.classfile.attribute.UnknownAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* A marker interface for elements that can appear when traversing
* a {@link MethodModel} or be presented to a {@link MethodBuilder}.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodElement
extends ClassFileElement
permits AccessFlags, CodeModel, CustomAttribute,
AnnotationDefaultAttribute, DeprecatedAttribute,
ExceptionsAttribute, MethodParametersAttribute,
RuntimeInvisibleAnnotationsAttribute, RuntimeInvisibleParameterAnnotationsAttribute,
RuntimeInvisibleTypeAnnotationsAttribute, RuntimeVisibleAnnotationsAttribute,
RuntimeVisibleParameterAnnotationsAttribute, RuntimeVisibleTypeAnnotationsAttribute,
SignatureAttribute, SyntheticAttribute, UnknownAttribute {
}

View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.MethodTypeDesc;
import java.util.Optional;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BufferedMethodBuilder;
import jdk.internal.classfile.impl.MethodImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models a method. The contents of the method can be traversed via
* a streaming view (e.g., {@link #elements()}), or via random access (e.g.,
* {@link #flags()}), or by freely mixing the two.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodModel
extends WritableElement<MethodModel>, CompoundElement<MethodElement>, AttributedElement, ClassElement
permits BufferedMethodBuilder.Model, MethodImpl {
/** {@return the access flags} */
AccessFlags flags();
/** {@return the class model this method is a member of, if known} */
Optional<ClassModel> parent();
/** {@return the name of this method} */
Utf8Entry methodName();
/** {@return the method descriptor of this method} */
Utf8Entry methodType();
/** {@return the method descriptor of this method, as a symbolic descriptor} */
default MethodTypeDesc methodTypeSymbol() {
return MethodTypeDesc.ofDescriptor(methodType().stringValue());
}
/** {@return the body of this method, if there is one} */
Optional<CodeModel> code();
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.MethodTypeDesc;
import java.util.List;
import jdk.internal.classfile.impl.SignaturesImpl;
import static java.util.Objects.requireNonNull;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the generic signature of a method, as defined by {@jvms 4.7.9}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodSignature
permits SignaturesImpl.MethodSignatureImpl {
/** {@return the type parameters of this method} */
List<Signature.TypeParam> typeParameters();
/** {@return the signatures of the parameters of this method} */
List<Signature> arguments();
/** {@return the signatures of the return value of this method} */
Signature result();
/** {@return the signatures of the exceptions thrown by this method} */
List<Signature.ThrowableSig> throwableSignatures();
/** {@return the raw signature string} */
String signatureString();
/**
* {@return a method signature for a raw (no generic information) method descriptor}
* @param methodDescriptor the method descriptor
*/
public static MethodSignature of(MethodTypeDesc methodDescriptor) {
requireNonNull(methodDescriptor);
return new SignaturesImpl.MethodSignatureImpl(
List.of(),
List.of(),
Signature.of(methodDescriptor.returnType()),
Util.mappedList(methodDescriptor.parameterList(), Signature::of));
}
/**
* {@return a method signature}
* @param result signature for the return type
* @param arguments signatures for the method arguments
*/
public static MethodSignature of(Signature result,
Signature... arguments) {
return new SignaturesImpl.MethodSignatureImpl(List.of(),
List.of(),
requireNonNull(result),
List.of(arguments));
}
/**
* {@return a method signature}
* @param typeParameters signatures for the type parameters
* @param exceptions signatures for the exceptions
* @param result signature for the return type
* @param arguments signatures for the method arguments
*/
public static MethodSignature of(List<Signature.TypeParam> typeParameters,
List<Signature.ThrowableSig> exceptions,
Signature result,
Signature... arguments) {
return new SignaturesImpl.MethodSignatureImpl(
List.copyOf(requireNonNull(typeParameters)),
List.copyOf(requireNonNull(exceptions)),
requireNonNull(result),
List.of(arguments));
}
/**
* Parses a raw method signature string into a {@linkplain MethodSignature}
* @param methodSignature the raw method signature string
* @return method signature
*/
public static MethodSignature parseFrom(String methodSignature) {
return new SignaturesImpl().parseMethodSignature(requireNonNull(methodSignature));
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import jdk.internal.classfile.impl.TransformImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A transformation on streams of {@link MethodElement}.
*
* @see ClassFileTransform
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
@FunctionalInterface
public non-sealed interface MethodTransform
extends ClassFileTransform<MethodTransform, MethodElement, MethodBuilder> {
/**
* A method transform that sends all elements to the builder.
*/
MethodTransform ACCEPT_ALL = new MethodTransform() {
@Override
public void accept(MethodBuilder builder, MethodElement element) {
builder.with(element);
}
};
/**
* Create a stateful method transform from a {@link Supplier}. The supplier
* will be invoked for each transformation.
*
* @param supplier a {@link Supplier} that produces a fresh transform object
* for each traversal
* @return the stateful method transform
*/
static MethodTransform ofStateful(Supplier<MethodTransform> supplier) {
return new TransformImpl.SupplierMethodTransform(supplier);
}
/**
* Create a method transform that passes each element through to the builder,
* and calls the specified function when transformation is complete.
*
* @param finisher the function to call when transformation is complete
* @return the method transform
*/
static MethodTransform endHandler(Consumer<MethodBuilder> finisher) {
return new MethodTransform() {
@Override
public void accept(MethodBuilder builder, MethodElement element) {
builder.with(element);
}
@Override
public void atEnd(MethodBuilder builder) {
finisher.accept(builder);
}
};
}
/**
* Create a method transform that passes each element through to the builder,
* except for those that the supplied {@link Predicate} is true for.
*
* @param filter the predicate that determines which elements to drop
* @return the method transform
*/
static MethodTransform dropping(Predicate<MethodElement> filter) {
return (b, e) -> {
if (!filter.test(e))
b.with(e);
};
}
/**
* Create a method transform that transforms {@link CodeModel} elements
* with the supplied code transform.
*
* @param xform the method transform
* @return the class transform
*/
static MethodTransform transformingCode(CodeTransform xform) {
return new TransformImpl.MethodCodeTransform(xform);
}
/**
* @implSpec The default implementation returns a resolved transform bound
* to the given method builder.
*/
@Override
default ResolvedTransform<MethodElement> resolve(MethodBuilder builder) {
return new TransformImpl.ResolvedTransformImpl<>(e -> accept(builder, e),
() -> atEnd(builder),
() -> atStart(builder));
}
/**
* @implSpec
* The default implementation returns this method transform chained with another
* method transform from the argument. Chaining of two transforms requires to
* involve a chained builder serving as a target builder for this transform
* and also as a source of elements for the downstream transform.
*/
@Override
default MethodTransform andThen(MethodTransform t) {
return new TransformImpl.ChainedMethodTransform(this, t);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.attribute.CodeAttribute;
import java.lang.classfile.instruction.CharacterRange;
import java.lang.classfile.instruction.ExceptionCatch;
import java.lang.classfile.instruction.LabelTarget;
import java.lang.classfile.instruction.LineNumber;
import java.lang.classfile.instruction.LocalVariable;
import java.lang.classfile.instruction.LocalVariableType;
import jdk.internal.classfile.impl.AbstractPseudoInstruction;
import jdk.internal.javac.PreviewFeature;
/**
* Models metadata about a {@link CodeAttribute}, such as entries in the
* exception table, line number table, local variable table, or the mapping
* between instructions and labels. Pseudo-instructions are delivered as part
* of the element stream of a {@link CodeModel}. Delivery of some
* pseudo-instructions can be disabled by modifying the value of classfile
* options (e.g., {@link ClassFile.DebugElementsOption}).
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface PseudoInstruction
extends CodeElement
permits CharacterRange, ExceptionCatch, LabelTarget, LineNumber, LocalVariable, LocalVariableType, AbstractPseudoInstruction {
}

View file

@ -0,0 +1,386 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import jdk.internal.classfile.impl.SignaturesImpl;
import java.util.List;
import static java.util.Objects.requireNonNull;
import java.util.Optional;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models generic Java type signatures, as defined in {@jvms 4.7.9.1}.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Signature {
/** {@return the raw signature string} */
String signatureString();
/**
* Parses generic Java type signature from raw string
* @param javaTypeSignature raw Java type signature string
* @return Java type signature
*/
public static Signature parseFrom(String javaTypeSignature) {
return new SignaturesImpl().parseSignature(requireNonNull(javaTypeSignature));
}
/**
* {@return a Java type signature}
* @param classDesc the symbolic description of the Java type
*/
public static Signature of(ClassDesc classDesc) {
requireNonNull(classDesc);
if (classDesc.isArray())
return ArrayTypeSig.of(of(classDesc.componentType()));
if (classDesc.isPrimitive())
return BaseTypeSig.of(classDesc);
return ClassTypeSig.of(classDesc);
}
/**
* Models the signature of a primitive type or void
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface BaseTypeSig extends Signature
permits SignaturesImpl.BaseTypeSigImpl {
/** {@return the single-letter descriptor for the base type} */
char baseType();
/**
* {@return the signature of a primitive type or void}
* @param classDesc a symbolic descriptor for the base type, must correspond
* to a primitive type
*/
public static BaseTypeSig of(ClassDesc classDesc) {
requireNonNull(classDesc);
if (!classDesc.isPrimitive())
throw new IllegalArgumentException("primitive class type required");
return new SignaturesImpl.BaseTypeSigImpl(classDesc.descriptorString().charAt(0));
}
/**
* {@return the signature of a primitive type or void}
* @param baseType the single-letter descriptor for the base type
*/
public static BaseTypeSig of(char baseType) {
if ("VIJCSBFDZ".indexOf(baseType) < 0)
throw new IllegalArgumentException("invalid base type signature");
return new SignaturesImpl.BaseTypeSigImpl(baseType);
}
}
/**
* Models the signature of a reference type, which may be a class, interface,
* type variable, or array type.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RefTypeSig
extends Signature
permits ArrayTypeSig, ClassTypeSig, TypeVarSig {
}
/**
* Models the signature of a possibly-parameterized class or interface type.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ClassTypeSig
extends RefTypeSig, ThrowableSig
permits SignaturesImpl.ClassTypeSigImpl {
/** {@return the signature of the outer type, if any} */
Optional<ClassTypeSig> outerType();
/** {@return the class name} */
String className();
/** {@return the class name, as a symbolic descriptor} */
default ClassDesc classDesc() {
var outer = outerType();
return outer.isEmpty() ? ClassDesc.ofInternalName(className())
: outer.get().classDesc().nested(className());
}
/** {@return the type arguments of the class} */
List<TypeArg> typeArgs();
/**
* {@return a class type signature}
* @param className the name of the class
* @param typeArgs signatures of the type arguments
*/
public static ClassTypeSig of(ClassDesc className, TypeArg... typeArgs) {
return of(null, className, typeArgs);
}
/**
* {@return a class type signature for an inner class}
* @param outerType signature of the outer type
* @param className the name of the class
* @param typeArgs signatures of the type arguments
*/
public static ClassTypeSig of(ClassTypeSig outerType, ClassDesc className, TypeArg... typeArgs) {
requireNonNull(className);
return of(outerType, Util.toInternalName(className), typeArgs);
}
/**
* {@return a class type signature}
* @param className the name of the class
* @param typeArgs signatures of the type arguments
*/
public static ClassTypeSig of(String className, TypeArg... typeArgs) {
return of(null, className, typeArgs);
}
/**
* {@return a class type signature for an inner class}
* @param outerType signature of the outer type
* @param className the name of the class
* @param typeArgs signatures of the type arguments
*/
public static ClassTypeSig of(ClassTypeSig outerType, String className, TypeArg... typeArgs) {
requireNonNull(className);
return new SignaturesImpl.ClassTypeSigImpl(Optional.ofNullable(outerType), className.replace(".", "/"), List.of(typeArgs));
}
}
/**
* Models the type argument.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface TypeArg
permits SignaturesImpl.TypeArgImpl {
/**
* Indicator for whether a wildcard has default bound, no bound,
* an upper bound, or a lower bound
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public enum WildcardIndicator {
/**
* default bound wildcard (empty)
*/
DEFAULT,
/**
* unbounded indicator {@code *}
*/
UNBOUNDED,
/**
* upper-bounded indicator {@code +}
*/
EXTENDS,
/**
* lower-bounded indicator {@code -}
*/
SUPER;
}
/** {@return the wildcard indicator} */
WildcardIndicator wildcardIndicator();
/** {@return the signature of the type bound, if any} */
Optional<RefTypeSig> boundType();
/**
* {@return a bounded type arg}
* @param boundType the bound
*/
public static TypeArg of(RefTypeSig boundType) {
requireNonNull(boundType);
return of(WildcardIndicator.DEFAULT, Optional.of(boundType));
}
/**
* {@return an unbounded type arg}
*/
public static TypeArg unbounded() {
return of(WildcardIndicator.UNBOUNDED, Optional.empty());
}
/**
* {@return an upper-bounded type arg}
* @param boundType the upper bound
*/
public static TypeArg extendsOf(RefTypeSig boundType) {
requireNonNull(boundType);
return of(WildcardIndicator.EXTENDS, Optional.of(boundType));
}
/**
* {@return a lower-bounded type arg}
* @param boundType the lower bound
*/
public static TypeArg superOf(RefTypeSig boundType) {
requireNonNull(boundType);
return of(WildcardIndicator.SUPER, Optional.of(boundType));
}
/**
* {@return a bounded type arg}
* @param wildcard the wild card
* @param boundType optional bound type
*/
public static TypeArg of(WildcardIndicator wildcard, Optional<RefTypeSig> boundType) {
return new SignaturesImpl.TypeArgImpl(wildcard, boundType);
}
}
/**
* Models the signature of a type variable.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface TypeVarSig
extends RefTypeSig, ThrowableSig
permits SignaturesImpl.TypeVarSigImpl {
/** {@return the name of the type variable} */
String identifier();
/**
* {@return a signature for a type variable}
* @param identifier the name of the type variable
*/
public static TypeVarSig of(String identifier) {
return new SignaturesImpl.TypeVarSigImpl(requireNonNull(identifier));
}
}
/**
* Models the signature of an array type.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ArrayTypeSig
extends RefTypeSig
permits SignaturesImpl.ArrayTypeSigImpl {
/** {@return the signature of the component type} */
Signature componentSignature();
/**
* {@return a signature for an array type}
* @param componentSignature the component type
*/
public static ArrayTypeSig of(Signature componentSignature) {
return of(1, requireNonNull(componentSignature));
}
/**
* {@return a signature for an array type}
* @param dims the dimension of the array
* @param componentSignature the component type
*/
public static ArrayTypeSig of(int dims, Signature componentSignature) {
requireNonNull(componentSignature);
if (dims < 1 || dims > 255)
throw new IllegalArgumentException("illegal array depth value");
if (componentSignature instanceof SignaturesImpl.ArrayTypeSigImpl arr)
return new SignaturesImpl.ArrayTypeSigImpl(dims + arr.arrayDepth(), arr.elemType());
return new SignaturesImpl.ArrayTypeSigImpl(dims, componentSignature);
}
}
/**
* Models a signature for a type parameter of a generic class or method.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface TypeParam
permits SignaturesImpl.TypeParamImpl {
/** {@return the name of the type parameter} */
String identifier();
/** {@return the class bound of the type parameter} */
Optional<RefTypeSig> classBound();
/** {@return the interface bounds of the type parameter} */
List<RefTypeSig> interfaceBounds();
/**
* {@return a signature for a type parameter}
* @param identifier the name of the type parameter
* @param classBound the class bound of the type parameter
* @param interfaceBounds the interface bounds of the type parameter
*/
public static TypeParam of(String identifier, RefTypeSig classBound, RefTypeSig... interfaceBounds) {
return new SignaturesImpl.TypeParamImpl(
requireNonNull(identifier),
Optional.ofNullable(classBound),
List.of(interfaceBounds));
}
/**
* {@return a signature for a type parameter}
* @param identifier the name of the type parameter
* @param classBound the class bound of the type parameter
* @param interfaceBounds the interface bounds of the type parameter
*/
public static TypeParam of(String identifier, Optional<RefTypeSig> classBound, RefTypeSig... interfaceBounds) {
return new SignaturesImpl.TypeParamImpl(
requireNonNull(identifier),
requireNonNull(classBound),
List.of(interfaceBounds));
}
}
/**
* Models a signature for a throwable type.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ThrowableSig extends Signature {
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.SuperclassImpl;
import jdk.internal.javac.PreviewFeature;
/**
* Models the superclass of a class. Delivered as a {@link
* java.lang.classfile.ClassElement} when traversing a {@link ClassModel}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Superclass
extends ClassElement
permits SuperclassImpl {
/** {@return the superclass} */
ClassEntry superclassEntry();
/**
* {@return a {@linkplain Superclass} element}
* @param superclassEntry the superclass
*/
static Superclass of(ClassEntry superclassEntry) {
return new SuperclassImpl(superclassEntry);
}
}

View file

@ -0,0 +1,862 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.constant.ClassDesc;
import java.util.List;
import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.TargetInfoImpl;
import jdk.internal.classfile.impl.UnboundAttribute;
import static java.lang.classfile.ClassFile.TAT_CAST;
import static java.lang.classfile.ClassFile.TAT_CLASS_EXTENDS;
import static java.lang.classfile.ClassFile.TAT_CLASS_TYPE_PARAMETER;
import static java.lang.classfile.ClassFile.TAT_CLASS_TYPE_PARAMETER_BOUND;
import static java.lang.classfile.ClassFile.TAT_CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
import static java.lang.classfile.ClassFile.TAT_CONSTRUCTOR_REFERENCE;
import static java.lang.classfile.ClassFile.TAT_CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
import static java.lang.classfile.ClassFile.TAT_EXCEPTION_PARAMETER;
import static java.lang.classfile.ClassFile.TAT_FIELD;
import static java.lang.classfile.ClassFile.TAT_INSTANCEOF;
import static java.lang.classfile.ClassFile.TAT_LOCAL_VARIABLE;
import static java.lang.classfile.ClassFile.TAT_METHOD_FORMAL_PARAMETER;
import static java.lang.classfile.ClassFile.TAT_METHOD_INVOCATION_TYPE_ARGUMENT;
import static java.lang.classfile.ClassFile.TAT_METHOD_RECEIVER;
import static java.lang.classfile.ClassFile.TAT_METHOD_REFERENCE;
import static java.lang.classfile.ClassFile.TAT_METHOD_REFERENCE_TYPE_ARGUMENT;
import static java.lang.classfile.ClassFile.TAT_METHOD_RETURN;
import static java.lang.classfile.ClassFile.TAT_METHOD_TYPE_PARAMETER;
import static java.lang.classfile.ClassFile.TAT_METHOD_TYPE_PARAMETER_BOUND;
import static java.lang.classfile.ClassFile.TAT_NEW;
import static java.lang.classfile.ClassFile.TAT_RESOURCE_VARIABLE;
import static java.lang.classfile.ClassFile.TAT_THROWS;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.javac.PreviewFeature;
/**
* Models an annotation on a type use, as defined in {@jvms 4.7.19} and {@jvms 4.7.20}.
*
* @see RuntimeVisibleTypeAnnotationsAttribute
* @see RuntimeInvisibleTypeAnnotationsAttribute
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface TypeAnnotation
extends Annotation
permits UnboundAttribute.UnboundTypeAnnotation {
/**
* The kind of target on which the annotation appears, as defined in {@jvms 4.7.20.1}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public enum TargetType {
/** For annotations on a class type parameter declaration. */
CLASS_TYPE_PARAMETER(TAT_CLASS_TYPE_PARAMETER, 1),
/** For annotations on a method type parameter declaration. */
METHOD_TYPE_PARAMETER(TAT_METHOD_TYPE_PARAMETER, 1),
/** For annotations on the type of an "extends" or "implements" clause. */
CLASS_EXTENDS(TAT_CLASS_EXTENDS, 2),
/** For annotations on a bound of a type parameter of a class. */
CLASS_TYPE_PARAMETER_BOUND(TAT_CLASS_TYPE_PARAMETER_BOUND, 2),
/** For annotations on a bound of a type parameter of a method. */
METHOD_TYPE_PARAMETER_BOUND(TAT_METHOD_TYPE_PARAMETER_BOUND, 2),
/** For annotations on a field. */
FIELD(TAT_FIELD, 0),
/** For annotations on a method return type. */
METHOD_RETURN(TAT_METHOD_RETURN, 0),
/** For annotations on the method receiver. */
METHOD_RECEIVER(TAT_METHOD_RECEIVER, 0),
/** For annotations on a method parameter. */
METHOD_FORMAL_PARAMETER(TAT_METHOD_FORMAL_PARAMETER, 1),
/** For annotations on a throws clause in a method declaration. */
THROWS(TAT_THROWS, 2),
/** For annotations on a local variable. */
LOCAL_VARIABLE(TAT_LOCAL_VARIABLE, -1),
/** For annotations on a resource variable. */
RESOURCE_VARIABLE(TAT_RESOURCE_VARIABLE, -1),
/** For annotations on an exception parameter. */
EXCEPTION_PARAMETER(TAT_EXCEPTION_PARAMETER, 2),
/** For annotations on a type test. */
INSTANCEOF(TAT_INSTANCEOF, 2),
/** For annotations on an object creation expression. */
NEW(TAT_NEW, 2),
/** For annotations on a constructor reference receiver. */
CONSTRUCTOR_REFERENCE(TAT_CONSTRUCTOR_REFERENCE, 2),
/** For annotations on a method reference receiver. */
METHOD_REFERENCE(TAT_METHOD_REFERENCE, 2),
/** For annotations on a typecast. */
CAST(TAT_CAST, 3),
/** For annotations on a type argument of an object creation expression. */
CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(TAT_CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT, 3),
/** For annotations on a type argument of a method call. */
METHOD_INVOCATION_TYPE_ARGUMENT(TAT_METHOD_INVOCATION_TYPE_ARGUMENT, 3),
/** For annotations on a type argument of a constructor reference. */
CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(TAT_CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT, 3),
/** For annotations on a type argument of a method reference. */
METHOD_REFERENCE_TYPE_ARGUMENT(TAT_METHOD_REFERENCE_TYPE_ARGUMENT, 3);
private final int targetTypeValue;
private final int sizeIfFixed;
private TargetType(int targetTypeValue, int sizeIfFixed) {
this.targetTypeValue = targetTypeValue;
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;
}
}
/**
* {@return information describing precisely which type in a declaration or expression
* is annotated}
*/
TargetInfo targetInfo();
/**
* {@return which part of the type indicated by {@link #targetInfo()} is annotated}
*/
List<TypePathComponent> targetPath();
/**
* {@return a type annotation}
* @param targetInfo which type in a declaration or expression is annotated
* @param targetPath which part of the type is annotated
* @param annotationClassUtf8Entry the annotation class
* @param annotationElements the annotation elements
*/
static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
Utf8Entry annotationClassUtf8Entry,
List<AnnotationElement> annotationElements) {
return new UnboundAttribute.UnboundTypeAnnotation(targetInfo, targetPath,
annotationClassUtf8Entry, annotationElements);
}
/**
* {@return a type annotation}
* @param targetInfo which type in a declaration or expression is annotated
* @param targetPath which part of the type is annotated
* @param annotationClass the annotation class
* @param annotationElements the annotation elements
*/
static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
ClassDesc annotationClass,
AnnotationElement... annotationElements) {
return of(targetInfo, targetPath, annotationClass, List.of(annotationElements));
}
/**
* {@return a type annotation}
* @param targetInfo which type in a declaration or expression is annotated
* @param targetPath which part of the type is annotated
* @param annotationClass the annotation class
* @param annotationElements the annotation elements
*/
static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
ClassDesc annotationClass,
List<AnnotationElement> annotationElements) {
return of(targetInfo, targetPath,
TemporaryConstantPool.INSTANCE.utf8Entry(annotationClass.descriptorString()), annotationElements);
}
/**
* {@return a type annotation}
* @param targetInfo which type in a declaration or expression is annotated
* @param targetPath which part of the type is annotated
* @param annotationClassUtf8Entry the annotation class
* @param annotationElements the annotation elements
*/
static TypeAnnotation of(TargetInfo targetInfo, List<TypePathComponent> targetPath,
Utf8Entry annotationClassUtf8Entry,
AnnotationElement... annotationElements) {
return of(targetInfo, targetPath, annotationClassUtf8Entry, List.of(annotationElements));
}
/**
* Specifies which type in a declaration or expression is being annotated.
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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);
}
}
/**
* Indicates that an annotation appears on the declaration of the i'th type
* parameter of a generic class, generic interface, generic method, or
* generic constructor.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface TypeParameterTarget extends TargetInfo
permits TargetInfoImpl.TypeParameterTargetImpl {
/**
* JVMS: The value of the type_parameter_index item specifies which type parameter declaration is annotated.
* A type_parameter_index value of 0 specifies the first type parameter declaration.
*
* @return the index into the type parameters
*/
int typeParameterIndex();
}
/**
* Indicates that an annotation appears on a type in the extends or implements
* clause of a class or interface declaration.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface SupertypeTarget extends TargetInfo
permits TargetInfoImpl.SupertypeTargetImpl {
/**
* JVMS: A supertype_index value of 65535 specifies that the annotation appears on the superclass in an extends
* clause of a class declaration.
*
* Any other supertype_index value is an index into the interfaces array of the enclosing ClassFile structure,
* and specifies that the annotation appears on that superinterface in either the implements clause of a class
* declaration or the extends clause of an interface declaration.
*
* @return the index into the interfaces array or 65535 to indicate it is the superclass
*/
int supertypeIndex();
}
/**
* Indicates that an annotation appears on the i'th bound of the j'th
* type parameter declaration of a generic class, interface, method, or
* constructor.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface TypeParameterBoundTarget extends TargetInfo
permits TargetInfoImpl.TypeParameterBoundTargetImpl {
/**
* Which type parameter declaration has an annotated bound.
*
* @return the zero-origin index into the type parameters
*/
int typeParameterIndex();
/**
* Which bound of the type parameter declaration is annotated.
*
* @return the zero-origin index into bounds on the type parameter
*/
int boundIndex();
}
/**
* Indicates that an annotation appears on either the type in a field
* declaration, the return type of a method, the type of a newly constructed
* object, or the receiver type of a method or constructor.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface EmptyTarget extends TargetInfo
permits TargetInfoImpl.EmptyTargetImpl {
}
/**
* Indicates that an annotation appears on the type in a formal parameter
* declaration of a method, constructor, or lambda expression.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface FormalParameterTarget extends TargetInfo
permits TargetInfoImpl.FormalParameterTargetImpl {
/**
* Which formal parameter declaration has an annotated type.
*
* @return the index into the formal parameter declarations, in the order
* declared in the source code
*/
int formalParameterIndex();
}
/**
* Indicates that an annotation appears on the i'th type in the throws
* clause of a method or constructor declaration.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface ThrowsTarget extends TargetInfo
permits TargetInfoImpl.ThrowsTargetImpl {
/**
* The index into the exception_index_table array of the
* Exceptions attribute of the method_info structure enclosing the
* RuntimeVisibleTypeAnnotations attribute.
*
* @return the index into the list java.lang.classfile.attribute.ExceptionsAttribute.exceptions()
*/
int throwsTargetIndex();
}
/**
* Indicates that an annotation appears on the type in a local variable declaration,
* including a variable declared as a resource in a try-with-resources statement.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface LocalVarTarget extends TargetInfo
permits TargetInfoImpl.LocalVarTargetImpl {
/**
* {@return the table of local variable location/indices.}
*/
List<LocalVarTargetInfo> table();
}
/**
* Indicates a range of code array offsets within which a local variable
* has a value, and the index into the local variable array of the current
* frame at which that local variable can be found.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface LocalVarTargetInfo
permits TargetInfoImpl.LocalVarTargetInfoImpl {
/**
* 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
*/
Label startLabel();
/**
* 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 end of the bytecode section
*/
Label endLabel();
/**
* The given local variable must be at index in the local variable array of the current frame.
*
* If the local variable at index is of type double or long, it occupies both index and index + 1.
*
* @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);
}
}
/**
* Indicates that an annotation appears on the i'th type in an exception parameter
* declaration.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface CatchTarget extends TargetInfo
permits TargetInfoImpl.CatchTargetImpl {
/**
* The index into the exception_table array of the Code
* attribute enclosing the RuntimeVisibleTypeAnnotations attribute.
*
* @return the index into the exception table
*/
int exceptionTableIndex();
}
/**
* Indicates that an annotation appears on either the type in an instanceof expression
* or a new expression, or the type before the :: in a method reference expression.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface OffsetTarget extends TargetInfo
permits TargetInfoImpl.OffsetTargetImpl {
/**
* The code array offset of either the bytecode instruction
* 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 the code label corresponding to the instruction
*/
Label target();
}
/**
* Indicates that an annotation appears either 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface TypeArgumentTarget extends TargetInfo
permits TargetInfoImpl.TypeArgumentTargetImpl {
/**
* The code array offset of either the bytecode instruction
* corresponding to the cast expression, the new bytecode instruction corresponding to the new expression, the
* bytecode instruction corresponding to the explicit constructor invocation statement, the bytecode
* instruction corresponding to the method invocation expression, or the bytecode instruction corresponding to
* the method reference expression.
*
* @return the code label corresponding to the instruction
*/
Label target();
/**
* For a cast expression, the value of the type_argument_index item specifies which type in the cast
* operator is annotated. A type_argument_index value of 0 specifies the first (or only) type in the cast
* operator.
*
* The possibility of more than one type in a cast expression arises from a cast to an intersection type.
*
* For an explicit type argument list, the value of the type_argument_index item specifies which type argument
* is annotated. A type_argument_index value of 0 specifies the first type argument.
*
* @return the index into the type arguments
*/
int typeArgumentIndex();
}
/**
* JVMS: Type_path structure identifies which part of the type is annotated,
* as defined in {@jvms 4.7.20.2}
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface TypePathComponent
permits UnboundAttribute.TypePathComponentImpl {
/**
* Type path kind, as defined in {@jvms 4.7.20.2}
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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;
private Kind(int tag) {
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);
/**
* The type path kind items from JVMS Table 4.7.20.2-A.
*
* @return the kind of path element
*/
Kind typePathKind();
/**
* JVMS: type_argument_index
* If the value of the type_path_kind item is 0, 1, or 2, then the value of the type_argument_index item is 0.
*
* If the value of the type_path_kind item is 3, then the value of the type_argument_index item specifies which
* type argument of a parameterized type is annotated, where 0 indicates the first type argument of a
* parameterized type.
*
* @return the index within the type component
*/
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) {
case ARRAY -> ARRAY;
case INNER_TYPE -> INNER_TYPE;
case WILDCARD -> WILDCARD;
case TYPE_ARGUMENT -> new UnboundAttribute.TypePathComponentImpl(Kind.TYPE_ARGUMENT, typeArgumentIndex);
};
}
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.invoke.TypeDescriptor;
import jdk.internal.javac.PreviewFeature;
/**
* Describes the types that can be part of a field or method descriptor.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public enum TypeKind {
/** the primitive type byte */
ByteType("byte", "B", 8),
/** the primitive type short */
ShortType("short", "S", 9),
/** the primitive type int */
IntType("int", "I", 10),
/** the primitive type float */
FloatType("float", "F", 6),
/** the primitive type long */
LongType("long", "J", 11),
/** the primitive type double */
DoubleType("double", "D", 7),
/** a reference type */
ReferenceType("reference type", "L", -1),
/** the primitive type char */
CharType("char", "C", 5),
/** the primitive type boolean */
BooleanType("boolean", "Z", 4),
/** void */
VoidType("void", "V", -1);
private final String name;
private final String descriptor;
private final int newarraycode;
/** {@return the human-readable name corresponding to this type} */
public String typeName() { return name; }
/** {@return the field descriptor character corresponding to this type} */
public String descriptor() { return descriptor; }
/** {@return the code used by the {@code newarray} opcode corresponding to this type} */
public int newarraycode() {
return newarraycode;
}
/**
* {@return the number of local variable slots consumed by this type}
*/
public int slotSize() {
return switch (this) {
case VoidType -> 0;
case LongType, DoubleType -> 2;
default -> 1;
};
}
/**
* Erase this type kind to the type which will be used for xLOAD, xSTORE,
* and xRETURN bytecodes
* @return the erased type kind
*/
public TypeKind asLoadable() {
return switch (this) {
case BooleanType, ByteType, CharType, ShortType -> TypeKind.IntType;
default -> this;
};
}
TypeKind(String name, String descriptor, int newarraycode) {
this.name = name;
this.descriptor = descriptor;
this.newarraycode = newarraycode;
}
/**
* {@return the type kind associated with the array type described by the
* array code used as an operand to {@code newarray}}
* @param newarraycode the operand of the {@code newarray} instruction
*/
public static TypeKind fromNewArrayCode(int newarraycode) {
return switch (newarraycode) {
case 4 -> TypeKind.BooleanType;
case 5 -> TypeKind.CharType;
case 6 -> TypeKind.FloatType;
case 7 -> TypeKind.DoubleType;
case 8 -> TypeKind.ByteType;
case 9 -> TypeKind.ShortType;
case 10 -> TypeKind.IntType;
case 11 -> TypeKind.LongType;
default -> throw new IllegalArgumentException("Bad new array code: " + newarraycode);
};
}
/**
* {@return the type kind associated with the specified field descriptor}
* @param s the field descriptor
*/
public static TypeKind fromDescriptor(CharSequence s) {
return switch (s.charAt(0)) {
case '[', 'L' -> TypeKind.ReferenceType;
case 'B' -> TypeKind.ByteType;
case 'C' -> TypeKind.CharType;
case 'Z' -> TypeKind.BooleanType;
case 'S' -> TypeKind.ShortType;
case 'I' -> TypeKind.IntType;
case 'F' -> TypeKind.FloatType;
case 'J' -> TypeKind.LongType;
case 'D' -> TypeKind.DoubleType;
case 'V' -> TypeKind.VoidType;
default -> throw new IllegalArgumentException("Bad type: " + s);
};
}
/**
* {@return the type kind associated with the specified field descriptor}
* @param descriptor the field descriptor
*/
public static TypeKind from(TypeDescriptor.OfField<?> descriptor) {
return fromDescriptor(descriptor.descriptorString());
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.PoolEntry;
import jdk.internal.classfile.impl.DirectFieldBuilder;
import jdk.internal.classfile.impl.DirectMethodBuilder;
import jdk.internal.javac.PreviewFeature;
/**
* A classfile element that can encode itself as a stream of bytes in the
* encoding expected by the classfile format.
*
* @param <T> the type of the entity
*
* @sealedGraph
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface WritableElement<T> extends ClassFileElement
permits Annotation, AnnotationElement, AnnotationValue, Attribute,
PoolEntry, BootstrapMethodEntry, FieldModel, MethodModel,
ConstantPoolBuilder, DirectFieldBuilder, DirectMethodBuilder {
/**
* Writes the element to the specified writer
*
* @param buf the writer
*/
void writeTo(BufWriter buf);
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.AnnotationValue;
import java.lang.classfile.Attribute;
import java.lang.classfile.MethodElement;
import java.lang.classfile.MethodModel;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code AnnotationDefault} attribute {@jvms 4.7.22}, which can
* 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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface AnnotationDefaultAttribute
extends Attribute<AnnotationDefaultAttribute>, MethodElement
permits BoundAttribute.BoundAnnotationDefaultAttr,
UnboundAttribute.UnboundAnnotationDefaultAttribute {
/**
* {@return the default value of the annotation type element represented by
* this method}
*/
AnnotationValue defaultValue();
/**
* {@return an {@code AnnotationDefault} attribute}
* @param annotationDefault the default value of the annotation type element
*/
static AnnotationDefaultAttribute of(AnnotationValue annotationDefault) {
return new UnboundAttribute.UnboundAnnotationDefaultAttribute(annotationDefault);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.BootstrapMethodEntry;
import java.lang.classfile.constantpool.ConstantPool;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* 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.
* <p>
* The attribute was introduced in the Java SE Platform version 7.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface BootstrapMethodsAttribute
extends Attribute<BootstrapMethodsAttribute>
permits BoundAttribute.BoundBootstrapMethodsAttribute,
UnboundAttribute.EmptyBootstrapAttribute {
/**
* {@return the elements of the bootstrap method table}
*/
List<BootstrapMethodEntry> bootstrapMethods();
/**
* {@return the size of the bootstrap methods table}. Calling this method
* does not necessarily inflate the entire table.
*/
int bootstrapMethodsSize();
// No factories; BMA is generated as part of constant pool
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single character range in the {@link CharacterRangeTableAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CharacterRangeInfo
permits UnboundAttribute.UnboundCharacterRangeInfo {
/**
* {@return the start of the character range region (inclusive)} This is
* the index into the code array at which the code for this character range
* begins.
*/
int startPc();
/**
* {@return the end of the character range region (exclusive)} This is the
* index into the code array after which the code for this character range
* ends.
*/
int endPc();
/**
* {@return the encoded start of the character range region (inclusive)}
* The value is constructed from the line_number/column_number pair as given
* by {@code line_number << 10 + column_number}, where the source file is
* viewed as an array of (possibly multi-byte) characters.
*/
int characterRangeStart();
/**
* {@return the encoded end of the character range region (exclusive)}.
* The value is constructed from the line_number/column_number pair as given
* by {@code line_number << 10 + column_number}, where the source file is
* viewed as an array of (possibly multi-byte) characters.
*/
int characterRangeEnd();
/**
* The value of the flags item describes the kind of range. Multiple flags
* may be set within flags.
* <ul>
* <li>{@link java.lang.classfile.ClassFile#CRT_STATEMENT} Range is a Statement
* (except ExpressionStatement), StatementExpression {@jls 14.8}, as well as each
* VariableDeclaratorId = VariableInitializer of
* LocalVariableDeclarationStatement {@jls 14.4} or FieldDeclaration {@jls 8.3} in the
* grammar.
* <li>{@link java.lang.classfile.ClassFile#CRT_BLOCK} Range is a Block in the
* grammar.
* <li>{@link java.lang.classfile.ClassFile#CRT_ASSIGNMENT} Range is an assignment
* expression - Expression1 AssignmentOperator Expression1 in the grammar as
* well as increment and decrement expressions (both prefix and postfix).
* <li>{@link java.lang.classfile.ClassFile#CRT_FLOW_CONTROLLER} An expression
* whose value will effect control flow. {@code Flowcon} in the following:
* <pre>
* if ( Flowcon ) Statement [else Statement]
* for ( ForInitOpt ; [Flowcon] ; ForUpdateOpt ) Statement
* while ( Flowcon ) Statement
* do Statement while ( Flowcon ) ;
* switch ( Flowcon ) { SwitchBlockStatementGroups }
* Flowcon || Expression3
* Flowcon &amp;&amp; Expression3
* Flowcon ? Expression : Expression1
* </pre>
* <li>{@link java.lang.classfile.ClassFile#CRT_FLOW_TARGET} Statement or
* expression effected by a CRT_FLOW_CONTROLLER. {@code Flowtarg} in the following:
* <pre>
* if ( Flowcon ) Flowtarg [else Flowtarg]
* for ( ForInitOpt ; [Flowcon] ; ForUpdateOpt ) Flowtarg
* while ( Flowcon ) Flowtarg
* do Flowtarg while ( Flowcon ) ;
* Flowcon || Flowtarg
* Flowcon &amp;&amp; Flowtarg
* Flowcon ? Flowtarg : Flowtarg
* </pre>
* <li>{@link java.lang.classfile.ClassFile#CRT_INVOKE} Method invocation. For
* example: Identifier Arguments.
* <li>{@link java.lang.classfile.ClassFile#CRT_CREATE} New object creation. For
* example: new Creator.
* <li>{@link java.lang.classfile.ClassFile#CRT_BRANCH_TRUE} A condition encoded
* in the branch instruction immediately contained in the code range for
* this item is not inverted towards the corresponding branch condition in
* the source code. I.e. actual jump occurs if and only if the the source
* code branch condition evaluates to true. Entries of this type are
* produced only for conditions that are listed in the description of
* CRT_FLOW_CONTROLLER flag. The source range for the entry contains flow
* controlling expression. start_pc field for an entry of this type must
* point to a branch instruction: if_acmp&lt;cond&gt;, if_icmp&lt;cond&gt;,
* if&lt;cond&gt;, ifnonull, ifnull or goto. CRT_BRANCH_TRUE and
* CRT_BRANCH_FALSE are special kinds of entries that can be used to
* determine what branch of a condition was chosen during the runtime.
* <li>{@link java.lang.classfile.ClassFile#CRT_BRANCH_FALSE} A condition encoded
* in the branch instruction immediately contained in the code range for
* this item is inverted towards the corresponding branch condition in the
* source code. I.e. actual jump occurs if and only if the the source code
* branch condition evaluates to false. Entries of this type are produced
* only for conditions that are listed in the description of
* CRT_FLOW_CONTROLLER flag. The source range for the entry contains flow
* controlling expression. start_pc field for an entry of this type must
* point to a branch instruction: if_acmp&lt;cond&gt;, if_icmp&lt;cond&gt;,
* if&lt;cond&gt;, ifnonull, ifnull or goto.
* </ul>
* <p>
* All bits of the flags item not assigned above are reserved for future use. They should be set to zero in generated class files and should be ignored by Java virtual machine implementations.
*
* @return the flags
*/
int flags();
/**
* {@return a character range description}
* @param startPc the start of the bytecode range, inclusive
* @param endPc the end of the bytecode range, exclusive
* @param characterRangeStart the start of the character range, inclusive,
* encoded as {@code line_number << 10 + column_number}
* @param characterRangeEnd the end of the character range, exclusive,
* encoded as {@code line_number << 10 + column_number}
* @param flags the range flags
*/
static CharacterRangeInfo of(int startPc,
int endPc,
int characterRangeStart,
int characterRangeEnd,
int flags) {
return new UnboundAttribute.UnboundCharacterRangeInfo(startPc, endPc,
characterRangeStart, characterRangeEnd,
flags);
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* The CharacterRangeTable attribute is an optional variable-length attribute in
* the attributes table of a {@code Code} attribute. It may be used by debuggers
* to determine which part of the Java virtual machine code array corresponds to
* a given position in the source file or to determine what section of source
* code corresponds to a given index into the code array. The
* CharacterRangeTable attribute consists of an array of character range entries.
* Each character range entry within the table associates a range of indices in
* the code array with a range of character indices in the source file. If the
* source file is viewed as an array of characters, a character index is the
* corresponding index into this array. Note that character indices are not the
* same as byte indices as multi-byte characters may be present in the source
* file. Each character range entry includes a flag which indicates what kind of
* range is described: statement, assignment, method call, etc. Both code index
* ranges and character ranges may nest within other ranges, but they may not
* partially overlap. Thus, a given code index may correspond to several
* character range entries and in turn several character ranges, but there will
* be a smallest character range, and for each kind of range in which it is
* enclosed there will be a smallest character range. Similarly, a given
* character index may correspond to several character range entries and in turn
* 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CharacterRangeTableAttribute
extends Attribute<CharacterRangeTableAttribute>
permits BoundAttribute.BoundCharacterRangeTableAttribute,
UnboundAttribute.UnboundCharacterRangeTableAttribute {
/**
* {@return the entries of the character range table}
*/
List<CharacterRangeInfo> characterRangeTable();
/**
* {@return a {@code CharacterRangeTable} attribute}
* @param ranges the descriptions of the character ranges
*/
static CharacterRangeTableAttribute of(List<CharacterRangeInfo> ranges) {
return new UnboundAttribute.UnboundCharacterRangeTableAttribute(ranges);
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.CodeModel;
import java.lang.classfile.Label;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Code} attribute {@jvms 4.7.3}, appears on non-native,
* non-abstract methods and contains the bytecode of the method body. Delivered
* as a {@link java.lang.classfile.MethodElement} when traversing the elements of a
* {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CodeAttribute extends Attribute<CodeAttribute>, CodeModel
permits BoundAttribute.BoundCodeAttribute {
/**
* {@return The length of the code array in bytes}
*/
int codeLength();
/**
* {@return the bytes (bytecode) of the code array}
*/
byte[] codeArray();
/**
* {@return the position of the {@code Label} in the {@code codeArray}
* or -1 if the {@code Label} does not point to the {@code codeArray}}
* @param label a marker for a position within this {@code CodeAttribute}
*/
int labelToBci(Label label);
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code CompilationID} attribute (@@@ need reference), which can
* appear on classes and records the compilation time of the class. Delivered
* as a {@link java.lang.classfile.ClassElement} when traversing the elements of
* a {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface CompilationIDAttribute
extends Attribute<CompilationIDAttribute>, ClassElement
permits BoundAttribute.BoundCompilationIDAttribute,
UnboundAttribute.UnboundCompilationIDAttribute {
/**
* {@return the compilation ID} The compilation ID is the value of
* {@link System#currentTimeMillis()} when the classfile is generated.
*/
Utf8Entry compilationId();
/**
* {@return a {@code CompilationID} attribute}
* @param id the compilation ID
*/
static CompilationIDAttribute of(Utf8Entry id) {
return new UnboundAttribute.UnboundCompilationIDAttribute(id);
}
/**
* {@return a {@code CompilationID} attribute}
* @param id the compilation ID
*/
static CompilationIDAttribute of(String id) {
return new UnboundAttribute.UnboundCompilationIDAttribute(TemporaryConstantPool.INSTANCE.utf8Entry(id));
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ConstantDesc;
import java.lang.classfile.Attribute;
import java.lang.classfile.FieldElement;
import java.lang.classfile.constantpool.ConstantValueEntry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ConstantValue} attribute {@jvms 4.7.2}, which can appear on
* fields and indicates that the field's value is a constant. Delivered as a
* {@link java.lang.classfile.FieldElement} when traversing the elements of a
* {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ConstantValueAttribute
extends Attribute<ConstantValueAttribute>, FieldElement
permits BoundAttribute.BoundConstantValueAttribute,
UnboundAttribute.UnboundConstantValueAttribute {
/**
* {@return the constant value of the field}
*/
ConstantValueEntry constant();
/**
* {@return a {@code ConstantValue} attribute}
* @param value the constant value
*/
static ConstantValueAttribute of(ConstantValueEntry value) {
return new UnboundAttribute.UnboundConstantValueAttribute(value);
}
/**
* {@return a {@code ConstantValue} attribute}
* @param value the constant value
*/
static ConstantValueAttribute of(ConstantDesc value) {
return of(switch(value) {
case Integer i -> TemporaryConstantPool.INSTANCE.intEntry(i);
case Float f -> TemporaryConstantPool.INSTANCE.floatEntry(f);
case Long l -> TemporaryConstantPool.INSTANCE.longEntry(l);
case Double d -> TemporaryConstantPool.INSTANCE.doubleEntry(d);
case String s -> TemporaryConstantPool.INSTANCE.stringEntry(s);
default -> throw new IllegalArgumentException("Invalid ConstantValueAttribute value: " + value);
});
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Deprecated} attribute {@jvms 4.7.15}, which can appear on
* 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface DeprecatedAttribute
extends Attribute<DeprecatedAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundDeprecatedAttribute,
UnboundAttribute.UnboundDeprecatedAttribute {
/**
* {@return a {@code Deprecated} attribute}
*/
static DeprecatedAttribute of() {
return new UnboundAttribute.UnboundDeprecatedAttribute();
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.util.Optional;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.NameAndTypeEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code EnclosingMethod} attribute {@jvms 4.7.7}, which can appear
* 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
* java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface EnclosingMethodAttribute
extends Attribute<EnclosingMethodAttribute>, ClassElement
permits BoundAttribute.BoundEnclosingMethodAttribute,
UnboundAttribute.UnboundEnclosingMethodAttribute {
/**
* {@return the innermost class that encloses the declaration of the current
* class}
*/
ClassEntry enclosingClass();
/**
* {@return the name and type of the enclosing method, if the class is
* immediately enclosed by a method or constructor}
*/
Optional<NameAndTypeEntry> enclosingMethod();
/**
* {@return the name of the enclosing method, if the class is
* immediately enclosed by a method or constructor}
*/
default Optional<Utf8Entry> enclosingMethodName() {
return enclosingMethod().map(NameAndTypeEntry::name);
}
/**
* {@return the type of the enclosing method, if the class is
* immediately enclosed by a method or constructor}
*/
default Optional<Utf8Entry> enclosingMethodType() {
return enclosingMethod().map(NameAndTypeEntry::type);
}
/**
* {@return the type of the enclosing method, if the class is
* immediately enclosed by a method or constructor}
*/
default Optional<MethodTypeDesc> enclosingMethodTypeSymbol() {
return enclosingMethod().map(Util::methodTypeSymbol);
}
/**
* {@return an {@code EnclosingMethod} attribute}
* @param className the class name
* @param method the name and type of the enclosing method or {@code empty} if
* the class is not immediately enclosed by a method or constructor
*/
static EnclosingMethodAttribute of(ClassEntry className,
Optional<NameAndTypeEntry> method) {
return new UnboundAttribute.UnboundEnclosingMethodAttribute(className, method.orElse(null));
}
/**
* {@return an {@code EnclosingMethod} attribute}
* @param className the class name
* @param methodName the name of the enclosing method or {@code empty} if
* the class is not immediately enclosed by a method or constructor
* @param methodType the type of the enclosing method or {@code empty} if
* the class is not immediately enclosed by a method or constructor
* @throws IllegalArgumentException if {@code className} represents a primitive type
*/
static EnclosingMethodAttribute of(ClassDesc className,
Optional<String> methodName,
Optional<MethodTypeDesc> methodType) {
return new UnboundAttribute.UnboundEnclosingMethodAttribute(
TemporaryConstantPool.INSTANCE.classEntry(className),
methodName.isPresent() && methodType.isPresent()
? TemporaryConstantPool.INSTANCE.nameAndTypeEntry(methodName.get(), methodType.get())
: null);
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.MethodElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Exceptions} attribute {@jvms 4.7.5}, which can appear on
* methods, and records the exceptions declared to be thrown by this method.
* Delivered as a {@link MethodElement} when traversing the elements of a
* {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ExceptionsAttribute
extends Attribute<ExceptionsAttribute>, MethodElement
permits BoundAttribute.BoundExceptionsAttribute,
UnboundAttribute.UnboundExceptionsAttribute {
/**
* {@return the exceptions declared to be thrown by this method}
*/
List<ClassEntry> exceptions();
/**
* {@return an {@code Exceptions} attribute}
* @param exceptions the checked exceptions that may be thrown from this method
*/
static ExceptionsAttribute of(List<ClassEntry> exceptions) {
return new UnboundAttribute.UnboundExceptionsAttribute(exceptions);
}
/**
* {@return an {@code Exceptions} attribute}
* @param exceptions the checked exceptions that may be thrown from this method
*/
static ExceptionsAttribute of(ClassEntry... exceptions) {
return of(List.of(exceptions));
}
/**
* {@return an {@code Exceptions} attribute}
* @param exceptions the checked exceptions that may be thrown from this method
*/
static ExceptionsAttribute ofSymbols(List<ClassDesc> exceptions) {
return of(Util.entryList(exceptions));
}
/**
* {@return an {@code Exceptions} attribute}
* @param exceptions the checked exceptions that may be thrown from this method
*/
static ExceptionsAttribute ofSymbols(ClassDesc... exceptions) {
return ofSymbols(Arrays.asList(exceptions));
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Optional;
import java.util.Set;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import java.lang.reflect.AccessFlag;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single inner class in the {@link InnerClassesAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface InnerClassInfo
permits UnboundAttribute.UnboundInnerClassInfo {
/**
* {@return the class described by this inner class description}
*/
ClassEntry innerClass();
/**
* {@return the class or interface of which this class is a member, if it is a
* member of a class or interface}
*/
Optional<ClassEntry> outerClass();
/**
* {@return the simple name of this class, or empty if this class is anonymous}
*/
Optional<Utf8Entry> innerName();
/**
* {@return a bit mask of flags denoting access permissions and properties
* of the inner class}
*/
int flagsMask();
/**
* {@return a set of flag enums denoting access permissions and properties
* of the inner class}
*/
default Set<AccessFlag> flags() {
return AccessFlag.maskToAccessFlags(flagsMask(), AccessFlag.Location.INNER_CLASS);
}
/**
* {@return whether a specific access flag is set}
* @param flag the access flag
*/
default boolean has(AccessFlag flag) {
return Util.has(AccessFlag.Location.INNER_CLASS, flagsMask(), flag);
}
/**
* {@return an inner class description}
* @param innerClass the inner class being described
* @param outerClass the class containing the inner class, if any
* @param innerName the name of the inner class, if it is not anonymous
* @param flags the inner class access flags
*/
static InnerClassInfo of(ClassEntry innerClass, Optional<ClassEntry> outerClass,
Optional<Utf8Entry> innerName, int flags) {
return new UnboundAttribute.UnboundInnerClassInfo(innerClass, outerClass, innerName, flags);
}
/**
* {@return an inner class description}
* @param innerClass the inner class being described
* @param outerClass the class containing the inner class, if any
* @param innerName the name of the inner class, if it is not anonymous
* @param flags the inner class access flags
* @throws IllegalArgumentException if {@code innerClass} or {@code outerClass} represents a primitive type
*/
static InnerClassInfo of(ClassDesc innerClass, Optional<ClassDesc> outerClass, Optional<String> innerName, int flags) {
return new UnboundAttribute.UnboundInnerClassInfo(TemporaryConstantPool.INSTANCE.classEntry(innerClass),
outerClass.map(TemporaryConstantPool.INSTANCE::classEntry),
innerName.map(TemporaryConstantPool.INSTANCE::utf8Entry),
flags);
}
/**
* {@return an inner class description}
* @param innerClass the inner class being described
* @param outerClass the class containing the inner class, if any
* @param innerName the name of the inner class, if it is not anonymous
* @param flags the inner class access flags
* @throws IllegalArgumentException if {@code innerClass} or {@code outerClass} represents a primitive type
*/
static InnerClassInfo of(ClassDesc innerClass, Optional<ClassDesc> outerClass, Optional<String> innerName, AccessFlag... flags) {
return of(innerClass, outerClass, innerName, Util.flagsToBits(AccessFlag.Location.INNER_CLASS, flags));
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code InnerClasses} attribute {@jvms 4.7.6}, which can
* appear on classes, and records which classes referenced by this classfile
* are inner classes. Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface InnerClassesAttribute
extends Attribute<InnerClassesAttribute>, ClassElement
permits BoundAttribute.BoundInnerClassesAttribute,
UnboundAttribute.UnboundInnerClassesAttribute {
/**
* {@return the inner classes used by this class}
*/
List<InnerClassInfo> classes();
/**
* {@return an {@code InnerClasses} attribute}
* @param innerClasses descriptions of the inner classes
*/
static InnerClassesAttribute of(List<InnerClassInfo> innerClasses) {
return new UnboundAttribute.UnboundInnerClassesAttribute(innerClasses);
}
/**
* {@return an {@code InnerClasses} attribute}
* @param innerClasses descriptions of the inner classes
*/
static InnerClassesAttribute of(InnerClassInfo... innerClasses) {
return new UnboundAttribute.UnboundInnerClassesAttribute(List.of(innerClasses));
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single line number in the {@link LineNumberTableAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LineNumberInfo
permits UnboundAttribute.UnboundLineNumberInfo {
/**
* {@return the index into the code array at which the code for this line
* begins}
*/
int startPc();
/**
* {@return the line number within the original source file}
*/
int lineNumber();
/**
* {@return a line number description}
* @param startPc the starting index of the code array for this line
* @param lineNumber the line number within the original source file
*/
public static LineNumberInfo of(int startPc, int lineNumber) {
return new UnboundAttribute.UnboundLineNumberInfo(startPc, lineNumber);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code LineNumberTable} attribute {@jvms 4.7.12}, which can appear
* on a {@code Code} attribute, and records the mapping between indexes into
* the code table and line numbers in the source file.
* Delivered as a {@link java.lang.classfile.instruction.LineNumber} when traversing the
* elements of a {@link java.lang.classfile.CodeModel}, according to the setting of the
* {@link java.lang.classfile.ClassFile.LineNumbersOption} option.
* <p>
* The attribute permits multiple instances in a given location.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LineNumberTableAttribute
extends Attribute<LineNumberTableAttribute>
permits BoundAttribute.BoundLineNumberTableAttribute,
UnboundAttribute.UnboundLineNumberTableAttribute {
/**
* {@return the table mapping bytecode offsets to source line numbers}
*/
List<LineNumberInfo> lineNumbers();
/**
* {@return a {@code LineNumberTable} attribute}
* @param lines the line number descriptions
*/
static LineNumberTableAttribute of(List<LineNumberInfo> lines) {
return new UnboundAttribute.UnboundLineNumberTableAttribute(lines);
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundLocalVariable;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single local variable in the {@link LocalVariableTableAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LocalVariableInfo
permits UnboundAttribute.UnboundLocalVariableInfo, BoundLocalVariable {
/**
* {@return the index into the code array (inclusive) at which the scope of
* this variable begins}
*/
int startPc();
/**
* {@return the length of the region of the code array in which this
* variable is in scope.}
*/
int length();
/**
* {@return the name of the local variable}
*/
Utf8Entry name();
/**
* {@return the field descriptor of the local variable}
*/
Utf8Entry type();
/**
* {@return the field descriptor of the local variable}
*/
default ClassDesc typeSymbol() {
return ClassDesc.ofDescriptor(type().stringValue());
}
/**
* {@return the index into the local variable array of the current frame
* which holds this local variable}
*/
int slot();
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code LocalVariableTable} attribute {@jvms 4.7.13}, which can appear
* on a {@code Code} attribute, and records debug information about local
* variables.
* Delivered as a {@link java.lang.classfile.instruction.LocalVariable} when traversing the
* elements of a {@link java.lang.classfile.CodeModel}, according to the setting of the
* {@link java.lang.classfile.ClassFile.DebugElementsOption} option.
* <p>
* The attribute permits multiple instances in a given location.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LocalVariableTableAttribute
extends Attribute<LocalVariableTableAttribute>
permits BoundAttribute.BoundLocalVariableTableAttribute, UnboundAttribute.UnboundLocalVariableTableAttribute {
/**
* {@return debug information for the local variables in this method}
*/
List<LocalVariableInfo> localVariables();
/**
* {@return a {@code LocalVariableTable} attribute}
* @param locals the local variable descriptions
*/
static LocalVariableTableAttribute of(List<LocalVariableInfo> locals) {
return new UnboundAttribute.UnboundLocalVariableTableAttribute(locals);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundLocalVariableType;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single local variable in the {@link LocalVariableTypeTableAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LocalVariableTypeInfo
permits UnboundAttribute.UnboundLocalVariableTypeInfo, BoundLocalVariableType {
/**
* {@return the index into the code array (inclusive) at which the scope of
* this variable begins}
*/
int startPc();
/**
* {@return the length of the region of the code array in which this
* variable is in scope.}
*/
int length();
/**
* {@return the name of the local variable}
*/
Utf8Entry name();
/**
* {@return the field signature of the local variable}
*/
Utf8Entry signature();
/**
* {@return the index into the local variable array of the current frame
* which holds this local variable}
*/
int slot();
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code LocalVariableTypeTable} attribute {@jvms 4.7.14}, which can appear
* on a {@code Code} attribute, and records debug information about local
* variables.
* Delivered as a {@link java.lang.classfile.instruction.LocalVariable} when traversing the
* elements of a {@link java.lang.classfile.CodeModel}, according to the setting of the
* {@link java.lang.classfile.ClassFile.LineNumbersOption} option.
* <p>
* The attribute permits multiple instances in a given location.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LocalVariableTypeTableAttribute
extends Attribute<LocalVariableTypeTableAttribute>
permits BoundAttribute.BoundLocalVariableTypeTableAttribute, UnboundAttribute.UnboundLocalVariableTypeTableAttribute {
/**
* {@return debug information for the local variables in this method}
*/
List<LocalVariableTypeInfo> localVariableTypes();
/**
* {@return a {@code LocalVariableTypeTable} attribute}
* @param locals the local variable descriptions
*/
static LocalVariableTypeTableAttribute of(List<LocalVariableTypeInfo> locals) {
return new UnboundAttribute.UnboundLocalVariableTypeTableAttribute(locals);
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.Optional;
import java.util.Set;
import java.lang.classfile.constantpool.Utf8Entry;
import java.lang.reflect.AccessFlag;
import java.lang.classfile.ClassFile;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single method parameter in the {@link MethodParametersAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodParameterInfo
permits UnboundAttribute.UnboundMethodParameterInfo {
/**
* The name of the method parameter, if there is one.
*
* @return the parameter name, if it has one
*/
Optional<Utf8Entry> name();
/**
* Parameter access flags for this parameter, as a bit mask. Valid
* parameter flags include {@link ClassFile#ACC_FINAL},
* {@link ClassFile#ACC_SYNTHETIC}, and {@link ClassFile#ACC_MANDATED}.
*
* @return the access flags, as a bit mask
*/
int flagsMask();
/**
* Parameter access flags for this parameter.
*
* @return the access flags, as a bit mask
*/
default Set<AccessFlag> flags() {
return AccessFlag.maskToAccessFlags(flagsMask(), AccessFlag.Location.METHOD_PARAMETER);
}
/**
* {@return whether the method parameter has a specific flag set}
* @param flag the method parameter flag
*/
default boolean has(AccessFlag flag) {
return Util.has(AccessFlag.Location.METHOD_PARAMETER, flagsMask(), flag);
}
/**
* {@return a method parameter description}
* @param name the method parameter name
* @param flags the method parameter access flags
*/
static MethodParameterInfo of(Optional<Utf8Entry> name, int flags) {
return new UnboundAttribute.UnboundMethodParameterInfo(name, flags);
}
/**
* {@return a method parameter description}
* @param name the method parameter name
* @param flags the method parameter access flags
*/
static MethodParameterInfo of(Optional<String> name, AccessFlag... flags) {
return of(name.map(TemporaryConstantPool.INSTANCE::utf8Entry), Util.flagsToBits(AccessFlag.Location.METHOD_PARAMETER, flags));
}
/**
* {@return a method parameter description}
* @param name the method parameter name
* @param flags the method parameter access flags
*/
static MethodParameterInfo ofParameter(Optional<String> name, int flags) {
return of(name.map(TemporaryConstantPool.INSTANCE::utf8Entry), flags);
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.MethodElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code MethodParameters} attribute {@jvms 4.7.24}, which can
* appear on methods, and records optional information about the method's
* parameters. Delivered as a {@link java.lang.classfile.MethodElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 8.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MethodParametersAttribute
extends Attribute<MethodParametersAttribute>, MethodElement
permits BoundAttribute.BoundMethodParametersAttribute,
UnboundAttribute.UnboundMethodParametersAttribute {
/**
* {@return information about the parameters of the method} The i'th entry
* in the list corresponds to the i'th parameter in the method declaration.
*/
List<MethodParameterInfo> parameters();
/**
* {@return a {@code MethodParameters} attribute}
* @param parameters the method parameter descriptions
*/
static MethodParametersAttribute of(List<MethodParameterInfo> parameters) {
return new UnboundAttribute.UnboundMethodParametersAttribute(parameters);
}
/**
* {@return a {@code MethodParameters} attribute}
* @param parameters the method parameter descriptions
*/
static MethodParametersAttribute of(MethodParameterInfo... parameters) {
return of(List.of(parameters));
}
}

View file

@ -0,0 +1,329 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Collection;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.lang.reflect.AccessFlag;
import java.lang.constant.ModuleDesc;
import java.lang.constant.PackageDesc;
import jdk.internal.classfile.impl.ModuleAttributeBuilderImpl;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Module} attribute {@jvms 4.7.25}, which can
* appear on classes that represent module descriptors.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 9.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleAttribute
extends Attribute<ModuleAttribute>, ClassElement
permits BoundAttribute.BoundModuleAttribute, UnboundAttribute.UnboundModuleAttribute {
/**
* {@return the name of the module}
*/
ModuleEntry moduleName();
/**
* {@return the the module flags of the module, as a bit mask}
*/
int moduleFlagsMask();
/**
* {@return the the module flags of the module, as a set of enum constants}
*/
default Set<AccessFlag> moduleFlags() {
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 the version of the module, if present}
*/
Optional<Utf8Entry> moduleVersion();
/**
* {@return the modules required by this module}
*/
List<ModuleRequireInfo> requires();
/**
* {@return the packages exported by this module}
*/
List<ModuleExportInfo> exports();
/**
* {@return the packages opened by this module}
*/
List<ModuleOpenInfo> opens();
/**
* {@return the services used by this module} Services may be discovered via
* {@link java.util.ServiceLoader}.
*/
List<ClassEntry> uses();
/**
* {@return the service implementations provided by this module}
*/
List<ModuleProvideInfo> provides();
/**
* {@return a {@code Module} attribute}
*
* @param moduleName the module name
* @param moduleFlags the module flags
* @param moduleVersion the module version
* @param requires the required packages
* @param exports the exported packages
* @param opens the opened packages
* @param uses the consumed services
* @param provides the provided services
*/
static ModuleAttribute of(ModuleEntry moduleName, int moduleFlags,
Utf8Entry moduleVersion,
Collection<ModuleRequireInfo> requires,
Collection<ModuleExportInfo> exports,
Collection<ModuleOpenInfo> opens,
Collection<ClassEntry> uses,
Collection<ModuleProvideInfo> provides) {
return new UnboundAttribute.UnboundModuleAttribute(moduleName, moduleFlags, moduleVersion, requires, exports, opens, uses, provides);
}
/**
* {@return a {@code Module} attribute}
*
* @param moduleName the module name
* @param attrHandler a handler that receives a {@link ModuleAttributeBuilder}
*/
static ModuleAttribute of(ModuleDesc moduleName,
Consumer<ModuleAttributeBuilder> attrHandler) {
var mb = new ModuleAttributeBuilderImpl(moduleName);
attrHandler.accept(mb);
return mb.build();
}
/**
* {@return a {@code Module} attribute}
*
* @param moduleName the module name
* @param attrHandler a handler that receives a {@link ModuleAttributeBuilder}
*/
static ModuleAttribute of(ModuleEntry moduleName,
Consumer<ModuleAttributeBuilder> attrHandler) {
var mb = new ModuleAttributeBuilderImpl(moduleName);
attrHandler.accept(mb);
return mb.build();
}
/**
* A builder for module attributes.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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);
/**
* Opens package
* @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);
/**
* Opens package
* @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
* @throws IllegalArgumentException if {@code service} represents a primitive type
*/
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
* @throws IllegalArgumentException if {@code service} or any of the {@code implClasses} represents a primitive type
*/
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();
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.constant.ModuleDesc;
import java.lang.constant.PackageDesc;
import java.lang.reflect.AccessFlag;
import java.lang.classfile.ClassFile;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single "exports" declaration in the {@link ModuleAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleExportInfo
permits UnboundAttribute.UnboundModuleExportInfo {
/**
* {@return the exported package}
*/
PackageEntry exportedPackage();
/**
* {@return the flags associated with this export declaration, as a bit mask}
* Valid flags include {@link ClassFile#ACC_SYNTHETIC} and
* {@link ClassFile#ACC_MANDATED}.
*/
int exportsFlagsMask();
/**
* {@return the flags associated with this export declaration, as a set of
* flag values}
*/
default Set<AccessFlag> exportsFlags() {
return AccessFlag.maskToAccessFlags(exportsFlagsMask(), AccessFlag.Location.MODULE_EXPORTS);
}
/**
* {@return the list of modules to which this package is exported, if it is a
* qualified export}
*/
List<ModuleEntry> exportsTo();
/**
* {@return whether the module has the specified access flag set}
* @param flag the access flag
*/
default boolean has(AccessFlag flag) {
return Util.has(AccessFlag.Location.MODULE_EXPORTS, exportsFlagsMask(), flag);
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags, as a bitmask
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageEntry exports, int exportFlags,
List<ModuleEntry> exportsTo) {
return new UnboundAttribute.UnboundModuleExportInfo(exports, exportFlags, exportsTo);
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageEntry exports, Collection<AccessFlag> exportFlags,
List<ModuleEntry> exportsTo) {
return of(exports, Util.flagsToBits(AccessFlag.Location.MODULE_EXPORTS, exportFlags), exportsTo);
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags, as a bitmask
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageEntry exports,
int exportFlags,
ModuleEntry... exportsTo) {
return of(exports, exportFlags, List.of(exportsTo));
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageEntry exports,
Collection<AccessFlag> exportFlags,
ModuleEntry... exportsTo) {
return of(exports, Util.flagsToBits(AccessFlag.Location.MODULE_EXPORTS, exportFlags), exportsTo);
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags, as a bitmask
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageDesc exports, int exportFlags,
List<ModuleDesc> exportsTo) {
return of(TemporaryConstantPool.INSTANCE.packageEntry(TemporaryConstantPool.INSTANCE.utf8Entry(exports.internalName())),
exportFlags,
Util.moduleEntryList(exportsTo));
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageDesc exports, Collection<AccessFlag> exportFlags,
List<ModuleDesc> exportsTo) {
return of(exports, Util.flagsToBits(AccessFlag.Location.MODULE_EXPORTS, exportFlags), exportsTo);
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags, as a bitmask
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageDesc exports,
int exportFlags,
ModuleDesc... exportsTo) {
return of(exports, exportFlags, List.of(exportsTo));
}
/**
* {@return a module export description}
* @param exports the exported package
* @param exportFlags the export flags
* @param exportsTo the modules to which this package is exported
*/
static ModuleExportInfo of(PackageDesc exports,
Collection<AccessFlag> exportFlags,
ModuleDesc... exportsTo) {
return of(exports, Util.flagsToBits(AccessFlag.Location.MODULE_EXPORTS, exportFlags), exportsTo);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.constant.ModuleDesc;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models hash information for a single module in the {@link ModuleHashesAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleHashInfo
permits UnboundAttribute.UnboundModuleHashInfo {
/**
* {@return the name of the related module}
*/
ModuleEntry moduleName();
/**
* {@return the hash of the related module}
*/
byte[] hash();
/**
* {@return a module hash description}
* @param moduleName the module name
* @param hash the hash value
*/
static ModuleHashInfo of(ModuleEntry moduleName, byte[] hash) {
return new UnboundAttribute.UnboundModuleHashInfo(moduleName, hash);
}
/**
* {@return a module hash description}
* @param moduleDesc the module name
* @param hash the hash value
*/
static ModuleHashInfo of(ModuleDesc moduleDesc, byte[] hash) {
return new UnboundAttribute.UnboundModuleHashInfo(TemporaryConstantPool.INSTANCE.moduleEntry(TemporaryConstantPool.INSTANCE.utf8Entry(moduleDesc.name())), hash);
}
}

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.util.List;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ModuleHashes} attribute, which can
* appear on classes that represent module descriptors. This is a JDK-specific
* attribute, which captures the hashes of a set of co-delivered modules.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.classfile.ClassModel}.
*
* <p>The specification of the {@code ModuleHashes} attribute is:
* <pre> {@code
*
* ModuleHashes_attribute {
* // index to CONSTANT_utf8_info structure in constant pool representing
* // the string "ModuleHashes"
* u2 attribute_name_index;
* u4 attribute_length;
*
* // index to CONSTANT_utf8_info structure with algorithm name
* u2 algorithm_index;
*
* // the number of entries in the hashes table
* u2 hashes_count;
* { u2 module_name_index (index to CONSTANT_Module_info structure)
* u2 hash_length;
* u1 hash[hash_length];
* } hashes[hashes_count];
*
* }
* } </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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleHashesAttribute
extends Attribute<ModuleHashesAttribute>, ClassElement
permits BoundAttribute.BoundModuleHashesAttribute, UnboundAttribute.UnboundModuleHashesAttribute {
/**
* {@return the algorithm name used to compute the hash}
*/
Utf8Entry algorithm();
/**
* {@return the hash information about related modules}
*/
List<ModuleHashInfo> hashes();
/**
* {@return a {@code ModuleHashes} attribute}
* @param algorithm the hashing algorithm
* @param hashes the hash descriptions
*/
static ModuleHashesAttribute of(String algorithm,
List<ModuleHashInfo> hashes) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(algorithm), hashes);
}
/**
* {@return a {@code ModuleHashes} attribute}
* @param algorithm the hashing algorithm
* @param hashes the hash descriptions
*/
static ModuleHashesAttribute of(String algorithm,
ModuleHashInfo... hashes) {
return of(algorithm, List.of(hashes));
}
/**
* {@return a {@code ModuleHashes} attribute}
* @param algorithm the hashing algorithm
* @param hashes the hash descriptions
*/
static ModuleHashesAttribute of(Utf8Entry algorithm,
List<ModuleHashInfo> hashes) {
return new UnboundAttribute.UnboundModuleHashesAttribute(algorithm, hashes);
}
/**
* {@return a {@code ModuleHashes} attribute}
* @param algorithm the hashing algorithm
* @param hashes the hash descriptions
*/
static ModuleHashesAttribute of(Utf8Entry algorithm,
ModuleHashInfo... hashes) {
return of(algorithm, List.of(hashes));
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ModuleMainClass} attribute {@jvms 4.7.27}, which can
* appear on classes that represent module descriptors.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 9.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleMainClassAttribute
extends Attribute<ModuleMainClassAttribute>, ClassElement
permits BoundAttribute.BoundModuleMainClassAttribute, UnboundAttribute.UnboundModuleMainClassAttribute {
/**
* {@return main class for this module}
*/
ClassEntry mainClass();
/**
* {@return a {@code ModuleMainClass} attribute}
* @param mainClass the main class
*/
static ModuleMainClassAttribute of(ClassEntry mainClass) {
return new UnboundAttribute.UnboundModuleMainClassAttribute(mainClass);
}
/**
* {@return a {@code ModuleMainClass} attribute}
* @param mainClass the main class
* @throws IllegalArgumentException if {@code mainClass} represents a primitive type
*/
static ModuleMainClassAttribute of(ClassDesc mainClass) {
return new UnboundAttribute.UnboundModuleMainClassAttribute(TemporaryConstantPool.INSTANCE.classEntry(mainClass));
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.constant.ModuleDesc;
import java.lang.constant.PackageDesc;
import java.lang.reflect.AccessFlag;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single "opens" declaration in the {@link ModuleAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleOpenInfo
permits UnboundAttribute.UnboundModuleOpenInfo {
/**
* {@return the package being opened}
*/
PackageEntry openedPackage();
/**
* {@return the flags associated with this open declaration, as a bit mask}
* Valid flags include {@link java.lang.classfile.ClassFile#ACC_SYNTHETIC} and
* {@link java.lang.classfile.ClassFile#ACC_MANDATED}
*/
int opensFlagsMask();
/**
* {@return the access flags}
*/
default Set<AccessFlag> opensFlags() {
return AccessFlag.maskToAccessFlags(opensFlagsMask(), AccessFlag.Location.MODULE_OPENS);
}
/**
* {@return whether the specified access flag is set}
* @param flag the access flag
*/
default boolean has(AccessFlag flag) {
return Util.has(AccessFlag.Location.MODULE_OPENS, opensFlagsMask(), flag);
}
/**
* The list of modules to which this package is opened, if it is a
* qualified open.
*
* @return the modules to which this package is opened
*/
List<ModuleEntry> opensTo();
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageEntry opens, int opensFlags,
List<ModuleEntry> opensTo) {
return new UnboundAttribute.UnboundModuleOpenInfo(opens, opensFlags, opensTo);
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageEntry opens, Collection<AccessFlag> opensFlags,
List<ModuleEntry> opensTo) {
return of(opens, Util.flagsToBits(AccessFlag.Location.MODULE_OPENS, opensFlags), opensTo);
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageEntry opens,
int opensFlags,
ModuleEntry... opensTo) {
return of(opens, opensFlags, List.of(opensTo));
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageEntry opens,
Collection<AccessFlag> opensFlags,
ModuleEntry... opensTo) {
return of(opens, Util.flagsToBits(AccessFlag.Location.MODULE_OPENS, opensFlags), opensTo);
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageDesc opens, int opensFlags,
List<ModuleDesc> opensTo) {
return of(TemporaryConstantPool.INSTANCE.packageEntry(TemporaryConstantPool.INSTANCE.utf8Entry(opens.internalName())),
opensFlags,
Util.moduleEntryList(opensTo));
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageDesc opens, Collection<AccessFlag> opensFlags,
List<ModuleDesc> opensTo) {
return of(opens, Util.flagsToBits(AccessFlag.Location.MODULE_OPENS, opensFlags), opensTo);
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageDesc opens,
int opensFlags,
ModuleDesc... opensTo) {
return of(opens, opensFlags, List.of(opensTo));
}
/**
* {@return a module open description}
* @param opens the package to open
* @param opensFlags the open flags
* @param opensTo the packages to which this package is opened, if it is a qualified open
*/
static ModuleOpenInfo of(PackageDesc opens,
Collection<AccessFlag> opensFlags,
ModuleDesc... opensTo) {
return of(opens, Util.flagsToBits(AccessFlag.Location.MODULE_OPENS, opensFlags), opensTo);
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import jdk.internal.classfile.impl.BoundAttribute;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.constant.PackageDesc;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ModulePackages} attribute {@jvms 4.7.26}, which can
* appear on classes that represent module descriptors.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 9.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModulePackagesAttribute
extends Attribute<ModulePackagesAttribute>, ClassElement
permits BoundAttribute.BoundModulePackagesAttribute,
UnboundAttribute.UnboundModulePackagesAttribute {
/**
* {@return the packages that are opened or exported by this module}
*/
List<PackageEntry> packages();
/**
* {@return a {@code ModulePackages} attribute}
* @param packages the packages
*/
static ModulePackagesAttribute of(List<PackageEntry> packages) {
return new UnboundAttribute.UnboundModulePackagesAttribute(packages);
}
/**
* {@return a {@code ModulePackages} attribute}
* @param packages the packages
*/
static ModulePackagesAttribute of(PackageEntry... packages) {
return of(List.of(packages));
}
/**
* {@return a {@code ModulePackages} attribute}
* @param packages the packages
*/
static ModulePackagesAttribute ofNames(List<PackageDesc> packages) {
var p = new PackageEntry[packages.size()];
for (int i = 0; i < packages.size(); i++) {
p[i] = TemporaryConstantPool.INSTANCE.packageEntry(TemporaryConstantPool.INSTANCE.utf8Entry(packages.get(i).internalName()));
}
return of(p);
}
/**
* {@return a {@code ModulePackages} attribute}
* @param packages the packages
*/
static ModulePackagesAttribute ofNames(PackageDesc... packages) {
// List view, since ref to packages is temporary
return ofNames(Arrays.asList(packages));
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single "provides" declaration in the {@link ModuleAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleProvideInfo
permits UnboundAttribute.UnboundModuleProvideInfo {
/**
* {@return the service interface representing the provided service}
*/
ClassEntry provides();
/**
* {@return the classes providing the service implementation}
*/
List<ClassEntry> providesWith();
/**
* {@return a service provision description}
* @param provides the service class interface
* @param providesWith the service class implementations
*/
static ModuleProvideInfo of(ClassEntry provides,
List<ClassEntry> providesWith) {
return new UnboundAttribute.UnboundModuleProvideInfo(provides, providesWith);
}
/**
* {@return a service provision description}
* @param provides the service class interface
* @param providesWith the service class implementations
*/
static ModuleProvideInfo of(ClassEntry provides,
ClassEntry... providesWith) {
return of(provides, List.of(providesWith));
}
/**
* {@return a service provision description}
* @param provides the service class interface
* @param providesWith the service class implementations
* @throws IllegalArgumentException if {@code provides} represents a primitive type
*/
static ModuleProvideInfo of(ClassDesc provides,
List<ClassDesc> providesWith) {
return of(TemporaryConstantPool.INSTANCE.classEntry(provides), Util.entryList(providesWith));
}
/**
* {@return a service provision description}
* @param provides the service class interface
* @param providesWith the service class implementations
* @throws IllegalArgumentException if {@code provides} or any of {@code providesWith} represents a primitive type
*/
static ModuleProvideInfo of(ClassDesc provides,
ClassDesc... providesWith) {
// List view, since ref to providesWith is temporary
return of(provides, Arrays.asList(providesWith));
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import java.lang.reflect.AccessFlag;
import java.lang.constant.ModuleDesc;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single "requires" declaration in the {@link ModuleAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleRequireInfo
permits UnboundAttribute.UnboundModuleRequiresInfo {
/**
* {@return The module on which the current module depends}
*/
ModuleEntry requires();
/**
* {@return the flags associated with this require declaration, as a bit mask}
* Valid flags include {@link java.lang.classfile.ClassFile#ACC_TRANSITIVE},
* {@link java.lang.classfile.ClassFile#ACC_STATIC_PHASE},
* {@link java.lang.classfile.ClassFile#ACC_SYNTHETIC} and
* {@link java.lang.classfile.ClassFile#ACC_MANDATED}
*/
int requiresFlagsMask();
/**
* {@return the access flags}
*/
default Set<AccessFlag> requiresFlags() {
return AccessFlag.maskToAccessFlags(requiresFlagsMask(), AccessFlag.Location.MODULE_REQUIRES);
}
/**
* {@return the required version of the required module, if present}
*/
Optional<Utf8Entry> requiresVersion();
/**
* {@return whether the specific access flag is set}
* @param flag the access flag
*/
default boolean has(AccessFlag flag) {
return Util.has(AccessFlag.Location.MODULE_REQUIRES, requiresFlagsMask(), flag);
}
/**
* {@return a module requirement description}
* @param requires the required module
* @param requiresFlags the require-specific flags
* @param requiresVersion the required version
*/
static ModuleRequireInfo of(ModuleEntry requires, int requiresFlags, Utf8Entry requiresVersion) {
return new UnboundAttribute.UnboundModuleRequiresInfo(requires, requiresFlags, Optional.ofNullable(requiresVersion));
}
/**
* {@return a module requirement description}
* @param requires the required module
* @param requiresFlags the require-specific flags
* @param requiresVersion the required version
*/
static ModuleRequireInfo of(ModuleEntry requires, Collection<AccessFlag> requiresFlags, Utf8Entry requiresVersion) {
return of(requires, Util.flagsToBits(AccessFlag.Location.MODULE_REQUIRES, requiresFlags), requiresVersion);
}
/**
* {@return a module requirement description}
* @param requires the required module
* @param requiresFlags the require-specific flags
* @param requiresVersion the required version
*/
static ModuleRequireInfo of(ModuleDesc requires, int requiresFlags, String requiresVersion) {
return new UnboundAttribute.UnboundModuleRequiresInfo(TemporaryConstantPool.INSTANCE.moduleEntry(TemporaryConstantPool.INSTANCE.utf8Entry(requires.name())), requiresFlags, Optional.ofNullable(requiresVersion).map(s -> TemporaryConstantPool.INSTANCE.utf8Entry(s)));
}
/**
* {@return a module requirement description}
* @param requires the required module
* @param requiresFlags the require-specific flags
* @param requiresVersion the required version
*/
static ModuleRequireInfo of(ModuleDesc requires, Collection<AccessFlag> requiresFlags, String requiresVersion) {
return of(requires, Util.flagsToBits(AccessFlag.Location.MODULE_REQUIRES, requiresFlags), requiresVersion);
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ModuleResolution} attribute, which can
* appear on classes that represent module descriptors. This is a JDK-specific
* * attribute, which captures resolution metadata for modules.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.classfile.ClassModel}.
*
* <p>The specification of the {@code ModuleResolution} attribute is:
* <pre> {@code
* ModuleResolution_attribute {
* u2 attribute_name_index; // "ModuleResolution"
* u4 attribute_length; // 2
* u2 resolution_flags;
*
* The value of the resolution_flags item is a mask of flags used to denote
* properties of module resolution. The flags are as follows:
*
* // Optional
* 0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
*
* // At most one of:
* 0x0002 (WARN_DEPRECATED)
* 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
* 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleResolutionAttribute
extends Attribute<ModuleResolutionAttribute>, ClassElement
permits BoundAttribute.BoundModuleResolutionAttribute, UnboundAttribute.UnboundModuleResolutionAttribute {
/**
* The value of the resolution_flags item is a mask of flags used to denote
* properties of module resolution. The flags are as follows:
* <pre> {@code
* // Optional
* 0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
*
* // At most one of:
* 0x0002 (WARN_DEPRECATED)
* 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
* 0x0008 (WARN_INCUBATING)
* } </pre>
* @return the module resolution flags
*/
int resolutionFlags();
/**
* {@return a {@code ModuleResolution} attribute}
* @param resolutionFlags the resolution flags
*/
static ModuleResolutionAttribute of(int resolutionFlags) {
return new UnboundAttribute.UnboundModuleResolutionAttribute(resolutionFlags);
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code ModuleTarget} attribute, which can
* appear on classes that represent module descriptors. This is a JDK-specific
* attribute, which captures constraints on the target platform.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.classfile.ClassModel}.
*
* <p>The specification of the {@code ModuleTarget} attribute is:
* <pre> {@code
* TargetPlatform_attribute {
* // index to CONSTANT_utf8_info structure in constant pool representing
* // the string "ModuleTarget"
* u2 attribute_name_index;
* u4 attribute_length;
*
* // index to CONSTANT_utf8_info structure with the target platform
* 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ModuleTargetAttribute
extends Attribute<ModuleTargetAttribute>, ClassElement
permits BoundAttribute.BoundModuleTargetAttribute, UnboundAttribute.UnboundModuleTargetAttribute {
/**
* {@return the target platform}
*/
Utf8Entry targetPlatform();
/**
* {@return a {@code ModuleTarget} attribute}
* @param targetPlatform the target platform
*/
static ModuleTargetAttribute of(String targetPlatform) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(targetPlatform));
}
/**
* {@return a {@code ModuleTarget} attribute}
* @param targetPlatform the target platform
*/
static ModuleTargetAttribute of(Utf8Entry targetPlatform) {
return new UnboundAttribute.UnboundModuleTargetAttribute(targetPlatform);
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code NestHost} attribute {@jvms 4.7.28}, which can
* appear on classes to indicate that this class is a member of a nest.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 11.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface NestHostAttribute extends Attribute<NestHostAttribute>, ClassElement
permits BoundAttribute.BoundNestHostAttribute,
UnboundAttribute.UnboundNestHostAttribute {
/**
* {@return the host class of the nest to which this class belongs}
*/
ClassEntry nestHost();
/**
* {@return a {@code NestHost} attribute}
* @param nestHost the host class of the nest
*/
static NestHostAttribute of(ClassEntry nestHost) {
return new UnboundAttribute.UnboundNestHostAttribute(nestHost);
}
/**
* {@return a {@code NestHost} attribute}
* @param nestHost the host class of the nest
* @throws IllegalArgumentException if {@code nestHost} represents a primitive type
*/
static NestHostAttribute of(ClassDesc nestHost) {
return of(TemporaryConstantPool.INSTANCE.classEntry(nestHost));
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code NestMembers} attribute {@jvms 4.7.29}, which can
* appear on classes to indicate that this class is the host of a nest.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 11.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface NestMembersAttribute extends Attribute<NestMembersAttribute>, ClassElement
permits BoundAttribute.BoundNestMembersAttribute, UnboundAttribute.UnboundNestMembersAttribute {
/**
* {@return the classes belonging to the nest hosted by this class}
*/
List<ClassEntry> nestMembers();
/**
* {@return a {@code NestMembers} attribute}
* @param nestMembers the member classes of the nest
*/
static NestMembersAttribute of(List<ClassEntry> nestMembers) {
return new UnboundAttribute.UnboundNestMembersAttribute(nestMembers);
}
/**
* {@return a {@code NestMembers} attribute}
* @param nestMembers the member classes of the nest
*/
static NestMembersAttribute of(ClassEntry... nestMembers) {
return of(List.of(nestMembers));
}
/**
* {@return a {@code NestMembers} attribute}
* @param nestMembers the member classes of the nest
*/
static NestMembersAttribute ofSymbols(List<ClassDesc> nestMembers) {
return of(Util.entryList(nestMembers));
}
/**
* {@return a {@code NestMembers} attribute}
* @param nestMembers the member classes of the nest
*/
static NestMembersAttribute ofSymbols(ClassDesc... nestMembers) {
// List view, since ref to nestMembers is temporary
return ofSymbols(Arrays.asList(nestMembers));
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.Arrays;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.classfile.impl.Util;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code PermittedSubclasses} attribute {@jvms 4.7.31}, which can
* appear on classes to indicate which classes may extend this class.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 17.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface PermittedSubclassesAttribute
extends Attribute<PermittedSubclassesAttribute>, ClassElement
permits BoundAttribute.BoundPermittedSubclassesAttribute, UnboundAttribute.UnboundPermittedSubclassesAttribute {
/**
* {@return the list of permitted subclasses}
*/
List<ClassEntry> permittedSubclasses();
/**
* {@return a {@code PermittedSubclasses} attribute}
* @param permittedSubclasses the permitted subclasses
*/
static PermittedSubclassesAttribute of(List<ClassEntry> permittedSubclasses) {
return new UnboundAttribute.UnboundPermittedSubclassesAttribute(permittedSubclasses);
}
/**
* {@return a {@code PermittedSubclasses} attribute}
* @param permittedSubclasses the permitted subclasses
*/
static PermittedSubclassesAttribute of(ClassEntry... permittedSubclasses) {
return of(List.of(permittedSubclasses));
}
/**
* {@return a {@code PermittedSubclasses} attribute}
* @param permittedSubclasses the permitted subclasses
*/
static PermittedSubclassesAttribute ofSymbols(List<ClassDesc> permittedSubclasses) {
return of(Util.entryList(permittedSubclasses));
}
/**
* {@return a {@code PermittedSubclasses} attribute}
* @param permittedSubclasses the permitted subclasses
*/
static PermittedSubclassesAttribute ofSymbols(ClassDesc... permittedSubclasses) {
// List view, since ref to nestMembers is temporary
return ofSymbols(Arrays.asList(permittedSubclasses));
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Record} attribute {@jvms 4.7.30}, which can
* appear on classes to indicate that this class is a record class.
* Delivered as a {@link java.lang.classfile.ClassElement} when
* traversing the elements of a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 16.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RecordAttribute extends Attribute<RecordAttribute>, ClassElement
permits BoundAttribute.BoundRecordAttribute, UnboundAttribute.UnboundRecordAttribute {
/**
* {@return the components of this record class}
*/
List<RecordComponentInfo> components();
/**
* {@return a {@code Record} attribute}
* @param components the record components
*/
static RecordAttribute of(List<RecordComponentInfo> components) {
return new UnboundAttribute.UnboundRecordAttribute(components);
}
/**
* {@return a {@code Record} attribute}
* @param components the record components
*/
static RecordAttribute of(RecordComponentInfo... components) {
return of(List.of(components));
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.AttributedElement;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundRecordComponentInfo;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models a single record component in the {@link java.lang.classfile.attribute.RecordAttribute}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RecordComponentInfo
extends AttributedElement
permits BoundRecordComponentInfo, UnboundAttribute.UnboundRecordComponentInfo {
/**
* {@return the name of this component}
*/
Utf8Entry name();
/**
* {@return the field descriptor of this component}
*/
Utf8Entry descriptor();
/**
* {@return the field descriptor of this component, as a {@linkplain ClassDesc}}
*/
default ClassDesc descriptorSymbol() {
return ClassDesc.ofDescriptor(descriptor().stringValue());
}
/**
* {@return a record component description}
* @param name the component name
* @param descriptor the component field descriptor
* @param attributes the component attributes
*/
static RecordComponentInfo of(Utf8Entry name,
Utf8Entry descriptor,
List<Attribute<?>> attributes) {
return new UnboundAttribute.UnboundRecordComponentInfo(name, descriptor, attributes);
}
/**
* {@return a record component description}
* @param name the component name
* @param descriptor the component field descriptor
* @param attributes the component attributes
*/
static RecordComponentInfo of(Utf8Entry name,
Utf8Entry descriptor,
Attribute<?>... attributes) {
return of(name, descriptor, List.of(attributes));
}
/**
* {@return a record component description}
* @param name the component name
* @param descriptor the component field descriptor
* @param attributes the component attributes
*/
static RecordComponentInfo of(String name,
ClassDesc descriptor,
List<Attribute<?>> attributes) {
return new UnboundAttribute.UnboundRecordComponentInfo(TemporaryConstantPool.INSTANCE.utf8Entry(name),
TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()),
attributes);
}
/**
* {@return a record component description}
* @param name the component name
* @param descriptor the component field descriptor
* @param attributes the component attributes
*/
static RecordComponentInfo of(String name,
ClassDesc descriptor,
Attribute<?>... attributes) {
return of(name, descriptor, List.of(attributes));
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.*;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeInvisibleAnnotations} attribute {@jvms 4.7.17}, which
* can appear on classes, methods, and fields. Delivered as a
* {@link java.lang.classfile.ClassElement}, {@link java.lang.classfile.FieldElement}, or
* {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeInvisibleAnnotationsAttribute
extends Attribute<RuntimeInvisibleAnnotationsAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeInvisibleAnnotationsAttribute {
/**
* {@return the non-runtime-visible annotations on this class, field, or method}
*/
List<Annotation> annotations();
/**
* {@return a {@code RuntimeInvisibleAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeInvisibleAnnotationsAttribute of(List<Annotation> annotations) {
return new UnboundAttribute.UnboundRuntimeInvisibleAnnotationsAttribute(annotations);
}
/**
* {@return a {@code RuntimeInvisibleAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeInvisibleAnnotationsAttribute of(Annotation... annotations) {
return of(List.of(annotations));
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Annotation;
import java.lang.classfile.Attribute;
import java.lang.classfile.MethodElement;
import java.lang.classfile.MethodModel;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeInvisibleParameterAnnotations} attribute
* {@jvms 4.7.19}, which can appear on methods. Delivered as a {@link
* java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeInvisibleParameterAnnotationsAttribute
extends Attribute<RuntimeInvisibleParameterAnnotationsAttribute>, MethodElement
permits BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeInvisibleParameterAnnotationsAttribute {
/**
* {@return the list of annotations corresponding to each method parameter}
* The element at the i'th index corresponds to the annotations on the i'th
* parameter.
*/
List<List<Annotation>> parameterAnnotations();
/**
* {@return a {@code RuntimeInvisibleParameterAnnotations} attribute}
* @param parameterAnnotations a list of parameter annotations for each parameter
*/
static RuntimeInvisibleParameterAnnotationsAttribute of(List<List<Annotation>> parameterAnnotations) {
return new UnboundAttribute.UnboundRuntimeInvisibleParameterAnnotationsAttribute(parameterAnnotations);
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.CodeElement;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import java.lang.classfile.TypeAnnotation;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeInvisibleTypeAnnotations} attribute {@jvms 4.7.21}, which
* can appear on classes, methods, fields, and code attributes. Delivered as a
* {@link java.lang.classfile.ClassElement}, {@link java.lang.classfile.FieldElement},
* {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 8.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeInvisibleTypeAnnotationsAttribute
extends Attribute<RuntimeInvisibleTypeAnnotationsAttribute>,
ClassElement, MethodElement, FieldElement, CodeElement
permits BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeInvisibleTypeAnnotationsAttribute {
/**
* {@return the non-runtime-visible type annotations on parts of this class, field, or method}
*/
List<TypeAnnotation> annotations();
/**
* {@return a {@code RuntimeInvisibleTypeAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeInvisibleTypeAnnotationsAttribute of(List<TypeAnnotation> annotations) {
return new UnboundAttribute.UnboundRuntimeInvisibleTypeAnnotationsAttribute(annotations);
}
/**
* {@return a {@code RuntimeInvisibleTypeAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeInvisibleTypeAnnotationsAttribute of(TypeAnnotation... annotations) {
return of(List.of(annotations));
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.*;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import java.util.List;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeVisibleAnnotations} attribute {@jvms 4.7.16}, which
* can appear on classes, methods, and fields. Delivered as a
* {@link java.lang.classfile.ClassElement}, {@link java.lang.classfile.FieldElement}, or
* {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeVisibleAnnotationsAttribute
extends Attribute<RuntimeVisibleAnnotationsAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeVisibleAnnotationsAttribute {
/**
* {@return the runtime-visible annotations on this class, field, or method}
*/
List<Annotation> annotations();
/**
* {@return a {@code RuntimeVisibleAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeVisibleAnnotationsAttribute of(List<Annotation> annotations) {
return new UnboundAttribute.UnboundRuntimeVisibleAnnotationsAttribute(annotations);
}
/**
* {@return a {@code RuntimeVisibleAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeVisibleAnnotationsAttribute of(Annotation... annotations) {
return of(List.of(annotations));
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Annotation;
import java.lang.classfile.Attribute;
import java.lang.classfile.MethodElement;
import java.lang.classfile.MethodModel;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeVisibleParameterAnnotations} attribute {@jvms 4.7.18}, which
* can appear on methods. Delivered as a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeVisibleParameterAnnotationsAttribute
extends Attribute<RuntimeVisibleParameterAnnotationsAttribute>, MethodElement
permits BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeVisibleParameterAnnotationsAttribute {
/**
* {@return the list of annotations corresponding to each method parameter}
* The element at the i'th index corresponds to the annotations on the i'th
* parameter.
*/
List<List<Annotation>> parameterAnnotations();
/**
* {@return a {@code RuntimeVisibleParameterAnnotations} attribute}
* @param parameterAnnotations a list of parameter annotations for each parameter
*/
static RuntimeVisibleParameterAnnotationsAttribute of(List<List<Annotation>> parameterAnnotations) {
return new UnboundAttribute.UnboundRuntimeVisibleParameterAnnotationsAttribute(parameterAnnotations);
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.CodeElement;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import java.lang.classfile.TypeAnnotation;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code RuntimeVisibleTypeAnnotations} attribute {@jvms 4.7.20}, which
* can appear on classes, methods, fields, and code attributes. Delivered as a
* {@link java.lang.classfile.ClassElement}, {@link java.lang.classfile.FieldElement},
* {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 8.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface RuntimeVisibleTypeAnnotationsAttribute
extends Attribute<RuntimeVisibleTypeAnnotationsAttribute>,
ClassElement, MethodElement, FieldElement, CodeElement
permits BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute,
UnboundAttribute.UnboundRuntimeVisibleTypeAnnotationsAttribute {
/**
* {@return the runtime-visible type annotations on parts of this class, field, or method}
*/
List<TypeAnnotation> annotations();
/**
* {@return a {@code RuntimeVisibleTypeAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeVisibleTypeAnnotationsAttribute of(List<TypeAnnotation> annotations) {
return new UnboundAttribute.UnboundRuntimeVisibleTypeAnnotationsAttribute(annotations);
}
/**
* {@return a {@code RuntimeVisibleTypeAnnotations} attribute}
* @param annotations the annotations
*/
static RuntimeVisibleTypeAnnotationsAttribute of(TypeAnnotation... annotations) {
return of(List.of(annotations));
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.ClassSignature;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import java.lang.classfile.MethodSignature;
import java.lang.classfile.Signature;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Signature} attribute {@jvms 4.7.9}, which
* can appear on classes, methods, or fields. Delivered as a
* {@link java.lang.classfile.ClassElement}, {@link java.lang.classfile.FieldElement}, or
* {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface SignatureAttribute
extends Attribute<SignatureAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundSignatureAttribute, UnboundAttribute.UnboundSignatureAttribute {
/**
* {@return the signature for the class, method, or field}
*/
Utf8Entry signature();
/**
* Parse the signature as a class signature.
* @return the class signature
*/
default ClassSignature asClassSignature() {
return ClassSignature.parseFrom(signature().stringValue());
}
/**
* Parse the signature as a method signature.
* @return the method signature
*/
default MethodSignature asMethodSignature() {
return MethodSignature.parseFrom(signature().stringValue());
}
/**
* Parse the signature as a type signature.
* @return the type signature
*/
default Signature asTypeSignature() {
return Signature.parseFrom(signature().stringValue());
}
/**
* {@return a {@code Signature} attribute for a class}
* @param classSignature the signature
*/
static SignatureAttribute of(ClassSignature classSignature) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(classSignature.signatureString()));
}
/**
* {@return a {@code Signature} attribute for a method}
* @param methodSignature the signature
*/
static SignatureAttribute of(MethodSignature methodSignature) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(methodSignature.signatureString()));
}
/**
* {@return a {@code Signature} attribute}
* @param signature the signature
*/
static SignatureAttribute of(Signature signature) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(signature.signatureString()));
}
/**
* {@return a {@code Signature} attribute}
* @param signature the signature
*/
static SignatureAttribute of(Utf8Entry signature) {
return new UnboundAttribute.UnboundSignatureAttribute(signature);
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code SourceDebugExtension} attribute.
* Delivered as a {@link java.lang.classfile.ClassElement} when traversing the elements of
* a {@link java.lang.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.
* <p>
* The attribute was introduced in the Java SE Platform version 5.0.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface SourceDebugExtensionAttribute
extends Attribute<SourceDebugExtensionAttribute>, ClassElement
permits BoundAttribute.BoundSourceDebugExtensionAttribute, UnboundAttribute.UnboundSourceDebugExtensionAttribute {
/**
* {@return the debug extension payload}
*/
byte[] contents();
/**
* {@return a {@code SourceDebugExtension} attribute}
* @param contents the extension contents
*/
static SourceDebugExtensionAttribute of(byte[] contents) {
return new UnboundAttribute.UnboundSourceDebugExtensionAttribute(contents);
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.ClassModel;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code SourceFile} attribute {@jvms 4.7.10}, which
* can appear on classes. Delivered as a {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface SourceFileAttribute
extends Attribute<SourceFileAttribute>, ClassElement
permits BoundAttribute.BoundSourceFileAttribute, UnboundAttribute.UnboundSourceFileAttribute {
/**
* {@return the name of the source file from which this class was compiled}
*/
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);
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.ClassModel;
import java.lang.classfile.constantpool.Utf8Entry;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code SourceID} attribute, which can
* appear on classes. Delivered as a {@link java.lang.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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface SourceIDAttribute
extends Attribute<SourceIDAttribute>, ClassElement
permits BoundAttribute.BoundSourceIDAttribute, UnboundAttribute.UnboundSourceIDAttribute {
/**
* {@return the source id} The source id is the last modified time of the
* source file (as reported by the filesystem, in milliseconds) when the
* classfile is compiled.
*/
Utf8Entry sourceId();
/**
* {@return a {@code SourceID} attribute}
* @param sourceId the source id
*/
static SourceIDAttribute of(Utf8Entry sourceId) {
return new UnboundAttribute.UnboundSourceIDAttribute(sourceId);
}
/**
* {@return a {@code SourceID} attribute}
* @param sourceId the source id
*/
static SourceIDAttribute of(String sourceId) {
return of(TemporaryConstantPool.INSTANCE.utf8Entry(sourceId));
}
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.constant.ClassDesc;
import java.util.List;
import java.lang.classfile.Label;
import java.lang.classfile.constantpool.ClassEntry;
import jdk.internal.classfile.impl.StackMapDecoder;
import jdk.internal.classfile.impl.TemporaryConstantPool;
import static java.lang.classfile.ClassFile.*;
import jdk.internal.javac.PreviewFeature;
/**
* Models stack map frame of {@code StackMapTable} attribute {@jvms 4.7.4}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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) {
return new StackMapDecoder.StackMapFrameImpl(255, target, locals, stack);
}
/**
* The type of a stack value.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
sealed interface VerificationTypeInfo {
/**
* {@return the tag of the type info}
*/
int tag();
}
/**
* A simple stack value.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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);
private final int tag;
SimpleVerificationTypeInfo(int tag) {
this.tag = tag;
}
@Override
public int tag() {
return tag;
}
}
/**
* A stack value for an object type.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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
* @throws IllegalArgumentException if {@code classDesc} represents a primitive type
*/
public static ObjectVerificationTypeInfo of(ClassDesc classDesc) {
return of(TemporaryConstantPool.INSTANCE.classEntry(classDesc));
}
/**
* {@return the class of the object}
*/
ClassEntry className();
/**
* {@return the class of the object}
*/
default ClassDesc classSymbol() {
return className().asSymbol();
}
}
/**
* An uninitialized stack value.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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);
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.util.List;
import java.lang.classfile.Attribute;
import java.lang.classfile.CodeElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* 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.
* <p>
* The attribute was introduced in the Java SE Platform version 6.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface StackMapTableAttribute
extends Attribute<StackMapTableAttribute>, CodeElement
permits BoundAttribute.BoundStackMapTableAttribute, UnboundAttribute.UnboundStackMapTableAttribute {
/**
* {@return the stack map frames}
*/
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);
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.classfile.impl.UnboundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models the {@code Synthetic} attribute {@jvms 4.7.8}, which can appear on
* 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.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface SyntheticAttribute
extends Attribute<SyntheticAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundSyntheticAttribute, UnboundAttribute.UnboundSyntheticAttribute {
/**
* {@return a {@code Synthetic} attribute}
*/
static SyntheticAttribute of() {
return new UnboundAttribute.UnboundSyntheticAttribute();
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.attribute;
import java.lang.classfile.Attribute;
import java.lang.classfile.ClassElement;
import java.lang.classfile.FieldElement;
import java.lang.classfile.MethodElement;
import jdk.internal.classfile.impl.BoundAttribute;
import jdk.internal.javac.PreviewFeature;
/**
* Models an unknown attribute on a class, method, or field.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface UnknownAttribute
extends Attribute<UnknownAttribute>,
ClassElement, MethodElement, FieldElement
permits BoundAttribute.BoundUnknownAttribute {
/**
* {@return the uninterpreted contents of the attribute payload}
*/
byte[] contents();
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* <h2>Provides interfaces describing classfile attributes for the {@link java.lang.classfile} library.</h2>
*
* The {@code java.lang.classfile.attribute} package contains interfaces describing classfile attributes.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
package java.lang.classfile.attribute;
import jdk.internal.javac.PreviewFeature;

View file

@ -0,0 +1,228 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.classfile.components;
import java.lang.constant.ConstantDesc;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.lang.classfile.ClassModel;
import java.lang.classfile.FieldModel;
import java.lang.classfile.MethodModel;
import java.lang.classfile.CodeModel;
import java.lang.classfile.CompoundElement;
import jdk.internal.classfile.impl.ClassPrinterImpl;
import jdk.internal.javac.PreviewFeature;
/**
* A printer of classfiles and its elements.
* <p>
* Any {@link ClassModel}, {@link FieldModel}, {@link MethodModel}, or {@link CodeModel}
* can be printed to a human-readable structured text in JSON, XML, or YAML format.
* Or it can be exported into a tree of traversable and printable nodes,
* more exactly into a tree of {@link MapNode}, {@link ListNode}, and {@link LeafNode} instances.
* <p>
* Level of details to print or to export is driven by {@link Verbosity} option.
* <p>
* Printing is for debugging purposes only. Printed text schema, tree content and structure
* not guaranteed. It may change anytime in a future.
* <p>
* The most frequent use case is to simply print a class:
* {@snippet lang="java" class="PackageSnippets" region="printClass"}
* <p>
* {@link ClassPrinter} allows to traverse tree of simple printable nodes to hook custom printer:
* {@snippet lang="java" class="PackageSnippets" region="customPrint"}
* <p>
* Another use case for {@link ClassPrinter} is to simplify writing of automated tests:
* {@snippet lang="java" class="PackageSnippets" region="printNodesInTest"}
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public final class ClassPrinter {
private ClassPrinter() {
}
/**
* Level of detail to print or export.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public enum Verbosity {
/**
* Only top level class info, class members and attribute names are printed.
*/
MEMBERS_ONLY,
/**
* Top level class info, class members, and critical attributes are printed.
* <p>
* Critical attributes are:
* <ul>
* <li>ConstantValue
* <li>Code
* <li>StackMapTable
* <li>BootstrapMethods
* <li>NestHost
* <li>NestMembers
* <li>PermittedSubclasses
* </ul>
* @jvms 4.7 Attributes
*/
CRITICAL_ATTRIBUTES,
/**
* All class content is printed, including constant pool.
*/
TRACE_ALL }
/**
* Named, traversable, and printable node parent.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface Node {
/**
* Printable name of the node.
* @return name of the node
*/
ConstantDesc name();
/**
* Walks through the underlying tree.
* @return ordered stream of nodes
*/
Stream<Node> walk();
/**
* Prints the node and its sub-tree into JSON format.
* @param out consumer of the printed fragments
*/
default void toJson(Consumer<String> out) {
ClassPrinterImpl.toJson(this, out);
}
/**
* Prints the node and its sub-tree into XML format.
* @param out consumer of the printed fragments
*/
default void toXml(Consumer<String> out) {
ClassPrinterImpl.toXml(this, out);
}
/**
* Prints the node and its sub-tree into YAML format.
* @param out consumer of the printed fragments
*/
default void toYaml(Consumer<String> out) {
ClassPrinterImpl.toYaml(this, out);
}
}
/**
* A leaf node holding single printable value.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface LeafNode extends Node
permits ClassPrinterImpl.LeafNodeImpl {
/**
* Printable node value
* @return node value
*/
ConstantDesc value();
}
/**
* A tree node holding {@link List} of nested nodes.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface ListNode extends Node, List<Node>
permits ClassPrinterImpl.ListNodeImpl {
}
/**
* A tree node holding {@link Map} of nested nodes.
* <p>
* Each {@link Map.Entry#getKey()} == {@link Map.Entry#getValue()}.{@link #name()}.
*
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
public sealed interface MapNode extends Node, Map<ConstantDesc, Node>
permits ClassPrinterImpl.MapNodeImpl {
}
/**
* Exports provided model into a tree of printable nodes.
* @param model a {@link ClassModel}, {@link FieldModel}, {@link MethodModel}, or {@link CodeModel} to export
* @param verbosity level of details to export
* @return root node of the exported tree
*/
public static MapNode toTree(CompoundElement<?> model, Verbosity verbosity) {
return ClassPrinterImpl.modelToTree(model, verbosity);
}
/**
* Prints provided model as structured text in JSON format.
* @param model a {@link ClassModel}, {@link FieldModel}, {@link MethodModel}, or {@link CodeModel} to print
* @param verbosity level of details to print
* @param out consumer of the print fragments
*/
public static void toJson(CompoundElement<?> model, Verbosity verbosity, Consumer<String> out) {
toTree(model, verbosity).toJson(out);
}
/**
* Prints provided model as structured text in XML format.
* @param model a {@link ClassModel}, {@link FieldModel}, {@link MethodModel}, or {@link CodeModel} to print
* @param verbosity level of details to print
* @param out consumer of the print fragments
*/
public static void toXml(CompoundElement<?> model, Verbosity verbosity, Consumer<String> out) {
toTree(model, verbosity).toXml(out);
}
/**
* Prints provided model as structured text in YAML format.
* @param model a {@link ClassModel}, {@link FieldModel}, {@link MethodModel}, or {@link CodeModel} to print
* @param verbosity level of details to print
* @param out consumer of the print fragments
*/
public static void toYaml(CompoundElement<?> model, Verbosity verbosity, Consumer<String> out) {
toTree(model, verbosity).toYaml(out);
}
}

Some files were not shown because too many files have changed in this diff Show more