Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8342468: Improve API documentation for java.lang.classfile.constantpool #23046

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -25,7 +25,9 @@

package java.lang.classfile;

import java.lang.classfile.attribute.BootstrapMethodsAttribute;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.LoadableConstantEntry;
import java.lang.classfile.constantpool.MethodHandleEntry;
import java.util.List;
Expand All @@ -34,22 +36,40 @@

/**
* Models an entry in the bootstrap method table. The bootstrap method table
* is stored in the {@code BootstrapMethods} attribute, but is modeled by
* the {@link ConstantPool}, since the bootstrap method table is logically
* part of the constant pool.
* is stored in the {@link BootstrapMethodsAttribute BootstrapMethods}
* attribute, but is modeled by the {@link ConstantPool}, since the bootstrap
* method table is logically part of the constant pool.
* <p>
* A bootstrap method entry is composite:
* {@snippet lang=text :
* // @link substring="BootstrapMethodEntry" target="ConstantPoolBuilder#bsmEntry(MethodHandleEntry, List)" :
* BootstrapMethodEntry(
* MethodHandleEntry bootstrapMethod, // @link substring="bootstrapMethod" target="#bootstrapMethod"
* List<LoadableConstantEntry> arguments // @link substring="arguments" target="#arguments()"
* )
* }
*
* @see ConstantPoolBuilder#bsmEntry ConstantPoolBuilder::bsmEntry
* @since 24
*/
public sealed interface BootstrapMethodEntry
permits BootstrapMethodEntryImpl {

/**
* {@return the constant pool associated with this entry}
*
* @apiNote
* Given a {@link ConstantPoolBuilder} {@code builder} and a {@code
* BootstrapMethodEntry} {@code entry}, use {@link
* ConstantPoolBuilder#canWriteDirect
* builder.canWriteDirect(entry.constantPool())} instead of object equality
* of the constant pool to determine if an entry is compatible.
*/
ConstantPool constantPool();

/**
* {@return the index into the bootstrap method table corresponding to this entry}
* {@return the index into the bootstrap method table corresponding to this
* entry}
*/
int bsmIndex();

Expand Down
53 changes: 44 additions & 9 deletions src/java.base/share/classes/java/lang/classfile/ClassFile.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -140,21 +140,56 @@ static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyReso

/**
* Option describing whether to preserve the original constant pool when
* transforming a classfile. Reusing the constant pool enables significant
* optimizations in processing time and minimizes differences between the
* original and transformed classfile, but may result in a bigger classfile
* when a classfile is significantly transformed.
* Default is {@code SHARED_POOL} to preserve the original constant
* pool.
* transforming a {@code class} file. Reusing the constant pool enables
* significant optimizations in processing time and minimizes differences
* between the original and transformed {@code class} files, but may result
* in a bigger transformed {@code class} file when many elements of the
* original {@code class} file are dropped and many original constant
* pool entries become unused. Default is {@link #SHARED_POOL} to preserve
* the original constant pool.
*
* @see ConstantPoolBuilder
* @see #build(ClassEntry, ConstantPoolBuilder, Consumer)
* @see #transformClass(ClassModel, ClassTransform)
* @since 24
*/
enum ConstantPoolSharingOption implements Option {

/** Preserves the original constant pool when transforming classfile */
/**
* Preserves the original constant pool when transforming the {@code
* class} file.
* <p>
* These two transformations below are equivalent:
* {@snippet lang=java :
* ClassModel originalClass = null; // @replace substring=null; replacement=...
* ClassDesc resultClassName = null; // @replace substring=null; replacement=...
* ClassTransform classTransform = null; // @replace substring=null; replacement=...
* var resultOne = ClassFile.of(ConstantPoolSharingOption.SHARED_POOL)
* .transformClass(originalClass, resultClassName, classTransform);
* var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(originalClass),
* clb -> clb.transform(originalClass, classTransform));
* }
*
* @see ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel)
*/
SHARED_POOL,

/** Creates a new constant pool when transforming classfile */
/**
* Creates a new constant pool when transforming the {@code class} file.
* <p>
* These two transformations below are equivalent:
* {@snippet lang=java :
* ClassModel originalClass = null; // @replace substring=null; replacement=...
* ClassDesc resultClassName = null; // @replace substring=null; replacement=...
* ClassTransform classTransform = null; // @replace substring=null; replacement=...
* var resultOne = ClassFile.of(ConstantPoolSharingOption.NEW_POOL)
* .transformClass(originalClass, resultClassName, classTransform);
* var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(),
* clb -> clb.transform(originalClass, classTransform));
* }
*
* @see ConstantPoolBuilder#of() ConstantPoolBuilder::of()
*/
NEW_POOL
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -28,10 +28,9 @@
import java.lang.constant.ConstantDesc;

/**
* A constant pool entry that may be used by annotation constant values,
* which includes the four kinds of primitive constants and UTF8 constants.
* These entries are also the only entries that do not refer to other
* constant pool entries.
* Marker interface for constant pool entries that can represent constant values
* associated with elements of annotations. They are also the only entries that
* do not refer to other constant pool entries.
*
* @apiNote
* An annotation constant value entry alone is not sufficient to determine
Expand All @@ -40,16 +39,17 @@
* in {@link AnnotationValue.OfInt}.
*
* @see AnnotationValue.OfConstant
* @jvms 4.7.16.1 The {@code element_value} structure
* @sealedGraph
* @since 24
*/
public sealed interface AnnotationConstantValueEntry extends PoolEntry
permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, Utf8Entry {

/**
* {@return the constant value} The constant value will be an {@link Integer},
* {@link Long}, {@link Float}, {@link Double} for the primitive constants,
* or {@link String} for UTF8 constants.
* {@return the constant value} The constant value will be an {@link
* Integer}, {@link Long}, {@link Float}, {@link Double} for the primitive
* constants, or {@link String} for UTF8 constants.
*/
ConstantDesc constantValue();
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -30,33 +30,82 @@
import jdk.internal.classfile.impl.AbstractPoolEntry;

/**
* Models a {@code CONSTANT_Class_info} constant in the constant pool of a
* classfile.
* @jvms 4.4.1 The CONSTANT_Class_info Structure
* Models a {@code CONSTANT_Class_info} structure, representing a reference
* type, in the constant pool of a {@code class} file.
* <p>
* The use of a {@code ClassEntry} is modeled by a {@link ClassDesc} that is not
* primitive. Conversions are through {@link ConstantPoolBuilder#classEntry(
* ClassDesc)} and {@link #asSymbol()}.
* <p>
* A {@code ClassEntry} is composite:
* {@snippet lang=text :
* // @link substring="ClassEntry" target="ConstantPoolBuilder#classEntry(Utf8Entry)" :
* ClassEntry(Utf8Entry name) // @link substring="name" target="#name"
* }
* where {@code name} represents:
* <ul>
* <li>The internal form of a binary name (JVMS {@jvms 4.2.1}), if and only if
* this {@code ClassEntry} represents a class or interface, such as {@code
* java/lang/String} for the {@link String} class.
* <li>A field descriptor string (JVMS {@jvms 4.3.2}) representing an array type,
* if and only if this {@code ClassEntry} represents an array type, such as
* {@code [I} for the {@code int[]} type, or {@code [Ljava/lang/String;} for the
* {@code String[]} type.
* </ul>
* A field descriptor string for an array type can be distinguished by its
* leading {@code '['} character.
*
* @apiNote
* The internal form of a binary name, where all occurrences of {@code .} in the
* name are replaced by {@code /}, is informally known as an <dfn>{@index
* "internal name"}</dfn>. This concept also applies to package names in
* addition to class and interface names.
*
* @see ConstantPoolBuilder#classEntry ConstantPoolBuilder::classEntry
* @see ClassDesc
* @jvms 4.4.1 The {@code CONSTANT_Class_info} Structure
* @since 24
*/
public sealed interface ClassEntry
extends LoadableConstantEntry
permits AbstractPoolEntry.ClassEntryImpl {

/**
* {@inheritDoc}
* <p>
* This is equivalent to {@link #asSymbol() asSymbol()}.
*/
@Override
default ConstantDesc constantValue() {
return asSymbol();
}

/**
* {@return the UTF8 constant pool entry for the class name}
* {@return the {@code Utf8Entry} referred by this structure} If the
* value of the UTF8 starts with a {@code [}, this represents an array type
* and the value is a descriptor string; otherwise, this represents a class
* or interface and the value is the {@linkplain ##internalname internal
* form} of a binary name.
*
* @see ConstantPoolBuilder#classEntry(Utf8Entry)
* ConstantPoolBuilder::classEntry(Utf8Entry)
*/
Utf8Entry name();

/**
* {@return the class name, as an internal binary name}
* {@return the represented reference type, as the {@linkplain
* ##internalname internal form} of a binary name or an array descriptor
* string} This is a shortcut for {@link #name() name().stringValue()}.
*/
String asInternalName();

/**
* {@return the class name, as a symbolic descriptor}
* {@return the represented reference type, as a symbolic descriptor} The
* returned descriptor is never {@linkplain ClassDesc#isPrimitive()
* primitive}.
*
* @see ConstantPoolBuilder#classEntry(ClassDesc)
* ConstantPoolBuilder::classEntry(ClassDesc)
*/
ClassDesc asSymbol();
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -33,30 +33,65 @@
import jdk.internal.classfile.impl.Util;

/**
* Models a {@code CONSTANT_Dynamic_info} constant in the constant pool of a
* classfile.
* @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures
* Models a {@code CONSTANT_Dynamic_info} structure, representing a <dfn>{@index
* "dynamically-computed constant"}</dfn>, in the constant pool of a {@code
* class} file.
* <p>
* The use of a {@code ConstantDynamicEntry} is modeled by a {@link
* DynamicConstantDesc}. Conversions are through {@link #asSymbol()} and {@link
* ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc)}.
* <p>
* A dynamic constant entry is composite:
* {@snippet lang=text :
* // @link substring="ConstantDynamicEntry" target="ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)" :
* ConstantDynamicEntry(
* BootstrapMethodEntry bootstrap, // @link substring="bootstrap" target="#bootstrap()"
* NameAndTypeEntry nameAndType // @link substring="nameAndType" target="#nameAndType()"
* )
* }
* where {@link #type() nameAndType.type()} is a {@linkplain #typeSymbol()
* field descriptor} string.
*
* @apiNote
* A dynamically-computed constant is frequently called a <dfn>{@index "dynamic
* constant"}</dfn>, or a <dfn>{@index "condy"}</dfn>, from the abbreviation of
* "constant dynamic".
*
* @see ConstantPoolBuilder#constantDynamicEntry
* ConstantPoolBuilder::constantDynamicEntry
* @see DynamicConstantDesc
* @see java.lang.invoke##condycon Dynamically-computed constants
* @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code
* CONSTANT_InvokeDynamic_info} Structures
* @since 24
*/
public sealed interface ConstantDynamicEntry
extends DynamicConstantPoolEntry, LoadableConstantEntry
permits AbstractPoolEntry.ConstantDynamicEntryImpl {

/**
* {@return a symbolic descriptor for the dynamic constant's type}
* {@return a symbolic descriptor for the {@linkplain #type() field type} of
* this dynamically-computed constant}
*/
default ClassDesc typeSymbol() {
return Util.fieldTypeSymbol(type());
}

/**
* {@inheritDoc}
* <p>
* This is equivalent to {@link #asSymbol() asSymbol()}.
*/
@Override
default ConstantDesc constantValue() {
return asSymbol();
}

/**
* {@return the symbolic descriptor for the {@code invokedynamic} constant}
* {@return a symbolic descriptor for this dynamically-computed constant}
*
* @see ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc)
* ConstantPoolBuilder::constantDynamicEntry(DynamicConstantDesc)
*/
default DynamicConstantDesc<?> asSymbol() {
return DynamicConstantDesc.ofNamed(bootstrap().bootstrapMethod().asSymbol(),
Expand All @@ -68,10 +103,15 @@ default DynamicConstantDesc<?> asSymbol() {
}

/**
* {@return the type of the constant}
* {@inheritDoc}
*
* @apiNote
* The data type of a dynamically-computed constant depends on its
* {@linkplain #type() descriptor}, while the data type of all other
* constants can be determined by their {@linkplain #tag() constant type}.
*/
@Override
default TypeKind typeKind() {
return TypeKind.fromDescriptor(type().stringValue());
return TypeKind.fromDescriptor(type());
}
}
Loading