1 /* 2 * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 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.CallSite; 29 import java.lang.invoke.ConstantBootstraps; 30 import java.lang.invoke.MethodHandle; 31 import java.lang.invoke.MethodHandles; 32 import java.lang.invoke.MethodHandles.Lookup; 33 import java.lang.invoke.MethodType; 34 import java.lang.invoke.VarHandle; 35 import java.lang.invoke.VarHandle.VarHandleDesc; 36 import java.util.Collection; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Set; 40 41 import static java.lang.constant.DirectMethodHandleDesc.*; 42 import static java.lang.constant.DirectMethodHandleDesc.Kind.STATIC; 43 44 /** 45 * Predefined values of <a href="package-summary.html#nominal">nominal descriptor</a> 46 * for common constants, including descriptors for primitive class types and 47 * other common platform types, and descriptors for method handles for standard 48 * bootstrap methods. 49 * 50 * @see ConstantDesc 51 * 52 * @since 12 53 */ 54 public final class ConstantDescs { 55 // No instances 56 private ConstantDescs() { } 57 58 /** Invocation name to use when no name is needed, such as the name of a 59 * constructor, or the invocation name of a dynamic constant or dynamic 60 * callsite when the bootstrap is known to ignore the invocation name. 61 */ 62 public static final String DEFAULT_NAME = "_"; 63 64 // Don't change the order of these declarations! 65 66 /** {@link ClassDesc} representing {@link Object} */ 67 public static final ClassDesc CD_Object = ClassDesc.of("java.lang.Object"); 68 69 /** {@link ClassDesc} representing {@link String} */ 70 public static final ClassDesc CD_String = ClassDesc.of("java.lang.String"); 71 72 /** {@link ClassDesc} representing {@link Class} */ 73 public static final ClassDesc CD_Class = ClassDesc.of("java.lang.Class"); 74 75 /** {@link ClassDesc} representing {@link Number} */ 76 public static final ClassDesc CD_Number = ClassDesc.of("java.lang.Number"); 77 78 /** {@link ClassDesc} representing {@link Integer} */ 79 public static final ClassDesc CD_Integer = ClassDesc.of("java.lang.Integer"); 80 81 /** {@link ClassDesc} representing {@link Long} */ 82 public static final ClassDesc CD_Long = ClassDesc.of("java.lang.Long"); 83 84 /** {@link ClassDesc} representing {@link Float} */ 85 public static final ClassDesc CD_Float = ClassDesc.of("java.lang.Float"); 86 87 /** {@link ClassDesc} representing {@link Double} */ 88 public static final ClassDesc CD_Double = ClassDesc.of("java.lang.Double"); 89 90 /** {@link ClassDesc} representing {@link Short} */ 91 public static final ClassDesc CD_Short = ClassDesc.of("java.lang.Short"); 92 93 /** {@link ClassDesc} representing {@link Byte} */ 94 public static final ClassDesc CD_Byte = ClassDesc.of("java.lang.Byte"); 95 96 /** {@link ClassDesc} representing {@link Character} */ 97 public static final ClassDesc CD_Character = ClassDesc.of("java.lang.Character"); 98 99 /** {@link ClassDesc} representing {@link Boolean} */ 100 public static final ClassDesc CD_Boolean = ClassDesc.of("java.lang.Boolean"); 101 102 /** {@link ClassDesc} representing {@link Void} */ 103 public static final ClassDesc CD_Void = ClassDesc.of("java.lang.Void"); 104 105 /** {@link ClassDesc} representing {@link Throwable} */ 106 public static final ClassDesc CD_Throwable = ClassDesc.of("java.lang.Throwable"); 107 108 /** {@link ClassDesc} representing {@link Exception} */ 109 public static final ClassDesc CD_Exception = ClassDesc.of("java.lang.Exception"); 110 111 /** {@link ClassDesc} representing {@link Enum} */ 112 public static final ClassDesc CD_Enum = ClassDesc.of("java.lang.Enum"); 113 114 /** {@link ClassDesc} representing {@link VarHandle} */ 115 public static final ClassDesc CD_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle"); 116 117 /** {@link ClassDesc} representing {@link MethodHandles} */ 118 public static final ClassDesc CD_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles"); 119 120 /** {@link ClassDesc} representing {@link MethodHandles.Lookup} */ 121 public static final ClassDesc CD_MethodHandles_Lookup = CD_MethodHandles.nested("Lookup"); 122 123 /** {@link ClassDesc} representing {@link MethodHandle} */ 124 public static final ClassDesc CD_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle"); 125 126 /** {@link ClassDesc} representing {@link MethodType} */ 127 public static final ClassDesc CD_MethodType = ClassDesc.of("java.lang.invoke.MethodType"); 128 129 /** {@link ClassDesc} representing {@link CallSite} */ 130 public static final ClassDesc CD_CallSite = ClassDesc.of("java.lang.invoke.CallSite"); 131 132 /** {@link ClassDesc} representing {@link Collection} */ 133 public static final ClassDesc CD_Collection = ClassDesc.of("java.util.Collection"); 134 135 /** {@link ClassDesc} representing {@link List} */ 136 public static final ClassDesc CD_List = ClassDesc.of("java.util.List"); 137 138 /** {@link ClassDesc} representing {@link Set} */ 139 public static final ClassDesc CD_Set = ClassDesc.of("java.util.Set"); 140 141 /** {@link ClassDesc} representing {@link Map} */ 142 public static final ClassDesc CD_Map = ClassDesc.of("java.util.Map"); 143 144 /** {@link ClassDesc} representing {@link ConstantDesc} */ 145 public static final ClassDesc CD_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc"); 146 147 /** {@link ClassDesc} representing {@link ClassDesc} */ 148 public static final ClassDesc CD_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc"); 149 150 /** {@link ClassDesc} representing {@link EnumDesc} */ 151 public static final ClassDesc CD_EnumDesc = CD_Enum.nested("EnumDesc"); 152 153 /** {@link ClassDesc} representing {@link MethodTypeDesc} */ 154 public static final ClassDesc CD_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc"); 155 156 /** {@link ClassDesc} representing {@link MethodHandleDesc} */ 157 public static final ClassDesc CD_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc"); 158 159 /** {@link ClassDesc} representing {@link DirectMethodHandleDesc} */ 160 public static final ClassDesc CD_DirectMethodHandleDesc = ClassDesc.of("java.lang.constant.DirectMethodHandleDesc"); 161 162 /** {@link ClassDesc} representing {@link VarHandleDesc} */ 163 public static final ClassDesc CD_VarHandleDesc = CD_VarHandle.nested("VarHandleDesc"); 164 165 /** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */ 166 public static final ClassDesc CD_MethodHandleDesc_Kind = CD_DirectMethodHandleDesc.nested("Kind"); 167 168 /** {@link ClassDesc} representing {@link DynamicConstantDesc} */ 169 public static final ClassDesc CD_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc"); 170 171 /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */ 172 public static final ClassDesc CD_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc"); 173 174 /** {@link ClassDesc} representing {@link ConstantBootstraps} */ 175 public static final ClassDesc CD_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps"); 176 177 private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = { 178 ConstantDescs.CD_MethodHandles_Lookup, 179 ConstantDescs.CD_String, 180 ConstantDescs.CD_MethodType}; 181 182 private static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = { 183 ConstantDescs.CD_MethodHandles_Lookup, 184 ConstantDescs.CD_String, 185 ConstantDescs.CD_Class}; 186 187 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class) ConstantBootstraps.primitiveClass} */ 188 public static final DirectMethodHandleDesc BSM_PRIMITIVE_CLASS 189 = ofConstantBootstrap(CD_ConstantBootstraps, "primitiveClass", 190 CD_Class); 191 192 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#enumConstant(Lookup, String, Class) ConstantBootstraps.enumConstant} */ 193 public static final DirectMethodHandleDesc BSM_ENUM_CONSTANT 194 = ofConstantBootstrap(CD_ConstantBootstraps, "enumConstant", 195 CD_Enum); 196 197 /** 198 * {@link MethodHandleDesc} representing {@link ConstantBootstraps#getStaticFinal(Lookup, String, Class, Class) ConstantBootstraps.getStaticFinal} 199 * @since 15 200 */ 201 public static final DirectMethodHandleDesc BSM_GET_STATIC_FINAL 202 = ofConstantBootstrap(CD_ConstantBootstraps, "getStaticFinal", 203 CD_Object, CD_Class); 204 205 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class) ConstantBootstraps.nullConstant} */ 206 public static final DirectMethodHandleDesc BSM_NULL_CONSTANT 207 = ofConstantBootstrap(CD_ConstantBootstraps, "nullConstant", 208 CD_Object); 209 210 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.fieldVarHandle} */ 211 public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD 212 = ofConstantBootstrap(CD_ConstantBootstraps, "fieldVarHandle", 213 CD_VarHandle, CD_Class, CD_Class); 214 215 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.staticFieldVarHandle} */ 216 public static final DirectMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD 217 = ofConstantBootstrap(CD_ConstantBootstraps, "staticFieldVarHandle", 218 CD_VarHandle, CD_Class, CD_Class); 219 220 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class) ConstantBootstraps.arrayVarHandle} */ 221 public static final DirectMethodHandleDesc BSM_VARHANDLE_ARRAY 222 = ofConstantBootstrap(CD_ConstantBootstraps, "arrayVarHandle", 223 CD_VarHandle, CD_Class); 224 225 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...) ConstantBootstraps.invoke} */ 226 public static final DirectMethodHandleDesc BSM_INVOKE 227 = ofConstantBootstrap(CD_ConstantBootstraps, "invoke", 228 CD_Object, CD_MethodHandle, CD_Object.arrayType()); 229 230 /** 231 * {@link MethodHandleDesc} representing {@link ConstantBootstraps#explicitCast(Lookup, String, Class, Object) ConstantBootstraps.explicitCast} 232 * @since 15 233 */ 234 public static final DirectMethodHandleDesc BSM_EXPLICIT_CAST 235 = ofConstantBootstrap(CD_ConstantBootstraps, "explicitCast", 236 CD_Object, CD_Object); 237 238 /** {@link ClassDesc} representing the primitive type {@code int} */ 239 public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I"); 240 241 /** {@link ClassDesc} representing the primitive type {@code long} */ 242 public static final ClassDesc CD_long = ClassDesc.ofDescriptor("J"); 243 244 /** {@link ClassDesc} representing the primitive type {@code float} */ 245 public static final ClassDesc CD_float = ClassDesc.ofDescriptor("F"); 246 247 /** {@link ClassDesc} representing the primitive type {@code double} */ 248 public static final ClassDesc CD_double = ClassDesc.ofDescriptor("D"); 249 250 /** {@link ClassDesc} representing the primitive type {@code short} */ 251 public static final ClassDesc CD_short = ClassDesc.ofDescriptor("S"); 252 253 /** {@link ClassDesc} representing the primitive type {@code byte} */ 254 public static final ClassDesc CD_byte = ClassDesc.ofDescriptor("B"); 255 256 /** {@link ClassDesc} representing the primitive type {@code char} */ 257 public static final ClassDesc CD_char = ClassDesc.ofDescriptor("C"); 258 259 /** {@link ClassDesc} representing the primitive type {@code boolean} */ 260 public static final ClassDesc CD_boolean = ClassDesc.ofDescriptor("Z"); 261 262 /** {@link ClassDesc} representing the primitive type {@code void} */ 263 public static final ClassDesc CD_void = ClassDesc.ofDescriptor("V"); 264 265 /** 266 * {@link MethodHandleDesc} representing {@link MethodHandles#classData(Lookup, String, Class) MethodHandles.classData} 267 * @since 21 268 */ 269 public static final DirectMethodHandleDesc BSM_CLASS_DATA 270 = ofConstantBootstrap(CD_MethodHandles, "classData", 271 CD_Object); 272 273 /** 274 * {@link MethodHandleDesc} representing {@link MethodHandles#classDataAt(Lookup, String, Class, int) MethodHandles.classDataAt} 275 * @since 21 276 */ 277 public static final DirectMethodHandleDesc BSM_CLASS_DATA_AT 278 = ofConstantBootstrap(CD_MethodHandles, "classDataAt", 279 CD_Object, CD_int); 280 281 /** Nominal descriptor representing the constant {@code null} */ 282 public static final ConstantDesc NULL 283 = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT, 284 DEFAULT_NAME, ConstantDescs.CD_Object); 285 286 /** 287 * Nominal descriptor representing the constant {@linkplain Boolean#TRUE} 288 * @since 15 289 */ 290 public static final DynamicConstantDesc<Boolean> TRUE 291 = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL, 292 "TRUE", CD_Boolean, CD_Boolean); 293 294 /** 295 * Nominal descriptor representing the constant {@linkplain Boolean#FALSE} 296 * @since 15 297 */ 298 public static final DynamicConstantDesc<Boolean> FALSE 299 = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL, 300 "FALSE", CD_Boolean, CD_Boolean); 301 302 /** 303 * The special name of instance initialization methods, {@value}. An instance 304 * initialization method has this special name and is {@code void}. 305 * 306 * @jvms 2.9.1 Instance Initialization Methods 307 * @since 21 308 */ 309 public static final String INIT_NAME = "<init>"; 310 311 /** 312 * The special name of class initialization methods, {@value}. A class 313 * initialization method has this special name, {@link java.lang.reflect.AccessFlag#STATIC 314 * ACC_STATIC} flag set, is {@link #MTD_void void} and takes no arguments. 315 * 316 * @jvms 2.9.2 Class Initialization Methods 317 * @since 21 318 */ 319 public static final String CLASS_INIT_NAME = "<clinit>"; 320 321 /** 322 * Nominal descriptor representing the method descriptor {@code ()V}, 323 * taking no argument and returning {@code void}. 324 * 325 * @since 21 326 */ 327 public static final MethodTypeDesc MTD_void = MethodTypeDesc.of(CD_void); 328 329 static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE 330 = MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType", 331 MethodTypeDesc.of(CD_MethodHandle, CD_MethodType)); 332 /** 333 * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for 334 * an {@code invokedynamic} callsite, which is a static method whose leading 335 * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}. 336 * 337 * @param owner the class declaring the method 338 * @param name the unqualified name of the method 339 * @param returnType the return type of the method 340 * @param paramTypes the types of the static bootstrap arguments, if any 341 * @return the {@link MethodHandleDesc} 342 * @throws NullPointerException if any of the arguments are null 343 * @jvms 4.2.2 Unqualified Names 344 */ 345 public static DirectMethodHandleDesc ofCallsiteBootstrap(ClassDesc owner, 346 String name, 347 ClassDesc returnType, 348 ClassDesc... paramTypes) { 349 return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes) 350 .insertParameterTypes(0, INDY_BOOTSTRAP_ARGS)); 351 } 352 353 /** 354 * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for a 355 * dynamic constant, which is a static method whose leading arguments are 356 * {@code Lookup}, {@code String}, and {@code Class}. 357 * 358 * @param owner the class declaring the method 359 * @param name the unqualified name of the method 360 * @param returnType the return type of the method 361 * @param paramTypes the types of the static bootstrap arguments, if any 362 * @return the {@link MethodHandleDesc} 363 * @throws NullPointerException if any of the arguments are null 364 * @jvms 4.2.2 Unqualified Names 365 */ 366 public static DirectMethodHandleDesc ofConstantBootstrap(ClassDesc owner, 367 String name, 368 ClassDesc returnType, 369 ClassDesc... paramTypes) { 370 return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes) 371 .insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS)); 372 } 373 }