mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8342466: Improve API documentation for java.lang.classfile.attribute
Reviewed-by: darcy, asotona
This commit is contained in:
parent
9782bfdd27
commit
973c630777
70 changed files with 2443 additions and 967 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, 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
|
||||
|
@ -24,54 +24,118 @@
|
|||
*/
|
||||
package java.lang.classfile;
|
||||
|
||||
import java.lang.classfile.attribute.BootstrapMethodsAttribute;
|
||||
import java.lang.classfile.attribute.CodeAttribute;
|
||||
import java.lang.classfile.attribute.UnknownAttribute;
|
||||
import java.lang.classfile.constantpool.ConstantPoolBuilder;
|
||||
import java.lang.classfile.constantpool.Utf8Entry;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Bidirectional mapper between the {@code class} file representation of an
|
||||
* attribute and its API model. The attribute mapper identifies an attribute
|
||||
* by its {@linkplain Attribute#attributeName name}, and is used to parse the
|
||||
* {@code class} file representation into a model, and to write the model
|
||||
* representation back to a {@code class} file.
|
||||
* <p>
|
||||
* {@link Attributes} defines the mappers for predefined attributes in the JVMS
|
||||
* and certain conventional attributes. For other attributes (JVMS {@jvms
|
||||
* 4.7.1}), users can define their own {@code AttributeMapper}; classes that
|
||||
* model those attributes should extend {@link CustomAttribute}. To read those
|
||||
* attributes, user-defined {@code AttributeMapper}s must be registered to the
|
||||
* {@link ClassFile.AttributeMapperOption}.
|
||||
*
|
||||
* @param <A> the attribute type
|
||||
* @see Attributes
|
||||
* @see ClassFile.AttributeMapperOption
|
||||
* @see java.lang.classfile.attribute
|
||||
* @since 24
|
||||
*/
|
||||
public interface AttributeMapper<A extends Attribute<A>> {
|
||||
|
||||
/**
|
||||
* Attribute stability indicator
|
||||
* Indicates the data dependency of the {@code class} file representation
|
||||
* of an attribute. Whether an attribute can be bulk-copied by its binary
|
||||
* representation to a new {@code class} file depends on if its data refers
|
||||
* to other parts of its enclosing {@code class} file.
|
||||
*
|
||||
* @apiNote
|
||||
* This dependency is called "stability" because it indicates the conditions
|
||||
* for a {@code class} file attribute to be eligible for bulk-copying to
|
||||
* another {@code class} file.
|
||||
*
|
||||
* @see AttributeMapper#stability()
|
||||
* @since 24
|
||||
*/
|
||||
enum AttributeStability {
|
||||
|
||||
/**
|
||||
* The attribute contains only pure data, such as timestamps, and can always be bulk-copied.
|
||||
* The attribute contains only standalone data, and has no reference to
|
||||
* other parts of its enclosing {@code class} file, besides the name of
|
||||
* the attribute. Thus, its contents can always be bulk-copied to
|
||||
* another {@code class} file.
|
||||
* <p>
|
||||
* For example, a bit mask is standalone data.
|
||||
*/
|
||||
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.
|
||||
* In addition to standalone data, the attribute refers to the constant
|
||||
* pool, including the {@link BootstrapMethodsAttribute BootstrapMethods}
|
||||
* attribute, of its enclosing {@code class} file. Thus, it can be
|
||||
* bulk-copied when the destination {@code class} file extends its
|
||||
* constant pool from that of the original {@code class}. It must be
|
||||
* expanded to translate constant pool references and rewritten when
|
||||
* constant pool indices are not compatible.
|
||||
* <p>
|
||||
* For example, a {@link Utf8Entry} is a reference to the constant pool.
|
||||
*
|
||||
* @see ConstantPoolBuilder#of(ClassModel)
|
||||
* @see ClassFile.ConstantPoolSharingOption
|
||||
*/
|
||||
CP_REFS,
|
||||
|
||||
/**
|
||||
* The attribute may contain labels, so need to be exploded and rewritten when the Code array is perturbed.
|
||||
* In addition to standalone data and references to the constant pool,
|
||||
* the attribute refers to positions into the {@code code} array of a
|
||||
* {@link CodeAttribute Code} attribute. Thus, it can be bulked-copied
|
||||
* when the {@code code} array is unchanged, which requires that the
|
||||
* destination {@code class} file extends its constant pool from that of
|
||||
* the original {@code class}. It must be expanded to translate {@link
|
||||
* Label}s or constant pool references and rewritten if the {@code code}
|
||||
* array is perturbed, including when constant pool indices are not
|
||||
* compatible.
|
||||
* <p>
|
||||
* For example, a bci value, modeled by a {@link Label}, is a reference
|
||||
* to a position in the {@code code} array.
|
||||
*/
|
||||
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.
|
||||
* The attribute refers to structures not managed by the library (type
|
||||
* variable lists, etc.). As a result, even when the attribute is
|
||||
* expanded, those references may not be correctly translated, and the
|
||||
* rewritten results may be incorrect.
|
||||
* <p>
|
||||
* If the attribute is read from a {@code class} file, {@link
|
||||
* ClassFile.AttributesProcessingOption} determines whether to preserve
|
||||
* or drop the attribute during transformation.
|
||||
*
|
||||
* @see ClassFile.AttributesProcessingOption#DROP_UNSTABLE_ATTRIBUTES
|
||||
*/
|
||||
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.
|
||||
* The attribute is completely unknown. As a result, expanding and
|
||||
* rewriting is not possible, and any difference between the destination
|
||||
* {@code class} file and its enclosing {@code class} file may make the
|
||||
* attribute incorrect.
|
||||
* <p>
|
||||
* {@link ClassFile.AttributesProcessingOption} determines whether to
|
||||
* preserve or drop the attribute during transformation.
|
||||
*
|
||||
* @see UnknownAttribute
|
||||
* @see ClassFile.AttributesProcessingOption#DROP_UNSTABLE_ATTRIBUTES
|
||||
* @see ClassFile.AttributesProcessingOption#DROP_UNKNOWN_ATTRIBUTES
|
||||
*/
|
||||
UNKNOWN
|
||||
}
|
||||
|
@ -82,35 +146,104 @@ public interface AttributeMapper<A extends Attribute<A>> {
|
|||
String name();
|
||||
|
||||
/**
|
||||
* Create an {@link Attribute} instance from a classfile.
|
||||
* Creates an {@link Attribute} instance from a {@code class} file for the
|
||||
* Class-File API.
|
||||
* <p>
|
||||
* This method is called by the Class-File API to support reading of
|
||||
* attributes. Users should never call this method.
|
||||
* <p>
|
||||
* The Class-File API makes these promises about the call to this method:
|
||||
* <ul>
|
||||
* <li>The {@link Utf8Entry} for the name of the attribute is accessible
|
||||
* with {@code cf.readEntry(pos - 6, Utf8Entry.class)}, and is validated;
|
||||
* <li>The length of the attribute is accessible with {@code cf.readInt(pos
|
||||
* - 4)}, and is validated to be positive and not beyond the length of the
|
||||
* {@code class} file;
|
||||
* <li>The {@link AttributedElement} attribute access functionalities on the
|
||||
* {@code enclosing} model may not be accessed when this method is called,
|
||||
* but can be accessed later by the returned attribute when it is accessible
|
||||
* to users.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The returned {@code Attribute} must fulfill these requirements:
|
||||
* <ul>
|
||||
* <li>{@link Attribute#attributeMapper()} returns this mapper;
|
||||
* <li>{@link Attribute#attributeName()} returns the attribute name in the
|
||||
* {@code class} file.
|
||||
* </ul>
|
||||
*
|
||||
* @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
|
||||
* @apiNote
|
||||
* Implementations of this method should perform minimal work to return an
|
||||
* attribute, as this method is called even if the resulting attribute is
|
||||
* never used. In particular, the implementation should avoid checking the
|
||||
* validity of the attribute {@code class} file data or performing actions
|
||||
* that may throw exceptions.
|
||||
*
|
||||
* @param enclosing the structure in which this attribute appears
|
||||
* @param cf provides access to the {@code class} file to read from
|
||||
* @param pos the offset into the {@code class} file at which the contents
|
||||
* of the attribute starts
|
||||
* @return the read attribute
|
||||
*/
|
||||
A readAttribute(AttributedElement enclosing, ClassReader cf, int pos);
|
||||
|
||||
/**
|
||||
* Write an {@link Attribute} instance to a classfile.
|
||||
* Writes an {@link Attribute} instance to a {@code class} file for the
|
||||
* Class-File API.
|
||||
* <p>
|
||||
* This method is called by the Class-File API to support writing of
|
||||
* attributes. Users should never call this method.
|
||||
* <p>
|
||||
* The Class-File API makes these promises about the call to this method:
|
||||
* <ul>
|
||||
* <li>{@link Attribute#attributeMapper() attr.attributeMapper()} returns
|
||||
* this mapper;
|
||||
* <li>The {@code buf} may already have data written, that its {@link
|
||||
* BufWriter#size() size} may not be {@code 0}.
|
||||
* </ul>
|
||||
* <p>
|
||||
* The {@code class} file writing must fulfill these requirements:
|
||||
* <ul>
|
||||
* <li>The attribute name {@code u2} and attribute length {@code u4} must
|
||||
* be written to the {@code buf};
|
||||
* <li>{@link Attribute#attributeName() attr.attributeName()} is written as
|
||||
* if with {@code buf.writeIndex(attr.attributeName())};
|
||||
* <li>The attribute length is the length, in bytes, of attribute contents
|
||||
* written to the {@code buf}, not including the 6 bytes used by the name
|
||||
* and the length;
|
||||
* <li>If any information in the API model of the attribute, {@code attr},
|
||||
* cannot be represented in the {@code class} file format of the attribute,
|
||||
* an {@link IllegalArgumentException} is thrown.
|
||||
* </ul>
|
||||
*
|
||||
* @param buf The {@link BufWriter} to which the attribute should be written
|
||||
* @param attr The attribute to write
|
||||
* @apiNote
|
||||
* {@link BufWriter#patchInt} can be used to update the attribute length
|
||||
* after the attribute contents are written to the {@code buf}.
|
||||
*
|
||||
* @param buf the {@link BufWriter} to which the attribute should be written
|
||||
* @param attr the attribute to write
|
||||
* @throws IllegalArgumentException if some data in the API model of the
|
||||
* attribute is invalid for the {@code class} file format
|
||||
*/
|
||||
void writeAttribute(BufWriter buf, A attr);
|
||||
|
||||
/**
|
||||
* {@return whether this attribute may appear more than once in a given location}
|
||||
* {@return whether this attribute may appear more than once in one
|
||||
* structure}
|
||||
* <p>
|
||||
* If an attribute does not allow multiple instances in one structure,
|
||||
* can be supplied to a {@link ClassFileBuilder}, and multiple instances of
|
||||
* the attribute are supplied to the builder, the last supplied attribute
|
||||
* appears on the built structure.
|
||||
*
|
||||
* @implSpec The default implementation returns {@code false}
|
||||
* @implSpec The default implementation returns {@code false}.
|
||||
*/
|
||||
default boolean allowMultiple() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return attribute stability indicator}
|
||||
* {@return the data dependency of this attribute on the {@code class} file}
|
||||
*/
|
||||
AttributeStability stability();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue