8343881: java.lang.classfile.Attribute attributeName() method should return Utf8Entry
Reviewed-by: liach
This commit is contained in:
parent
75c651f859
commit
ba39321902
@ -25,6 +25,7 @@
|
||||
package java.lang.classfile;
|
||||
|
||||
import java.lang.classfile.attribute.*;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
import jdk.internal.classfile.impl.BoundAttribute;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
@ -65,7 +66,7 @@ public sealed interface Attribute<A extends Attribute<A>>
|
||||
/**
|
||||
* {@return the name of the attribute}
|
||||
*/
|
||||
String attributeName();
|
||||
Utf8Entry attributeName();
|
||||
|
||||
/**
|
||||
* {@return the {@link AttributeMapper} associated with this attribute}
|
||||
|
@ -24,6 +24,8 @@
|
||||
*/
|
||||
package java.lang.classfile;
|
||||
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import jdk.internal.classfile.impl.TemporaryConstantPool;
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
|
||||
/**
|
||||
@ -55,8 +57,8 @@ public abstract non-sealed class CustomAttribute<T extends CustomAttribute<T>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String attributeName() {
|
||||
return mapper.name();
|
||||
public Utf8Entry attributeName() {
|
||||
return TemporaryConstantPool.INSTANCE.utf8Entry(mapper.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,7 +64,7 @@ public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
|
||||
@Override
|
||||
public final void writeAttribute(BufWriter writer, T attr) {
|
||||
BufWriterImpl buf = (BufWriterImpl) writer;
|
||||
buf.writeIndex(buf.constantPool().utf8Entry(name));
|
||||
buf.writeIndex(attr.attributeName());
|
||||
int lengthIndex = buf.skip(4);
|
||||
writeBody(buf, attr);
|
||||
int written = buf.size() - lengthIndex - 4;
|
||||
|
@ -47,6 +47,7 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||
private final AttributeMapper<T> mapper;
|
||||
final ClassReaderImpl classReader;
|
||||
final int payloadStart;
|
||||
Utf8Entry name;
|
||||
|
||||
BoundAttribute(ClassReader classReader, AttributeMapper<T> mapper, int payloadStart) {
|
||||
this.mapper = mapper;
|
||||
@ -59,8 +60,11 @@ public abstract sealed class BoundAttribute<T extends Attribute<T>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public String attributeName() {
|
||||
return mapper.name();
|
||||
public Utf8Entry attributeName() {
|
||||
if (name == null) {
|
||||
name = classReader.readEntry(payloadStart - 6, Utf8Entry.class);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -574,7 +574,7 @@ public final class ClassPrinterImpl {
|
||||
list("flags", "flag", clm.flags().flags().stream().map(AccessFlag::name)),
|
||||
leaf("superclass", clm.superclass().map(ClassEntry::asInternalName).orElse("")),
|
||||
list("interfaces", "interface", clm.interfaces().stream().map(ClassEntry::asInternalName)),
|
||||
list("attributes", "attribute", clm.attributes().stream().map(Attribute::attributeName)))
|
||||
list("attributes", "attribute", clm.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue)))
|
||||
.with(constantPoolToTree(clm.constantPool(), verbosity))
|
||||
.with(attributesToTree(clm.attributes(), verbosity))
|
||||
.with(new ListNodeImpl(BLOCK, "fields", clm.fields().stream().map(f ->
|
||||
@ -672,7 +672,7 @@ public final class ClassPrinterImpl {
|
||||
"flag", f.flags().flags().stream().map(AccessFlag::name)),
|
||||
leaf("field type", f.fieldType().stringValue()),
|
||||
list("attributes",
|
||||
"attribute", f.attributes().stream().map(Attribute::attributeName)))
|
||||
"attribute", f.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue)))
|
||||
.with(attributesToTree(f.attributes(), verbosity));
|
||||
}
|
||||
|
||||
@ -683,7 +683,7 @@ public final class ClassPrinterImpl {
|
||||
"flag", m.flags().flags().stream().map(AccessFlag::name)),
|
||||
leaf("method type", m.methodType().stringValue()),
|
||||
list("attributes",
|
||||
"attribute", m.attributes().stream().map(Attribute::attributeName)))
|
||||
"attribute", m.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue)))
|
||||
.with(attributesToTree(m.attributes(), verbosity))
|
||||
.with(codeToTree((CodeAttribute)m.code().orElse(null), verbosity));
|
||||
}
|
||||
@ -694,7 +694,7 @@ public final class ClassPrinterImpl {
|
||||
codeNode.with(leaf("max stack", com.maxStack()));
|
||||
codeNode.with(leaf("max locals", com.maxLocals()));
|
||||
codeNode.with(list("attributes",
|
||||
"attribute", com.attributes().stream().map(Attribute::attributeName)));
|
||||
"attribute", com.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue)));
|
||||
var stackMap = new MapNodeImpl(BLOCK, "stack map frames");
|
||||
var visibleTypeAnnos = new LinkedHashMap<Integer, List<TypeAnnotation>>();
|
||||
var invisibleTypeAnnos = new LinkedHashMap<Integer, List<TypeAnnotation>>();
|
||||
@ -996,7 +996,7 @@ public final class ClassPrinterImpl {
|
||||
"name", rc.name().stringValue(),
|
||||
"type", rc.descriptor().stringValue()))
|
||||
.with(list("attributes", "attribute", rc.attributes().stream()
|
||||
.map(Attribute::attributeName)))
|
||||
.map(Attribute::attributeName).map(Utf8Entry::stringValue)))
|
||||
.with(attributesToTree(rc.attributes(), verbosity)))));
|
||||
case AnnotationDefaultAttribute ada ->
|
||||
nodes.add(new MapNodeImpl(FLOW, "annotation default").with(elementValueToTree(ada.defaultValue())));
|
||||
|
@ -241,6 +241,11 @@ public final class DirectCodeBuilder
|
||||
if (crSize < characterRangesCount)
|
||||
b.patchU2(pos, crSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return constantPool.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE);
|
||||
}
|
||||
};
|
||||
attributes.withAttribute(a);
|
||||
}
|
||||
@ -265,6 +270,11 @@ public final class DirectCodeBuilder
|
||||
if (lvSize < localVariablesCount)
|
||||
b.patchU2(pos, lvSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return constantPool.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE);
|
||||
}
|
||||
};
|
||||
attributes.withAttribute(a);
|
||||
}
|
||||
@ -289,6 +299,11 @@ public final class DirectCodeBuilder
|
||||
if (lvtSize < localVariableTypesCount)
|
||||
b.patchU2(pos, lvtSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return constantPool.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE);
|
||||
}
|
||||
};
|
||||
attributes.withAttribute(a);
|
||||
}
|
||||
@ -371,6 +386,11 @@ public final class DirectCodeBuilder
|
||||
dcb.attributes.writeTo(buf);
|
||||
buf.setLabelContext(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return constantPool.utf8Entry(Attributes.NAME_CODE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -416,6 +436,11 @@ public final class DirectCodeBuilder
|
||||
b.writeU2(buf.size() / 4);
|
||||
b.writeBytes(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return buf.constantPool().utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean codeAndExceptionsMatch(int codeLength) {
|
||||
|
@ -146,6 +146,11 @@ public final class SplitConstantPool implements ConstantPoolBuilder {
|
||||
for (int i = 0; i < bsmSize; i++)
|
||||
bootstrapMethodEntry(i).writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS);
|
||||
}
|
||||
};
|
||||
a.writeTo(buf);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import java.lang.classfile.constantpool.ConstantDynamicEntry;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.InvokeDynamicEntry;
|
||||
import java.lang.classfile.constantpool.MemberRefEntry;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
import java.util.ArrayList;
|
||||
@ -401,6 +402,11 @@ public final class StackMapGenerator {
|
||||
prevFrame = fr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cp.utf8Entry(Attributes.NAME_STACK_MAP_TABLE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,6 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String attributeName() {
|
||||
return mapper.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTo(BufWriterImpl buf) {
|
||||
@ -93,6 +88,8 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -105,27 +102,50 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -137,11 +157,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -153,11 +181,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -169,10 +205,18 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -185,10 +229,17 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -200,11 +251,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -216,11 +275,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -232,11 +299,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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;
|
||||
|
||||
@ -255,11 +330,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -271,11 +354,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -287,11 +378,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -303,11 +402,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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;
|
||||
|
||||
@ -326,11 +433,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -342,11 +457,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -358,11 +481,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -374,11 +505,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -390,11 +529,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -406,11 +553,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -422,11 +577,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -438,11 +601,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -454,11 +625,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -470,11 +649,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -486,11 +673,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -502,11 +697,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -518,11 +721,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -534,11 +745,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -550,11 +769,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -572,11 +799,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -594,11 +829,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -610,11 +853,19 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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) {
|
||||
@ -626,6 +877,11 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
public List<TypeAnnotation> annotations() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
|
||||
public record UnboundCharacterRangeInfo(int startPc, int endPc,
|
||||
@ -749,6 +1005,9 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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;
|
||||
@ -817,6 +1076,11 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
public List<ModuleProvideInfo> provides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>>
|
||||
@ -841,6 +1105,9 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
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());
|
||||
}
|
||||
@ -854,5 +1121,10 @@ public abstract sealed class UnboundAttribute<T extends Attribute<T>>
|
||||
public List<BootstrapMethodEntry> bootstrapMethods() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -281,6 +281,11 @@ public class Util {
|
||||
b.writeBytes(bytecode.array(), 0, bytecode.length());
|
||||
b.writeU2U2(0, 0);//exception handlers & attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cp.utf8Entry(Attributes.NAME_CODE);
|
||||
}
|
||||
}))));
|
||||
ClassPrinter.toYaml(clm.methods().get(0).code().get(), ClassPrinter.Verbosity.TRACE_ALL, dump);
|
||||
} catch (Error | Exception _) {
|
||||
|
@ -176,8 +176,8 @@ public record ParserVerifier(ClassModel classModel) {
|
||||
if (cfe instanceof AttributedElement ae) {
|
||||
var attrNames = new HashSet<String>();
|
||||
for (var a : ae.attributes()) {
|
||||
if (!a.attributeMapper().allowMultiple() && !attrNames.add(a.attributeName())) {
|
||||
errors.add(new VerifyError("Multiple %s attributes in %s".formatted(a.attributeName(), toString(ae))));
|
||||
if (!a.attributeMapper().allowMultiple() && !attrNames.add(a.attributeName().stringValue())) {
|
||||
errors.add(new VerifyError("Multiple %s attributes in %s".formatted(a.attributeName().stringValue(), toString(ae))));
|
||||
}
|
||||
verifyAttribute(ae, a, errors);
|
||||
}
|
||||
@ -331,7 +331,7 @@ public record ParserVerifier(ClassModel classModel) {
|
||||
throw new AssertionError(a);
|
||||
};
|
||||
if (size >= 0 && size != ((BoundAttribute)a).payloadLen()) {
|
||||
errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName(), toString(ae))));
|
||||
errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName().stringValue(), toString(ae))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ public class AttributeWriter extends BasicWriter {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
print(" ");
|
||||
print(attr.attributeName());
|
||||
print(attr.attributeName().stringValue());
|
||||
print(": ");
|
||||
print("length = 0x" + toHex(data.length));
|
||||
print(" (unknown attribute)");
|
||||
|
@ -41,6 +41,7 @@ import java.lang.classfile.CodeBuilder;
|
||||
import java.lang.classfile.attribute.MethodParameterInfo;
|
||||
import java.lang.classfile.attribute.MethodParametersAttribute;
|
||||
import java.lang.classfile.constantpool.ConstantPoolException;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.constant.ConstantDescs;
|
||||
import java.lang.constant.MethodTypeDesc;
|
||||
@ -89,6 +90,11 @@ class BoundAttributeTest {
|
||||
b.writeIndex(oneClass);
|
||||
b.writeIndex(oneClassString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cp.utf8Entry(Attributes.NAME_NEST_MEMBERS);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -93,6 +93,11 @@ class CorpusTest {
|
||||
b.writeU2(curPc);
|
||||
b.writeU2(ln.line());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cob.constantPool().utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE);
|
||||
}
|
||||
});
|
||||
case LocalVariable lv -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTable()) {
|
||||
@Override
|
||||
@ -100,6 +105,11 @@ class CorpusTest {
|
||||
b.writeU2(1);
|
||||
Util.writeLocalVariable(b, lv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cob.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE);
|
||||
}
|
||||
});
|
||||
case LocalVariableType lvt -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTypeTable()) {
|
||||
@Override
|
||||
@ -107,6 +117,11 @@ class CorpusTest {
|
||||
b.writeU2(1);
|
||||
Util.writeLocalVariable(b, lvt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cob.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE);
|
||||
}
|
||||
});
|
||||
default -> cob.with(coe);
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import java.lang.classfile.attribute.LocalVariableTableAttribute;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.ConstantPoolException;
|
||||
import java.lang.classfile.constantpool.IntegerEntry;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
@ -49,6 +50,7 @@ import jdk.internal.classfile.impl.DirectMethodBuilder;
|
||||
import jdk.internal.classfile.impl.LabelContext;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class LimitsTest {
|
||||
@ -145,7 +147,13 @@ class LimitsTest {
|
||||
b.writeInt(-2); //npairs to jump back and cause OOME if not checked
|
||||
b.writeU2(0);//exception handlers
|
||||
b.writeU2(0);//attributes
|
||||
}})))).methods().get(0).code().get().elementList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return mb.constantPool().utf8Entry(Attributes.NAME_CODE);
|
||||
}
|
||||
})))).methods().get(0).code().get().elementList());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -167,7 +175,13 @@ class LimitsTest {
|
||||
b.writeInt(-5); //high to jump back and cause OOME if not checked
|
||||
b.writeU2(0);//exception handlers
|
||||
b.writeU2(0);//attributes
|
||||
}})))).methods().get(0).code().get().elementList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return mb.constantPool().utf8Entry(Attributes.NAME_CODE);
|
||||
}
|
||||
})))).methods().get(0).code().get().elementList());
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
ClassFile.of().parse(ClassFile.of().build(ClassDesc.of("TableSwitchClass"), cb -> cb.withMethod(
|
||||
"tableSwitchMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb ->
|
||||
@ -189,7 +203,13 @@ class LimitsTest {
|
||||
b.writeInt(Integer.MAX_VALUE - 4); //high to jump back and cause infinite loop
|
||||
b.writeU2(0);//exception handlers
|
||||
b.writeU2(0);//attributes
|
||||
}})))).methods().get(0).code().get().elementList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return mb.constantPool().utf8Entry(Attributes.NAME_CODE);
|
||||
}
|
||||
})))).methods().get(0).code().get().elementList());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -76,7 +76,7 @@ class LowJCovAttributeTest {
|
||||
private void testRead0() {
|
||||
int[] mask = new int[1];
|
||||
for (Attribute<?> attr : classLow.attributes()) {
|
||||
switch (attr.attributeName()) {
|
||||
switch (attr.attributeName().stringValue()) {
|
||||
case Attributes.NAME_COMPILATION_ID: {
|
||||
CompilationIDAttribute cid = (CompilationIDAttribute) attr;
|
||||
Utf8Entry v = cid.compilationId();
|
||||
|
@ -77,7 +77,7 @@ class LowModuleTest {
|
||||
|
||||
private void testRead0(ClassModel classLow) {
|
||||
for (Attribute<?> attr : classLow.attributes()) {
|
||||
switch (attr.attributeName()) {
|
||||
switch (attr.attributeName().stringValue()) {
|
||||
case Attributes.NAME_SOURCE_FILE: {
|
||||
SourceFileAttribute sfa = (SourceFileAttribute) attr;
|
||||
Utf8Entry sf = sfa.sourceFile();
|
||||
|
@ -31,7 +31,9 @@
|
||||
import java.io.IOException;
|
||||
import java.lang.classfile.constantpool.PoolEntry;
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
import static java.lang.constant.ConstantDescs.*;
|
||||
|
||||
import java.lang.invoke.MethodHandleInfo;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
@ -47,12 +49,14 @@ import java.util.stream.Stream;
|
||||
import java.lang.classfile.*;
|
||||
import java.lang.classfile.attribute.*;
|
||||
import java.lang.classfile.components.ClassPrinter;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
import java.lang.constant.ModuleDesc;
|
||||
|
||||
import jdk.internal.classfile.impl.BufWriterImpl;
|
||||
import jdk.internal.classfile.impl.DirectClassBuilder;
|
||||
import jdk.internal.classfile.impl.UnboundAttribute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class VerifierSelfTest {
|
||||
@ -109,6 +113,11 @@ class VerifierSelfTest {
|
||||
public void writeBody(BufWriterImpl b) {
|
||||
b.writeU2(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utf8Entry attributeName() {
|
||||
return cb.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE);
|
||||
}
|
||||
}));
|
||||
assertTrue(cc.verify(bytes).stream().anyMatch(e -> e.getMessage().contains("Invalid LocalVariableTable attribute location")));
|
||||
}
|
||||
@ -366,7 +375,7 @@ class VerifierSelfTest {
|
||||
super(new AttributeMapper<CloneAttribute>(){
|
||||
@Override
|
||||
public String name() {
|
||||
return a.attributeName();
|
||||
return a.attributeName().stringValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -234,7 +234,7 @@ public record ClassRecord(
|
||||
public static AttributesRecord ofStreamingElements(Supplier<Stream<? extends ClassFileElement>> elements, ConstantPool cp, CompatibilityFilter... cf) {
|
||||
Map<String, Attribute<?>> attrs = elements.get().filter(e -> e instanceof Attribute<?>)
|
||||
.map(e -> (Attribute<?>) e)
|
||||
.collect(toMap(Attribute::attributeName, e -> e));
|
||||
.collect(toMap(a -> a.attributeName().stringValue(), e -> e));
|
||||
return new AttributesRecord(
|
||||
mapAttr(attrs, annotationDefault(), a -> ElementValueRecord.ofElementValue(a.defaultValue())),
|
||||
cp == null ? null : IntStream.range(0, cp.bootstrapMethodCount()).mapToObj(i -> BootstrapMethodRecord.ofBootstrapMethodEntry(cp.bootstrapMethodEntry(i))).collect(toSetOrNull()),
|
||||
|
@ -59,8 +59,8 @@ class RebuildingTransformation {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute a -> fb.with(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null)));
|
||||
case SignatureAttribute a -> fb.with(SignatureAttribute.of(Signature.parseFrom(a.asTypeSignature().signatureString())));
|
||||
case SyntheticAttribute a -> fb.with(SyntheticAttribute.of());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -91,8 +91,8 @@ class RebuildingTransformation {
|
||||
case RuntimeVisibleTypeAnnotationsAttribute a -> mb.with(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null)));
|
||||
case SignatureAttribute a -> mb.with(SignatureAttribute.of(MethodSignature.parseFrom(a.asMethodSignature().signatureString())));
|
||||
case SyntheticAttribute a -> mb.with(SyntheticAttribute.of());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -131,7 +131,7 @@ class RebuildingTransformation {
|
||||
case RuntimeVisibleAnnotationsAttribute rvaa -> rcac.accept(RuntimeVisibleAnnotationsAttribute.of(transformAnnotations(rvaa.annotations())));
|
||||
case RuntimeVisibleTypeAnnotationsAttribute rvtaa -> rcac.accept(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(rvtaa.annotations(), null, null)));
|
||||
case SignatureAttribute sa -> rcac.accept(SignatureAttribute.of(Signature.parseFrom(sa.asTypeSignature().signatureString())));
|
||||
default -> throw new AssertionError("Unexpected record component attribute: " + rca.attributeName());
|
||||
default -> throw new AssertionError("Unexpected record component attribute: " + rca.attributeName().stringValue());
|
||||
}}).toArray(Attribute[]::new))).toArray(RecordComponentInfo[]::new)));
|
||||
case RuntimeInvisibleAnnotationsAttribute a -> clb.with(RuntimeInvisibleAnnotationsAttribute.of(transformAnnotations(a.annotations())));
|
||||
case RuntimeInvisibleTypeAnnotationsAttribute a -> clb.with(RuntimeInvisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null)));
|
||||
@ -142,8 +142,8 @@ class RebuildingTransformation {
|
||||
case SourceFileAttribute a -> clb.with(SourceFileAttribute.of(a.sourceFile().stringValue()));
|
||||
case SourceIDAttribute a -> clb.with(SourceIDAttribute.of(a.sourceId().stringValue()));
|
||||
case SyntheticAttribute a -> clb.with(SyntheticAttribute.of());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName());
|
||||
case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue());
|
||||
case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -595,7 +595,7 @@ class RebuildingTransformation {
|
||||
transformFrameTypeInfos(fr.locals(), cob, labels),
|
||||
transformFrameTypeInfos(fr.stack(), cob, labels))).toList()));
|
||||
case CustomAttribute a ->
|
||||
throw new AssertionError("Unexpected custom attribute: " + a.attributeName());
|
||||
throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public class AnnotationDefaultTest extends TestResult {
|
||||
checkEquals(countNumberOfAttributes(method.attributes()),
|
||||
1L,
|
||||
"Number of AnnotationDefault attribute");
|
||||
checkEquals(attr.attributeName(),
|
||||
checkEquals(attr.attributeName().stringValue(),
|
||||
"AnnotationDefault", "attribute_name_index");
|
||||
|
||||
ExpectedValues expectedValue = expectedValues.get(methodName);
|
||||
|
@ -169,7 +169,7 @@ public class EnclosingMethodTest extends TestResult {
|
||||
// stop checking, attr is null. test case failed
|
||||
return;
|
||||
}
|
||||
checkEquals(attr.attributeName(),
|
||||
checkEquals(attr.attributeName().stringValue(),
|
||||
"EnclosingMethod",
|
||||
"attribute_name_index of EnclosingMethod attribute in the class : " + className);
|
||||
checkEquals(((BoundAttribute<?>)attr).payloadLen(), 4,
|
||||
|
@ -138,7 +138,7 @@ public class LineNumberTestBase extends TestBase {
|
||||
private <T extends Attribute<T>> int countAttributes(AttributeMapper<T> attr, AttributedElement attributedElement) {
|
||||
int i = 0;
|
||||
for (Attribute<?> attribute : attributedElement.attributes()) {
|
||||
if (attribute.attributeName().equals(attr.name())) {
|
||||
if (attribute.attributeName().equalsString(attr.name())) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ public class Driver extends TestResult {
|
||||
|
||||
SignatureAttribute attribute = sup.get();
|
||||
if (expectedSignature != null && checkNotNull(attribute, memberName + " must have attribute")) {
|
||||
checkEquals(attribute.attributeName(),
|
||||
checkEquals(attribute.attributeName().stringValue(),
|
||||
"Signature", "Attribute's name : " + memberName);
|
||||
checkEquals(((BoundAttribute<?>)attribute).payloadLen(), 2, "Attribute's length : " + memberName);
|
||||
checkEquals(attribute.signature().stringValue(),
|
||||
|
@ -108,7 +108,7 @@ public class SourceFileTestBase extends TestBase {
|
||||
|
||||
SourceFileAttribute attribute = sourceFileAttributes.get(0);
|
||||
|
||||
assertEquals(attribute.attributeName(), Attributes.sourceFile().name(), "Incorrect attribute name");
|
||||
assertEquals(attribute.attributeName().stringValue(), Attributes.sourceFile().name(), "Incorrect attribute name");
|
||||
assertEquals(attribute.sourceFile().stringValue(), fileName,
|
||||
"Incorrect source file name");
|
||||
assertEquals(((BoundAttribute<?>)attribute).payloadLen(), 2, "Incorrect attribute length");
|
||||
|
@ -302,7 +302,7 @@ public class DeprecatedTest extends TestResult {
|
||||
if (checkNotNull(attr, name + " must have deprecated attribute")) {
|
||||
checkEquals(0, ((BoundAttribute<?>)attr).payloadLen(),
|
||||
"attribute_length should equal to 0");
|
||||
checkEquals("Deprecated", attr.attributeName(),
|
||||
checkEquals("Deprecated", attr.attributeName().stringValue(),
|
||||
name + " attribute_name_index");
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ public abstract class InnerClassesTestBase extends TestResult {
|
||||
if (!checkNotNull(innerClasses, "InnerClasses attribute should not be null")) {
|
||||
return;
|
||||
}
|
||||
checkEquals(innerClasses.attributeName(), "InnerClasses",
|
||||
checkEquals(innerClasses.attributeName().stringValue(), "InnerClasses",
|
||||
"innerClasses.attribute_name_index");
|
||||
// Inner Classes attribute consists of length (2 bytes)
|
||||
// and 8 bytes for each inner class's entry.
|
||||
|
@ -76,7 +76,7 @@ public class CheckSubtypesOfSealedTest extends TestBase {
|
||||
void check(ClassModel classFile) throws Exception {
|
||||
boolean found = false;
|
||||
for (Attribute<?> attr: classFile.attributes()) {
|
||||
if (attr.attributeName().equals("PermittedSubclasses")) {
|
||||
if (attr.attributeName().equalsString("PermittedSubclasses")) {
|
||||
PermittedSubclassesAttribute permittedSubclasses = (PermittedSubclassesAttribute)attr;
|
||||
found = true;
|
||||
if (permittedSubclasses.permittedSubclasses().isEmpty()) {
|
||||
@ -99,7 +99,7 @@ public class CheckSubtypesOfSealedTest extends TestBase {
|
||||
NOT_SEALED {
|
||||
void check(ClassModel classFile) throws Exception {
|
||||
for (Attribute<?> attr: classFile.attributes()) {
|
||||
if (attr.attributeName().equals("PermittedSubclasses")) {
|
||||
if (attr.attributeName().equalsString("PermittedSubclasses")) {
|
||||
throw new AssertionError(classFile.thisClass().name() + " should not be sealed");
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class T6716452 {
|
||||
if (!c.isAssignableFrom(mm.attributes().get(index).getClass())) {
|
||||
error(mm + ": unexpected attribute found,"
|
||||
+ " expected " + c.getName()
|
||||
+ " found " + mm.attributes().get(index).attributeName());
|
||||
+ " found " + mm.attributes().get(index).attributeName().stringValue());
|
||||
}
|
||||
} else {
|
||||
error(mm + ": expected attribute " + attr.name() + " not found");
|
||||
|
Loading…
x
Reference in New Issue
Block a user