blob: 0b0f1836f66c248990440f0474535bfc43bef352 [file]
/*
* Copyright (c) 2022, 2024, 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 jdk.internal.classfile.impl;
import java.lang.classfile.*;
import java.lang.classfile.attribute.*;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantValueEntry;
import java.lang.classfile.constantpool.ModuleEntry;
import java.lang.classfile.constantpool.NameAndTypeEntry;
import java.lang.classfile.constantpool.PackageEntry;
import java.lang.classfile.constantpool.Utf8Entry;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import jdk.internal.access.SharedSecrets;
import static java.util.Objects.requireNonNull;
public abstract sealed class UnboundAttribute<T extends Attribute<T>>
extends AbstractElement
implements Attribute<T>, Util.Writable {
protected final AttributeMapper<T> mapper;
public UnboundAttribute(AttributeMapper<T> mapper) {
this.mapper = mapper;
}
@Override
public AttributeMapper<T> attributeMapper() {
return mapper;
}
@Override
@SuppressWarnings("unchecked")
public void writeTo(BufWriterImpl buf) {
mapper.writeAttribute(buf, (T) this);
}
@Override
public void writeTo(DirectClassBuilder builder) {
builder.writeAttribute(this);
}
@Override
public void writeTo(DirectCodeBuilder builder) {
builder.writeAttribute(this);
}
@Override
public void writeTo(DirectMethodBuilder builder) {
builder.writeAttribute(this);
}
@Override
public void writeTo(DirectFieldBuilder builder) {
builder.writeAttribute(this);
}
@Override
public String toString() {
return String.format("Attribute[name=%s]", mapper.name());
}
public static final class UnboundConstantValueAttribute
extends UnboundAttribute<ConstantValueAttribute>
implements ConstantValueAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CONSTANT_VALUE);
private final ConstantValueEntry entry;
public UnboundConstantValueAttribute(ConstantValueEntry entry) {
super(Attributes.constantValue());
this.entry = requireNonNull(entry);
}
@Override
public ConstantValueEntry constant() {
return entry;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundDeprecatedAttribute
extends UnboundAttribute<DeprecatedAttribute>
implements DeprecatedAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_DEPRECATED);
public UnboundDeprecatedAttribute() {
super(Attributes.deprecated());
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundSyntheticAttribute
extends UnboundAttribute<SyntheticAttribute>
implements SyntheticAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SYNTHETIC);
public UnboundSyntheticAttribute() {
super(Attributes.synthetic());
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundSignatureAttribute
extends UnboundAttribute<SignatureAttribute>
implements SignatureAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SIGNATURE);
private final Utf8Entry signature;
public UnboundSignatureAttribute(Utf8Entry signature) {
super(Attributes.signature());
this.signature = requireNonNull(signature);
}
@Override
public Utf8Entry signature() {
return signature;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundExceptionsAttribute
extends UnboundAttribute<ExceptionsAttribute>
implements ExceptionsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_EXCEPTIONS);
private final List<ClassEntry> exceptions;
public UnboundExceptionsAttribute(List<ClassEntry> exceptions) {
super(Attributes.exceptions());
this.exceptions = List.copyOf(exceptions);
}
@Override
public List<ClassEntry> exceptions() {
return exceptions;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundAnnotationDefaultAttribute
extends UnboundAttribute<AnnotationDefaultAttribute>
implements AnnotationDefaultAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ANNOTATION_DEFAULT);
private final AnnotationValue annotationDefault;
public UnboundAnnotationDefaultAttribute(AnnotationValue annotationDefault) {
super(Attributes.annotationDefault());
this.annotationDefault = requireNonNull(annotationDefault);
}
@Override
public AnnotationValue defaultValue() {
return annotationDefault;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundSourceFileAttribute extends UnboundAttribute<SourceFileAttribute>
implements SourceFileAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_FILE);
private final Utf8Entry sourceFile;
public UnboundSourceFileAttribute(Utf8Entry sourceFile) {
super(Attributes.sourceFile());
this.sourceFile = requireNonNull(sourceFile);
}
@Override
public Utf8Entry sourceFile() {
return sourceFile;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundStackMapTableAttribute extends UnboundAttribute<StackMapTableAttribute>
implements StackMapTableAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_STACK_MAP_TABLE);
private final List<StackMapFrameInfo> entries;
public UnboundStackMapTableAttribute(List<StackMapFrameInfo> entries) {
super(Attributes.stackMapTable());
this.entries = List.copyOf(entries);
}
@Override
public List<StackMapFrameInfo> entries() {
return entries;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundInnerClassesAttribute
extends UnboundAttribute<InnerClassesAttribute>
implements InnerClassesAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_INNER_CLASSES);
private final List<InnerClassInfo> innerClasses;
public UnboundInnerClassesAttribute(List<InnerClassInfo> innerClasses) {
super(Attributes.innerClasses());
this.innerClasses = List.copyOf(innerClasses);
}
@Override
public List<InnerClassInfo> classes() {
return innerClasses;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRecordAttribute
extends UnboundAttribute<RecordAttribute>
implements RecordAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RECORD);
private final List<RecordComponentInfo> components;
public UnboundRecordAttribute(List<RecordComponentInfo> components) {
super(Attributes.record());
this.components = List.copyOf(components);
}
@Override
public List<RecordComponentInfo> components() {
return components;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundEnclosingMethodAttribute
extends UnboundAttribute<EnclosingMethodAttribute>
implements EnclosingMethodAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ENCLOSING_METHOD);
private final ClassEntry classEntry;
private final NameAndTypeEntry method;
public UnboundEnclosingMethodAttribute(ClassEntry classEntry, NameAndTypeEntry method) {
super(Attributes.enclosingMethod());
this.classEntry = requireNonNull(classEntry);
this.method = method;
}
@Override
public ClassEntry enclosingClass() {
return classEntry;
}
@Override
public Optional<NameAndTypeEntry> enclosingMethod() {
return Optional.ofNullable(method);
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundMethodParametersAttribute
extends UnboundAttribute<MethodParametersAttribute>
implements MethodParametersAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_METHOD_PARAMETERS);
private final List<MethodParameterInfo> parameters;
public UnboundMethodParametersAttribute(List<MethodParameterInfo> parameters) {
super(Attributes.methodParameters());
this.parameters = List.copyOf(parameters);
}
@Override
public List<MethodParameterInfo> parameters() {
return parameters;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundModuleTargetAttribute
extends UnboundAttribute<ModuleTargetAttribute>
implements ModuleTargetAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_TARGET);
final Utf8Entry moduleTarget;
public UnboundModuleTargetAttribute(Utf8Entry moduleTarget) {
super(Attributes.moduleTarget());
this.moduleTarget = requireNonNull(moduleTarget);
}
@Override
public Utf8Entry targetPlatform() {
return moduleTarget;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundModuleMainClassAttribute
extends UnboundAttribute<ModuleMainClassAttribute>
implements ModuleMainClassAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_MAIN_CLASS);
final ClassEntry mainClass;
public UnboundModuleMainClassAttribute(ClassEntry mainClass) {
super(Attributes.moduleMainClass());
this.mainClass = requireNonNull(mainClass);
}
@Override
public ClassEntry mainClass() {
return mainClass;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundModuleHashesAttribute
extends UnboundAttribute<ModuleHashesAttribute>
implements ModuleHashesAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_HASHES);
private final Utf8Entry algorithm;
private final List<ModuleHashInfo> hashes;
public UnboundModuleHashesAttribute(Utf8Entry algorithm, List<ModuleHashInfo> hashes) {
super(Attributes.moduleHashes());
this.algorithm = requireNonNull(algorithm);
this.hashes = List.copyOf(hashes);
}
@Override
public Utf8Entry algorithm() {
return algorithm;
}
@Override
public List<ModuleHashInfo> hashes() {
return hashes;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundModulePackagesAttribute
extends UnboundAttribute<ModulePackagesAttribute>
implements ModulePackagesAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_PACKAGES);
private final Collection<PackageEntry> packages;
public UnboundModulePackagesAttribute(Collection<PackageEntry> packages) {
super(Attributes.modulePackages());
this.packages = List.copyOf(packages);
}
@Override
public List<PackageEntry> packages() {
return List.copyOf(packages);
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundModuleResolutionAttribute
extends UnboundAttribute<ModuleResolutionAttribute>
implements ModuleResolutionAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_RESOLUTION);
private final int resolutionFlags;
public UnboundModuleResolutionAttribute(int flags) {
super(Attributes.moduleResolution());
resolutionFlags = flags;
}
@Override
public int resolutionFlags() {
return resolutionFlags;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundPermittedSubclassesAttribute
extends UnboundAttribute<PermittedSubclassesAttribute>
implements PermittedSubclassesAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_PERMITTED_SUBCLASSES);
private final List<ClassEntry> permittedSubclasses;
public UnboundPermittedSubclassesAttribute(List<ClassEntry> permittedSubclasses) {
super(Attributes.permittedSubclasses());
this.permittedSubclasses = List.copyOf(permittedSubclasses);
}
@Override
public List<ClassEntry> permittedSubclasses() {
return permittedSubclasses;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundNestMembersAttribute
extends UnboundAttribute<NestMembersAttribute>
implements NestMembersAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_MEMBERS);
private final List<ClassEntry> memberEntries;
public UnboundNestMembersAttribute(List<ClassEntry> memberEntries) {
super(Attributes.nestMembers());
this.memberEntries = List.copyOf(memberEntries);
}
@Override
public List<ClassEntry> nestMembers() {
return memberEntries;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundNestHostAttribute
extends UnboundAttribute<NestHostAttribute>
implements NestHostAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_HOST);
private final ClassEntry hostEntry;
public UnboundNestHostAttribute(ClassEntry hostEntry) {
super(Attributes.nestHost());
this.hostEntry = requireNonNull(hostEntry);
}
@Override
public ClassEntry nestHost() {
return hostEntry;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundCompilationIDAttribute
extends UnboundAttribute<CompilationIDAttribute>
implements CompilationIDAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_COMPILATION_ID);
private final Utf8Entry idEntry;
public UnboundCompilationIDAttribute(Utf8Entry idEntry) {
super(Attributes.compilationId());
this.idEntry = requireNonNull(idEntry);
}
@Override
public Utf8Entry compilationId() {
return idEntry;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundSourceIDAttribute
extends UnboundAttribute<SourceIDAttribute>
implements SourceIDAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_ID);
private final Utf8Entry idEntry;
public UnboundSourceIDAttribute(Utf8Entry idEntry) {
super(Attributes.sourceId());
this.idEntry = requireNonNull(idEntry);
}
@Override
public Utf8Entry sourceId() {
return idEntry;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundSourceDebugExtensionAttribute
extends UnboundAttribute<SourceDebugExtensionAttribute>
implements SourceDebugExtensionAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_DEBUG_EXTENSION);
private final byte[] contents;
public UnboundSourceDebugExtensionAttribute(byte[] contents) {
super(Attributes.sourceDebugExtension());
this.contents = requireNonNull(contents);
}
@Override
public byte[] contents() {
return contents;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundCharacterRangeTableAttribute
extends UnboundAttribute<CharacterRangeTableAttribute>
implements CharacterRangeTableAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE);
private final List<CharacterRangeInfo> ranges;
public UnboundCharacterRangeTableAttribute(List<CharacterRangeInfo> ranges) {
super(Attributes.characterRangeTable());
this.ranges = List.copyOf(ranges);
}
@Override
public List<CharacterRangeInfo> characterRangeTable() {
return ranges;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundLineNumberTableAttribute
extends UnboundAttribute<LineNumberTableAttribute>
implements LineNumberTableAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE);
private final List<LineNumberInfo> lines;
public UnboundLineNumberTableAttribute(List<LineNumberInfo> lines) {
super(Attributes.lineNumberTable());
this.lines = List.copyOf(lines);
}
@Override
public List<LineNumberInfo> lineNumbers() {
return lines;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundLocalVariableTableAttribute
extends UnboundAttribute<LocalVariableTableAttribute>
implements LocalVariableTableAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE);
private final List<LocalVariableInfo> locals;
public UnboundLocalVariableTableAttribute(List<LocalVariableInfo> locals) {
super(Attributes.localVariableTable());
this.locals = List.copyOf(locals);
}
@Override
public List<LocalVariableInfo> localVariables() {
return locals;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundLocalVariableTypeTableAttribute
extends UnboundAttribute<LocalVariableTypeTableAttribute>
implements LocalVariableTypeTableAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE);
private final List<LocalVariableTypeInfo> locals;
public UnboundLocalVariableTypeTableAttribute(List<LocalVariableTypeInfo> locals) {
super(Attributes.localVariableTypeTable());
this.locals = List.copyOf(locals);
}
@Override
public List<LocalVariableTypeInfo> localVariableTypes() {
return locals;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeVisibleAnnotationsAttribute
extends UnboundAttribute<RuntimeVisibleAnnotationsAttribute>
implements RuntimeVisibleAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_ANNOTATIONS);
private final List<Annotation> elements;
public UnboundRuntimeVisibleAnnotationsAttribute(List<Annotation> elements) {
super(Attributes.runtimeVisibleAnnotations());
this.elements = List.copyOf(elements);
}
@Override
public List<Annotation> annotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeInvisibleAnnotationsAttribute
extends UnboundAttribute<RuntimeInvisibleAnnotationsAttribute>
implements RuntimeInvisibleAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_ANNOTATIONS);
private final List<Annotation> elements;
public UnboundRuntimeInvisibleAnnotationsAttribute(List<Annotation> elements) {
super(Attributes.runtimeInvisibleAnnotations());
this.elements = List.copyOf(elements);
}
@Override
public List<Annotation> annotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeVisibleParameterAnnotationsAttribute
extends UnboundAttribute<RuntimeVisibleParameterAnnotationsAttribute>
implements RuntimeVisibleParameterAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
private final List<List<Annotation>> elements;
public UnboundRuntimeVisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) {
super(Attributes.runtimeVisibleParameterAnnotations());
// deep copy
var array = elements.toArray().clone();
for (int i = 0; i < array.length; i++) {
array[i] = List.copyOf((List<?>) array[i]);
}
this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array);
}
@Override
public List<List<Annotation>> parameterAnnotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute
extends UnboundAttribute<RuntimeInvisibleParameterAnnotationsAttribute>
implements RuntimeInvisibleParameterAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
private final List<List<Annotation>> elements;
public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) {
super(Attributes.runtimeInvisibleParameterAnnotations());
// deep copy
var array = elements.toArray().clone();
for (int i = 0; i < array.length; i++) {
array[i] = List.copyOf((List<?>) array[i]);
}
this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array);
}
@Override
public List<List<Annotation>> parameterAnnotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute
extends UnboundAttribute<RuntimeVisibleTypeAnnotationsAttribute>
implements RuntimeVisibleTypeAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
private final List<TypeAnnotation> elements;
public UnboundRuntimeVisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) {
super(Attributes.runtimeVisibleTypeAnnotations());
this.elements = List.copyOf(elements);
}
@Override
public List<TypeAnnotation> annotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute
extends UnboundAttribute<RuntimeInvisibleTypeAnnotationsAttribute>
implements RuntimeInvisibleTypeAnnotationsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
private final List<TypeAnnotation> elements;
public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) {
super(Attributes.runtimeInvisibleTypeAnnotations());
this.elements = List.copyOf(elements);
}
@Override
public List<TypeAnnotation> annotations() {
return elements;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public record UnboundCharacterRangeInfo(int startPc, int endPc,
int characterRangeStart,
int characterRangeEnd,
int flags)
implements CharacterRangeInfo { }
public record UnboundInnerClassInfo(ClassEntry innerClass,
Optional<ClassEntry> outerClass,
Optional<Utf8Entry> innerName,
int flagsMask)
implements InnerClassInfo {
public UnboundInnerClassInfo {
requireNonNull(innerClass);
requireNonNull(outerClass);
requireNonNull(innerName);
}
}
public record UnboundLineNumberInfo(int startPc, int lineNumber)
implements LineNumberInfo { }
public record UnboundLocalVariableInfo(int startPc, int length,
Utf8Entry name,
Utf8Entry type,
int slot)
implements LocalVariableInfo {
public UnboundLocalVariableInfo {
requireNonNull(name);
requireNonNull(type);
}
}
public record UnboundLocalVariableTypeInfo(int startPc, int length,
Utf8Entry name,
Utf8Entry signature,
int slot)
implements LocalVariableTypeInfo {
public UnboundLocalVariableTypeInfo {
requireNonNull(name);
requireNonNull(signature);
}
}
public record UnboundMethodParameterInfo(Optional<Utf8Entry> name, int flagsMask)
implements MethodParameterInfo {
public UnboundMethodParameterInfo {
requireNonNull(name);
}
}
public record UnboundModuleExportInfo(PackageEntry exportedPackage,
int exportsFlagsMask,
List<ModuleEntry> exportsTo)
implements ModuleExportInfo {
public UnboundModuleExportInfo {
requireNonNull(exportedPackage);
exportsTo = List.copyOf(exportsTo);
}
}
public record UnboundModuleHashInfo(ModuleEntry moduleName,
byte[] hash) implements ModuleHashInfo {
public UnboundModuleHashInfo {
requireNonNull(moduleName);
requireNonNull(hash);
}
}
public record UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask,
List<ModuleEntry> opensTo)
implements ModuleOpenInfo {
public UnboundModuleOpenInfo {
requireNonNull(openedPackage);
opensTo = List.copyOf(opensTo);
}
}
public record UnboundModuleProvideInfo(ClassEntry provides,
List<ClassEntry> providesWith)
implements ModuleProvideInfo {
public UnboundModuleProvideInfo {
requireNonNull(provides);
providesWith = List.copyOf(providesWith);
}
}
public record UnboundModuleRequiresInfo(ModuleEntry requires, int requiresFlagsMask,
Optional<Utf8Entry> requiresVersion)
implements ModuleRequireInfo {
public UnboundModuleRequiresInfo {
requireNonNull(requires);
requireNonNull(requiresVersion);
}
}
public record UnboundRecordComponentInfo(Utf8Entry name,
Utf8Entry descriptor,
List<Attribute<?>> attributes)
implements RecordComponentInfo {
public UnboundRecordComponentInfo {
requireNonNull(name);
requireNonNull(descriptor);
attributes = List.copyOf(attributes);
}
}
public record UnboundTypeAnnotation(TargetInfo targetInfo,
List<TypePathComponent> targetPath,
Annotation annotation) implements TypeAnnotation {
public UnboundTypeAnnotation {
requireNonNull(targetInfo);
targetPath = List.copyOf(targetPath);
requireNonNull(annotation);
}
}
public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePathKind, int typeArgumentIndex)
implements TypeAnnotation.TypePathComponent {}
public static final class UnboundModuleAttribute extends UnboundAttribute<ModuleAttribute> implements ModuleAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE);
private final ModuleEntry moduleName;
private final int moduleFlags;
private final Utf8Entry moduleVersion;
private final List<ModuleRequireInfo> requires;
private final List<ModuleExportInfo> exports;
private final List<ModuleOpenInfo> opens;
private final List<ClassEntry> uses;
private final List<ModuleProvideInfo> provides;
public UnboundModuleAttribute(ModuleEntry moduleName,
int moduleFlags,
Utf8Entry moduleVersion,
Collection<ModuleRequireInfo> requires,
Collection<ModuleExportInfo> exports,
Collection<ModuleOpenInfo> opens,
Collection<ClassEntry> uses,
Collection<ModuleProvideInfo> provides)
{
super(Attributes.module());
this.moduleName = requireNonNull(moduleName);
this.moduleFlags = moduleFlags;
this.moduleVersion = moduleVersion;
this.requires = List.copyOf(requires);
this.exports = List.copyOf(exports);
this.opens = List.copyOf(opens);
this.uses = List.copyOf(uses);
this.provides = List.copyOf(provides);
}
@Override
public ModuleEntry moduleName() {
return moduleName;
}
@Override
public int moduleFlagsMask() {
return moduleFlags;
}
@Override
public Optional<Utf8Entry> moduleVersion() {
return Optional.ofNullable(moduleVersion);
}
@Override
public List<ModuleRequireInfo> requires() {
return requires;
}
@Override
public List<ModuleExportInfo> exports() {
return exports;
}
@Override
public List<ModuleOpenInfo> opens() {
return opens;
}
@Override
public List<ClassEntry> uses() {
return uses;
}
@Override
public List<ModuleProvideInfo> provides() {
return provides;
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>>
extends UnboundAttribute<T> {
public AdHocAttribute(AttributeMapper<T> mapper) {
super(mapper);
}
public abstract void writeBody(BufWriterImpl b);
@Override
public void writeTo(BufWriterImpl b) {
b.writeIndex(b.constantPool().utf8Entry(mapper.name()));
int lengthIndex = b.skip(4);
writeBody(b);
int written = b.size() - lengthIndex - 4;
b.patchInt(lengthIndex, written);
}
}
public static final class EmptyBootstrapAttribute
extends UnboundAttribute<BootstrapMethodsAttribute>
implements BootstrapMethodsAttribute {
private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS);
public EmptyBootstrapAttribute() {
super(Attributes.bootstrapMethods());
}
@Override
public int bootstrapMethodsSize() {
return 0;
}
@Override
public List<BootstrapMethodEntry> bootstrapMethods() {
return List.of();
}
@Override
public Utf8Entry attributeName() {
return NAME;
}
}
}