< prev index next >

src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java

Print this page




  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang.constant;
  26 
  27 import java.lang.Enum.EnumDesc;
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.VarHandle;
  31 import java.lang.invoke.VarHandle.VarHandleDesc;
  32 import java.util.Arrays;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Objects;

  36 import java.util.function.Function;
  37 import java.util.stream.Stream;
  38 


  39 import static java.lang.constant.ConstantDescs.CD_Class;
  40 import static java.lang.constant.ConstantDescs.CD_VarHandle;
  41 import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
  42 import static java.lang.constant.ConstantUtils.EMPTY_CONSTANTDESC;
  43 import static java.lang.constant.ConstantUtils.validateMemberName;
  44 import static java.util.Objects.requireNonNull;
  45 import static java.util.stream.Collectors.joining;
  46 
  47 /**
  48  * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
  49  * dynamic constant (one described in the constant pool with
  50  * {@code Constant_Dynamic_info}.)
  51  *
  52  * <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be
  53  * <a href="../doc-files/ValueBased.html">value-based</a>.
  54  *
  55  * @param <T> the type of the dynamic constant
  56  *
  57  * @since 12
  58  */
  59 public abstract class DynamicConstantDesc<T>
  60         implements ConstantDesc {
  61 
  62     private final DirectMethodHandleDesc bootstrapMethod;
  63     private final ConstantDesc[] bootstrapArgs;
  64     private final String constantName;
  65     private final ClassDesc constantType;
  66 
  67     private static final Map<MethodHandleDesc, Function<DynamicConstantDesc<?>, ConstantDesc>> canonicalMap
  68             = Map.ofEntries(Map.entry(ConstantDescs.BSM_PRIMITIVE_CLASS, DynamicConstantDesc::canonicalizePrimitiveClass),
  69                             Map.entry(ConstantDescs.BSM_ENUM_CONSTANT, DynamicConstantDesc::canonicalizeEnum),
  70                             Map.entry(ConstantDescs.BSM_NULL_CONSTANT, DynamicConstantDesc::canonicalizeNull),
  71                             Map.entry(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, DynamicConstantDesc::canonicalizeStaticFieldVarHandle),
  72                             Map.entry(ConstantDescs.BSM_VARHANDLE_FIELD, DynamicConstantDesc::canonicalizeFieldVarHandle),
  73                             Map.entry(ConstantDescs.BSM_VARHANDLE_ARRAY, DynamicConstantDesc::canonicalizeArrayVarHandle)
  74     );
  75 
  76     /**
  77      * Creates a nominal descriptor for a dynamic constant.
  78      *
  79      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
  80      *                        bootstrap method for the constant


 120      * because this may result in a more specific type that can be provided to
 121      * callers.
 122      *
 123      * @param <T> the type of the dynamic constant
 124      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 125      *                        bootstrap method for the constant
 126      * @param constantName The unqualified name that would appear in the {@code NameAndType}
 127      *                     operand of the {@code LDC} for this constant
 128      * @param constantType a {@link ClassDesc} describing the type
 129      *                     that would appear in the {@code NameAndType} operand
 130      *                     of the {@code LDC} for this constant
 131      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 132      *                      to the bootstrap, that would appear in the
 133      *                      {@code BootstrapMethods} attribute
 134      * @return the nominal descriptor
 135      * @throws NullPointerException if any argument is null
 136      * @throws IllegalArgumentException if the {@code name} has the incorrect
 137      * format
 138      * @jvms 4.2.2 Unqualified Names
 139      */

 140     public static<T> ConstantDesc ofCanonical(DirectMethodHandleDesc bootstrapMethod,
 141                                               String constantName,
 142                                               ClassDesc constantType,
 143                                               ConstantDesc[] bootstrapArgs) {
 144         return DynamicConstantDesc.<T>ofNamed(bootstrapMethod, constantName, constantType, bootstrapArgs)
 145                 .tryCanonicalize();
 146     }
 147 
 148     /**
 149      * Returns a nominal descriptor for a dynamic constant.
 150      *
 151      * @param <T> the type of the dynamic constant
 152      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 153      *                        bootstrap method for the constant
 154      * @param constantName The unqualified name that would appear in the {@code NameAndType}
 155      *                     operand of the {@code LDC} for this constant
 156      * @param constantType a {@link ClassDesc} describing the type
 157      *                     that would appear in the {@code NameAndType} operand
 158      *                     of the {@code LDC} for this constant
 159      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 160      *                      to the bootstrap, that would appear in the
 161      *                      {@code BootstrapMethods} attribute
 162      * @return the nominal descriptor
 163      * @throws NullPointerException if any argument is null
 164      * @throws IllegalArgumentException if the {@code name} has the incorrect
 165      * format
 166      * @jvms 4.2.2 Unqualified Names
 167      */
 168 
 169     public static<T> DynamicConstantDesc<T> ofNamed(DirectMethodHandleDesc bootstrapMethod,
 170                                                     String constantName,
 171                                                     ClassDesc constantType,
 172                                                     ConstantDesc... bootstrapArgs) {
 173         return new AnonymousDynamicConstantDesc<>(bootstrapMethod, constantName, constantType, bootstrapArgs);
 174     }
 175 
 176     /**
 177      * Returns a nominal descriptor for a dynamic constant whose name parameter
 178      * is {@link ConstantDescs#DEFAULT_NAME}, and whose type parameter is always
 179      * the same as the bootstrap method return type.
 180      *
 181      * @param <T> the type of the dynamic constant
 182      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 183      *                        bootstrap method for the constant
 184      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 185      *                      to the bootstrap, that would appear in the
 186      *                      {@code BootstrapMethods} attribute
 187      * @return the nominal descriptor
 188      * @throws NullPointerException if any argument is null
 189      * @jvms 4.2.2 Unqualified Names
 190      */

 191     public static<T> DynamicConstantDesc<T> of(DirectMethodHandleDesc bootstrapMethod,
 192                                                ConstantDesc... bootstrapArgs) {
 193         return ofNamed(bootstrapMethod, DEFAULT_NAME, bootstrapMethod.invocationType().returnType(), bootstrapArgs);
 194     }
 195 
 196     /**
 197      * Returns a nominal descriptor for a dynamic constant whose bootstrap has
 198      * no static arguments, whose name parameter is {@link ConstantDescs#DEFAULT_NAME},
 199      * and whose type parameter is always the same as the bootstrap method return type.
 200      *
 201      * @param <T> the type of the dynamic constant
 202      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 203      *                        bootstrap method for the constant
 204      * @return the nominal descriptor
 205      * @throws NullPointerException if any argument is null
 206      */

 207     public static<T> DynamicConstantDesc<T> of(DirectMethodHandleDesc bootstrapMethod) {
 208         return of(bootstrapMethod, EMPTY_CONSTANTDESC);
 209     }
 210 
 211     /**
 212      * Returns the name that would appear in the {@code NameAndType} operand
 213      * of the {@code LDC} for this constant.
 214      *
 215      * @return the constant name
 216      */

 217     public String constantName() {
 218         return constantName;
 219     }
 220 
 221     /**
 222      * Returns a {@link ClassDesc} describing the type that would appear in the
 223      * {@code NameAndType} operand of the {@code LDC} for this constant.
 224      *
 225      * @return the constant type
 226      */

 227     public ClassDesc constantType() {
 228         return constantType;
 229     }
 230 
 231     /**
 232      * Returns a {@link MethodHandleDesc} describing the bootstrap method for
 233      * this constant.
 234      *
 235      * @return the bootstrap method
 236      */

 237     public DirectMethodHandleDesc bootstrapMethod() {
 238         return bootstrapMethod;
 239     }
 240 
 241     /**
 242      * Returns the bootstrap arguments for this constant.
 243      *
 244      * @return the bootstrap arguments
 245      */
 246     public ConstantDesc[] bootstrapArgs() {
 247         return bootstrapArgs.clone();
 248     }
 249 
 250     /**
 251      * Returns the bootstrap arguments for this constant as an immutable {@link List}.
 252      *
 253      * @return a {@link List} of the bootstrap arguments
 254      */
 255     public List<ConstantDesc> bootstrapArgsList() {
 256         return List.of(bootstrapArgs);


 375     /**
 376      * Returns a compact textual description of this constant description,
 377      * including the bootstrap method, the constant name and type, and
 378      * the static bootstrap arguments.
 379      *
 380      * @return A compact textual description of this call site descriptor
 381      */
 382     @Override
 383     public String toString() {
 384         return String.format("DynamicConstantDesc[%s::%s(%s%s)%s]",
 385                              bootstrapMethod.owner().displayName(),
 386                              bootstrapMethod.methodName(),
 387                              constantName.equals(ConstantDescs.DEFAULT_NAME) ? "" : constantName + "/",
 388                              Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
 389                              constantType.displayName());
 390     }
 391 
 392     private static class AnonymousDynamicConstantDesc<T> extends DynamicConstantDesc<T> {
 393         AnonymousDynamicConstantDesc(DirectMethodHandleDesc bootstrapMethod, String constantName, ClassDesc constantType, ConstantDesc... bootstrapArgs) {
 394             super(bootstrapMethod, constantName, constantType, bootstrapArgs);





 395         }
 396     }
 397 }


  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.lang.constant;
  26 
  27 import java.lang.Enum.EnumDesc;
  28 import java.lang.invoke.MethodHandle;
  29 import java.lang.invoke.MethodHandles;
  30 import java.lang.invoke.VarHandle;
  31 import java.lang.invoke.VarHandle.VarHandleDesc;
  32 import java.util.Arrays;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.Objects;
  36 import java.util.Optional;
  37 import java.util.function.Function;
  38 import java.util.stream.Stream;
  39 
  40 import jdk.internal.lang.annotation.Foldable;
  41 
  42 import static java.lang.constant.ConstantDescs.CD_Class;
  43 import static java.lang.constant.ConstantDescs.CD_VarHandle;
  44 import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
  45 import static java.lang.constant.ConstantUtils.EMPTY_CONSTANTDESC;
  46 import static java.lang.constant.ConstantUtils.validateMemberName;
  47 import static java.util.Objects.requireNonNull;
  48 import static java.util.stream.Collectors.joining;
  49 
  50 /**
  51  * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
  52  * dynamic constant (one described in the constant pool with
  53  * {@code Constant_Dynamic_info}.)
  54  *
  55  * <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be
  56  * <a href="../doc-files/ValueBased.html">value-based</a>.
  57  *
  58  * @param <T> the type of the dynamic constant
  59  *
  60  * @since 12
  61  */
  62 public abstract class DynamicConstantDesc<T>
  63         implements ConstantDesc, Constable {
  64 
  65     private final DirectMethodHandleDesc bootstrapMethod;
  66     private final ConstantDesc[] bootstrapArgs;
  67     private final String constantName;
  68     private final ClassDesc constantType;
  69 
  70     private static final Map<MethodHandleDesc, Function<DynamicConstantDesc<?>, ConstantDesc>> canonicalMap
  71             = Map.ofEntries(Map.entry(ConstantDescs.BSM_PRIMITIVE_CLASS, DynamicConstantDesc::canonicalizePrimitiveClass),
  72                             Map.entry(ConstantDescs.BSM_ENUM_CONSTANT, DynamicConstantDesc::canonicalizeEnum),
  73                             Map.entry(ConstantDescs.BSM_NULL_CONSTANT, DynamicConstantDesc::canonicalizeNull),
  74                             Map.entry(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, DynamicConstantDesc::canonicalizeStaticFieldVarHandle),
  75                             Map.entry(ConstantDescs.BSM_VARHANDLE_FIELD, DynamicConstantDesc::canonicalizeFieldVarHandle),
  76                             Map.entry(ConstantDescs.BSM_VARHANDLE_ARRAY, DynamicConstantDesc::canonicalizeArrayVarHandle)
  77     );
  78 
  79     /**
  80      * Creates a nominal descriptor for a dynamic constant.
  81      *
  82      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
  83      *                        bootstrap method for the constant


 123      * because this may result in a more specific type that can be provided to
 124      * callers.
 125      *
 126      * @param <T> the type of the dynamic constant
 127      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 128      *                        bootstrap method for the constant
 129      * @param constantName The unqualified name that would appear in the {@code NameAndType}
 130      *                     operand of the {@code LDC} for this constant
 131      * @param constantType a {@link ClassDesc} describing the type
 132      *                     that would appear in the {@code NameAndType} operand
 133      *                     of the {@code LDC} for this constant
 134      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 135      *                      to the bootstrap, that would appear in the
 136      *                      {@code BootstrapMethods} attribute
 137      * @return the nominal descriptor
 138      * @throws NullPointerException if any argument is null
 139      * @throws IllegalArgumentException if the {@code name} has the incorrect
 140      * format
 141      * @jvms 4.2.2 Unqualified Names
 142      */
 143     @Foldable
 144     public static<T> ConstantDesc ofCanonical(DirectMethodHandleDesc bootstrapMethod,
 145                                               String constantName,
 146                                               ClassDesc constantType,
 147                                               ConstantDesc[] bootstrapArgs) {
 148         return DynamicConstantDesc.<T>ofNamed(bootstrapMethod, constantName, constantType, bootstrapArgs)
 149                 .tryCanonicalize();
 150     }
 151 
 152     /**
 153      * Returns a nominal descriptor for a dynamic constant.
 154      *
 155      * @param <T> the type of the dynamic constant
 156      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 157      *                        bootstrap method for the constant
 158      * @param constantName The unqualified name that would appear in the {@code NameAndType}
 159      *                     operand of the {@code LDC} for this constant
 160      * @param constantType a {@link ClassDesc} describing the type
 161      *                     that would appear in the {@code NameAndType} operand
 162      *                     of the {@code LDC} for this constant
 163      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 164      *                      to the bootstrap, that would appear in the
 165      *                      {@code BootstrapMethods} attribute
 166      * @return the nominal descriptor
 167      * @throws NullPointerException if any argument is null
 168      * @throws IllegalArgumentException if the {@code name} has the incorrect
 169      * format
 170      * @jvms 4.2.2 Unqualified Names
 171      */
 172     @Foldable
 173     public static<T> DynamicConstantDesc<T> ofNamed(DirectMethodHandleDesc bootstrapMethod,
 174                                                     String constantName,
 175                                                     ClassDesc constantType,
 176                                                     ConstantDesc... bootstrapArgs) {
 177         return new AnonymousDynamicConstantDesc<>(bootstrapMethod, constantName, constantType, bootstrapArgs);
 178     }
 179 
 180     /**
 181      * Returns a nominal descriptor for a dynamic constant whose name parameter
 182      * is {@link ConstantDescs#DEFAULT_NAME}, and whose type parameter is always
 183      * the same as the bootstrap method return type.
 184      *
 185      * @param <T> the type of the dynamic constant
 186      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 187      *                        bootstrap method for the constant
 188      * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
 189      *                      to the bootstrap, that would appear in the
 190      *                      {@code BootstrapMethods} attribute
 191      * @return the nominal descriptor
 192      * @throws NullPointerException if any argument is null
 193      * @jvms 4.2.2 Unqualified Names
 194      */
 195     @Foldable
 196     public static<T> DynamicConstantDesc<T> of(DirectMethodHandleDesc bootstrapMethod,
 197                                                ConstantDesc... bootstrapArgs) {
 198         return ofNamed(bootstrapMethod, DEFAULT_NAME, bootstrapMethod.invocationType().returnType(), bootstrapArgs);
 199     }
 200 
 201     /**
 202      * Returns a nominal descriptor for a dynamic constant whose bootstrap has
 203      * no static arguments, whose name parameter is {@link ConstantDescs#DEFAULT_NAME},
 204      * and whose type parameter is always the same as the bootstrap method return type.
 205      *
 206      * @param <T> the type of the dynamic constant
 207      * @param bootstrapMethod a {@link DirectMethodHandleDesc} describing the
 208      *                        bootstrap method for the constant
 209      * @return the nominal descriptor
 210      * @throws NullPointerException if any argument is null
 211      */
 212     @Foldable
 213     public static<T> DynamicConstantDesc<T> of(DirectMethodHandleDesc bootstrapMethod) {
 214         return of(bootstrapMethod, EMPTY_CONSTANTDESC);
 215     }
 216 
 217     /**
 218      * Returns the name that would appear in the {@code NameAndType} operand
 219      * of the {@code LDC} for this constant.
 220      *
 221      * @return the constant name
 222      */
 223     @Foldable
 224     public String constantName() {
 225         return constantName;
 226     }
 227 
 228     /**
 229      * Returns a {@link ClassDesc} describing the type that would appear in the
 230      * {@code NameAndType} operand of the {@code LDC} for this constant.
 231      *
 232      * @return the constant type
 233      */
 234     @Foldable
 235     public ClassDesc constantType() {
 236         return constantType;
 237     }
 238 
 239     /**
 240      * Returns a {@link MethodHandleDesc} describing the bootstrap method for
 241      * this constant.
 242      *
 243      * @return the bootstrap method
 244      */
 245     @Foldable
 246     public DirectMethodHandleDesc bootstrapMethod() {
 247         return bootstrapMethod;
 248     }
 249 
 250     /**
 251      * Returns the bootstrap arguments for this constant.
 252      *
 253      * @return the bootstrap arguments
 254      */
 255     public ConstantDesc[] bootstrapArgs() {
 256         return bootstrapArgs.clone();
 257     }
 258 
 259     /**
 260      * Returns the bootstrap arguments for this constant as an immutable {@link List}.
 261      *
 262      * @return a {@link List} of the bootstrap arguments
 263      */
 264     public List<ConstantDesc> bootstrapArgsList() {
 265         return List.of(bootstrapArgs);


 384     /**
 385      * Returns a compact textual description of this constant description,
 386      * including the bootstrap method, the constant name and type, and
 387      * the static bootstrap arguments.
 388      *
 389      * @return A compact textual description of this call site descriptor
 390      */
 391     @Override
 392     public String toString() {
 393         return String.format("DynamicConstantDesc[%s::%s(%s%s)%s]",
 394                              bootstrapMethod.owner().displayName(),
 395                              bootstrapMethod.methodName(),
 396                              constantName.equals(ConstantDescs.DEFAULT_NAME) ? "" : constantName + "/",
 397                              Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
 398                              constantType.displayName());
 399     }
 400 
 401     private static class AnonymousDynamicConstantDesc<T> extends DynamicConstantDesc<T> {
 402         AnonymousDynamicConstantDesc(DirectMethodHandleDesc bootstrapMethod, String constantName, ClassDesc constantType, ConstantDesc... bootstrapArgs) {
 403             super(bootstrapMethod, constantName, constantType, bootstrapArgs);
 404         }
 405 
 406         @Override
 407         public Optional<? extends ConstantDesc> describeConstable() {
 408             return Optional.empty();
 409         }
 410     }
 411 }
< prev index next >