Skip to content

Commit

Permalink
Improve api docs for constantpool
Browse files Browse the repository at this point in the history
  • Loading branch information
liach committed Nov 14, 2024
1 parent dbf2346 commit e3ac100
Show file tree
Hide file tree
Showing 30 changed files with 1,056 additions and 349 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 @@ -35,10 +37,27 @@

/**
* 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>
* Conceptually, a bootstrap method entry is a record:
* {@snippet lang=text :
* // @link region=1 substring="BootstrapMethodEntry" target="ConstantPoolBuilder#bsmEntry(DirectMethodHandleDesc, List)"
* // @link substring="DirectMethodHandleDesc" target="#bootstrapMethod" :
* BootstrapMethodEntry(DirectMethodHandleDesc, List<ConstantDesc>) // @link substring="List<ConstantDesc>" target="#arguments()"
* // @end region=1
* }
* <p>
* Physically, a bootstrap method entry is a record:
* {@snippet lang=text :
* // @link region=1 substring="BootstrapMethodEntry" target="ConstantPoolBuilder#bsmEntry(MethodHandleEntry, List)"
* // @link substring="MethodHandleEntry" target="#bootstrapMethod" :
* BootstrapMethodEntry(MethodHandleEntry, List<LoadableConstantEntry>) // @link substring="List<LoadableConstantEntry>" target="#arguments()"
* // @end region=1
* }
*
* @see ConstantPoolBuilder#bsmEntry ConstantPoolBuilder::bsmEntry
* @since 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
Expand All @@ -47,21 +66,38 @@ public sealed interface BootstrapMethodEntry

/**
* {@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();

/**
* {@return the bootstrap method}
*
* @apiNote
* A symbolic descriptor for the bootstrap method is available through
* {@link MethodHandleEntry#asSymbol() bootstrapMethod().asSymbol()}.
*/
MethodHandleEntry bootstrapMethod();

/**
* {@return the bootstrap arguments}
*
* @apiNote
* A symbolic descriptor for each entry in the returned list is available
* via {@link LoadableConstantEntry#constantValue
* LoadableConstantEntry::constantValue}.
*/
List<LoadableConstantEntry> arguments();
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@
import jdk.internal.javac.PreviewFeature;

/**
* 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 @@ -42,6 +41,7 @@
* in {@link AnnotationValue.OfInt}.
*
* @see AnnotationValue.OfConstant
* @jvms 4.7.16.1 The {@code element_value} structure
* @sealedGraph
* @since 22
*/
Expand All @@ -50,9 +50,9 @@ 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, Oracle and/or its affiliates. All rights reserved.
* 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
Expand Down Expand Up @@ -31,34 +31,79 @@
import jdk.internal.javac.PreviewFeature;

/**
* 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. This describes a class
* or interface with the internal form of its binary name (JVMS {@jvms 4.2.1}),
* or an array type with its descriptor string (JVMS {@jvms 4.3.2}).
* <p>
* Conceptually, a class entry is a record:
* {@snippet lang=text :
* // @link substring="ClassEntry" target="ConstantPoolBuilder#classEntry(ClassDesc)" :
* ClassEntry(ClassDesc) // @link substring="ClassDesc" target="#asSymbol()"
* }
* where the {@code ClassDesc} must not be primitive.
* <p>
* Physically, a class entry is a record:
* {@snippet lang=text :
* // @link substring="ClassEntry" target="ConstantPoolBuilder#classEntry(Utf8Entry)" :
* ClassEntry(Utf8Entry) // @link substring="Utf8Entry" target="Utf8Entry"
* }
* where the {@code Utf8Entry} is a valid internal form of binary name or array
* type descriptor string.
*
* @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 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
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 class entry} 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 ##internal-name 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
* ##internal-name internal form} of a binary name or an array descriptor
* string} The return value is equivalent to {@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, Oracle and/or its affiliates. All rights reserved.
* 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
Expand Down Expand Up @@ -34,10 +34,37 @@
import jdk.internal.javac.PreviewFeature;

/**
* 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>
* Conceptually, a constant dynamic entry is a record:
* {@snippet lang=text :
* // @link substring="ConstantDynamicEntry" target="ConstantPoolBuilder#constantDynamicEntry(DynamicConstantDesc)" :
* ConstantDynamicEntry(DynamicConstantDesc) // @link substring="DynamicConstantDesc" target="#asSymbol()"
* }
* <p>
* Physically, a constant dynamic entry is a record:
* {@snippet lang=text :
* // @link region substring="ConstantDynamicEntry" target="ConstantPoolBuilder#constantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry)"
* // @link substring="BootstrapMethodEntry" target="#bootstrap()"
* ConstantDynamicEntry(BootstrapMethodEntry, NameAndTypeEntry) // @link substring="NameAndTypeEntry" target="#nameAndType()"
* // @end
* }
* where the type in the {@code NameAndTypeEntry} 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 22
*/
@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
Expand All @@ -46,19 +73,28 @@ public sealed interface ConstantDynamicEntry
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 @@ -70,10 +106,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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,24 @@

import java.lang.classfile.BootstrapMethodEntry;
import java.lang.classfile.ClassReader;
import java.lang.classfile.attribute.BootstrapMethodsAttribute;
import java.util.Iterator;
import java.util.NoSuchElementException;

import jdk.internal.javac.PreviewFeature;

/**
* Provides read access to the constant pool and bootstrap method table of a
* classfile.
* @jvms 4.4 The Constant Pool
* Provides read access to the constant pool and the bootstrap method table of a
* {@code class} file.
*
* <h2 id="index">Index in the Constant Pool</h2>
* The constant pool entries are accessed by index. A valid index is in the
* range of {@link #size() [1, size())}. It is {@linkplain PoolEntry#width()
* unusable} if a {@link LongEntry} or {@link DoubleEntry} is at its previous
* index.
*
* @see BootstrapMethodsAttribute
* @jvms 4.4 The Constant Pool
* @sealedGraph
* @since 22
*/
Expand All @@ -58,7 +66,11 @@ public sealed interface ConstantPool extends Iterable<PoolEntry>
PoolEntry entryByIndex(int index);

/**
* {@return the size of the constant pool}
* {@return the exclusive upper bound of the valid indices of this constant
* pool} The actual number of entries is lower because {@code 0}, {@code
* size()} are not valid, and a valid index may be unusable.
*
* @see ##index Index in the Constant Pool
*/
int size();

Expand All @@ -69,13 +81,18 @@ public sealed interface ConstantPool extends Iterable<PoolEntry>
* @param index the index within the pool of the desired entry
* @param cls the entry type
* @throws ConstantPoolException if the index is out of range of the
* constant pool, or the entry is not of the given type
* constant pool or considered unusable, or the entry is not
* of the given type
* @since 23
*/
<T extends PoolEntry> T entryByIndex(int index, Class<T> cls);

/**
* {@return an iterator over pool entries}
*
* @apiNote
* This skips any unusable index and is less error-prone than iterating by
* raw index.
*/
@Override
default Iterator<PoolEntry> iterator() {
Expand All @@ -97,7 +114,6 @@ public PoolEntry next() {
};
}


/**
* {@return the {@link BootstrapMethodEntry} at the specified index within
* the bootstrap method table}
Expand Down
Loading

0 comments on commit e3ac100

Please sign in to comment.