1 /* 2 * Copyright (c) 2018, 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.Kind.STATIC; 42 43 /** 44 * Predefined values of <a href="package-summary.html#nominal">nominal descriptor</a> 45 * for common constants, including descriptors for primitive class types and 46 * other common platform types, and descriptors for method handles for standard 47 * bootstrap methods. 48 * 49 * @see ConstantDesc 50 */ 51 public final class ConstantDescs { 52 // No instances 53 private ConstantDescs() { } 54 55 /** Invocation name to use when no name is needed, such as the name of a 56 * constructor, or the invocation name of a dynamic constant or dynamic 57 * callsite when the bootstrap is known to ignore the invocation name. 58 */ 59 public static final String DEFAULT_NAME = "_"; 60 61 // Don't change the order of these declarations! 62 63 /** {@link ClassDesc} representing {@link Object} */ 64 public static final ClassDesc CR_Object = ClassDesc.of("java.lang.Object"); 65 66 /** {@link ClassDesc} representing {@link String} */ 67 public static final ClassDesc CR_String = ClassDesc.of("java.lang.String"); 68 69 /** {@link ClassDesc} representing {@link Class} */ 70 public static final ClassDesc CR_Class = ClassDesc.of("java.lang.Class"); 71 72 /** {@link ClassDesc} representing {@link Number} */ 73 public static final ClassDesc CR_Number = ClassDesc.of("java.lang.Number"); 74 75 /** {@link ClassDesc} representing {@link Integer} */ 76 public static final ClassDesc CR_Integer = ClassDesc.of("java.lang.Integer"); 77 78 /** {@link ClassDesc} representing {@link Long} */ 79 public static final ClassDesc CR_Long = ClassDesc.of("java.lang.Long"); 80 81 /** {@link ClassDesc} representing {@link Float} */ 82 public static final ClassDesc CR_Float = ClassDesc.of("java.lang.Float"); 83 84 /** {@link ClassDesc} representing {@link Double} */ 85 public static final ClassDesc CR_Double = ClassDesc.of("java.lang.Double"); 86 87 /** {@link ClassDesc} representing {@link Short} */ 88 public static final ClassDesc CR_Short = ClassDesc.of("java.lang.Short"); 89 90 /** {@link ClassDesc} representing {@link Byte} */ 91 public static final ClassDesc CR_Byte = ClassDesc.of("java.lang.Byte"); 92 93 /** {@link ClassDesc} representing {@link Character} */ 94 public static final ClassDesc CR_Character = ClassDesc.of("java.lang.Character"); 95 96 /** {@link ClassDesc} representing {@link Boolean} */ 97 public static final ClassDesc CR_Boolean = ClassDesc.of("java.lang.Boolean"); 98 99 /** {@link ClassDesc} representing {@link Void} */ 100 public static final ClassDesc CR_Void = ClassDesc.of("java.lang.Void"); 101 102 /** {@link ClassDesc} representing {@link Throwable} */ 103 public static final ClassDesc CR_Throwable = ClassDesc.of("java.lang.Throwable"); 104 105 /** {@link ClassDesc} representing {@link Exception} */ 106 public static final ClassDesc CR_Exception = ClassDesc.of("java.lang.Exception"); 107 108 /** {@link ClassDesc} representing {@link Enum} */ 109 public static final ClassDesc CR_Enum = ClassDesc.of("java.lang.Enum"); 110 111 /** {@link ClassDesc} representing {@link VarHandle} */ 112 public static final ClassDesc CR_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle"); 113 114 /** {@link ClassDesc} representing {@link MethodHandles} */ 115 public static final ClassDesc CR_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles"); 116 117 /** {@link ClassDesc} representing {@link MethodHandles.Lookup} */ 118 public static final ClassDesc CR_MethodHandles_Lookup = CR_MethodHandles.inner("Lookup"); 119 120 /** {@link ClassDesc} representing {@link MethodHandle} */ 121 public static final ClassDesc CR_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle"); 122 123 /** {@link ClassDesc} representing {@link MethodType} */ 124 public static final ClassDesc CR_MethodType = ClassDesc.of("java.lang.invoke.MethodType"); 125 126 /** {@link ClassDesc} representing {@link CallSite} */ 127 public static final ClassDesc CR_CallSite = ClassDesc.of("java.lang.invoke.CallSite"); 128 129 /** {@link ClassDesc} representing {@link Collection} */ 130 public static final ClassDesc CR_Collection = ClassDesc.of("java.util.Collection"); 131 132 /** {@link ClassDesc} representing {@link List} */ 133 public static final ClassDesc CR_List = ClassDesc.of("java.util.List"); 134 135 /** {@link ClassDesc} representing {@link Set} */ 136 public static final ClassDesc CR_Set = ClassDesc.of("java.util.Set"); 137 138 /** {@link ClassDesc} representing {@link Map} */ 139 public static final ClassDesc CR_Map = ClassDesc.of("java.util.Map"); 140 141 /** {@link ClassDesc} representing {@link ConstantDesc} */ 142 public static final ClassDesc CR_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc"); 143 144 /** {@link ClassDesc} representing {@link ClassDesc} */ 145 public static final ClassDesc CR_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc"); 146 147 /** {@link ClassDesc} representing {@link EnumDesc} */ 148 public static final ClassDesc CR_EnumDesc = CR_Enum.inner("EnumDesc"); 149 150 /** {@link ClassDesc} representing {@link MethodTypeDesc} */ 151 public static final ClassDesc CR_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc"); 152 153 /** {@link ClassDesc} representing {@link MethodHandleDesc} */ 154 public static final ClassDesc CR_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc"); 155 156 /** {@link ClassDesc} representing {@link DirectMethodHandleDescImpl} */ 157 public static final ClassDesc CR_DirectMethodHandleDesc = ClassDesc.of("java.lang.constant.DirectMethodHandleDesc"); 158 159 /** {@link ClassDesc} representing {@link VarHandleDesc} */ 160 public static final ClassDesc CR_VarHandleDesc = CR_VarHandle.inner("VarHandleDesc"); 161 162 /** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */ 163 public static final ClassDesc CR_MethodHandleDesc_Kind = CR_DirectMethodHandleDesc.inner("Kind"); 164 165 /** {@link ClassDesc} representing {@link DynamicConstantDesc} */ 166 public static final ClassDesc CR_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc"); 167 168 /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */ 169 public static final ClassDesc CR_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc"); 170 171 /** {@link ClassDesc} representing {@link ConstantBootstraps} */ 172 public static final ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps"); 173 174 private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = { 175 ConstantDescs.CR_MethodHandles_Lookup, 176 ConstantDescs.CR_String, 177 ConstantDescs.CR_MethodType }; 178 179 private static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = { 180 ConstantDescs.CR_MethodHandles_Lookup, 181 ConstantDescs.CR_String, 182 ConstantDescs.CR_Class }; 183 184 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class)} */ 185 public static final DirectMethodHandleDesc BSM_PRIMITIVE_CLASS 186 = ofConstantBootstrap(CR_ConstantBootstraps, "primitiveClass", 187 CR_Class); 188 189 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#enumConstant(Lookup, String, Class)} */ 190 public static final DirectMethodHandleDesc BSM_ENUM_CONSTANT 191 = ofConstantBootstrap(CR_ConstantBootstraps, "enumConstant", 192 CR_Enum); 193 194 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class)} */ 195 public static final DirectMethodHandleDesc BSM_NULL_CONSTANT 196 = ofConstantBootstrap(CR_ConstantBootstraps, "nullConstant", 197 ConstantDescs.CR_Object); 198 199 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class)} */ 200 public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD 201 = ofConstantBootstrap(CR_ConstantBootstraps, "fieldVarHandle", 202 CR_VarHandle, CR_Class, CR_Class); 203 204 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class)} */ 205 public static final DirectMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD 206 = ofConstantBootstrap(CR_ConstantBootstraps, "staticFieldVarHandle", 207 CR_VarHandle, CR_Class, CR_Class); 208 209 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class)} */ 210 public static final DirectMethodHandleDesc BSM_VARHANDLE_ARRAY 211 = ofConstantBootstrap(CR_ConstantBootstraps, "arrayVarHandle", 212 CR_VarHandle, CR_Class); 213 214 /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...)} */ 215 public static final DirectMethodHandleDesc BSM_INVOKE 216 = ofConstantBootstrap(CR_ConstantBootstraps, "invoke", 217 CR_Object, CR_MethodHandle, CR_Object.arrayType()); 218 219 /** {@link ClassDesc} representing the primitive type {@code int} */ 220 public static final ClassDesc CR_int = ClassDesc.ofDescriptor("I"); 221 222 /** {@link ClassDesc} representing the primitive type {@code long} */ 223 public static final ClassDesc CR_long = ClassDesc.ofDescriptor("J"); 224 225 /** {@link ClassDesc} representing the primitive type {@code float} */ 226 public static final ClassDesc CR_float = ClassDesc.ofDescriptor("F"); 227 228 /** {@link ClassDesc} representing the primitive type {@code double} */ 229 public static final ClassDesc CR_double = ClassDesc.ofDescriptor("D"); 230 231 /** {@link ClassDesc} representing the primitive type {@code short} */ 232 public static final ClassDesc CR_short = ClassDesc.ofDescriptor("S"); 233 234 /** {@link ClassDesc} representing the primitive type {@code byte} */ 235 public static final ClassDesc CR_byte = ClassDesc.ofDescriptor("B"); 236 237 /** {@link ClassDesc} representing the primitive type {@code char} */ 238 public static final ClassDesc CR_char = ClassDesc.ofDescriptor("C"); 239 240 /** {@link ClassDesc} representing the primitive type {@code boolean} */ 241 public static final ClassDesc CR_boolean = ClassDesc.ofDescriptor("Z"); 242 243 /** {@link ClassDesc} representing the primitive type {@code void} */ 244 public static final ClassDesc CR_void = ClassDesc.ofDescriptor("V"); 245 246 /** Nominal descriptor representing the constant {@code null} */ 247 public static final ConstantDesc<?> NULL 248 = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT, 249 DEFAULT_NAME, ConstantDescs.CR_Object); 250 251 // Used by XxxDesc classes, but need to be here to avoid bootstrap cycles 252 static final DirectMethodHandleDesc MHR_METHODTYPEDESC_FACTORY 253 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_MethodTypeDesc, "ofDescriptor", 254 CR_MethodTypeDesc, CR_String); 255 256 static final DirectMethodHandleDesc MHR_CLASSDESC_FACTORY 257 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_ClassDesc, "ofDescriptor", 258 CR_ClassDesc, CR_String); 259 260 static final DirectMethodHandleDesc MHR_METHODHANDLEDESC_FACTORY 261 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_DirectMethodHandleDesc, "ofDescriptor", 262 CR_DirectMethodHandleDesc, CR_String, CR_String, CR_String, CR_String); 263 264 static final DirectMethodHandleDesc MHR_METHODHANDLE_ASTYPE 265 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_MethodHandle, "asType", 266 CR_MethodHandle, CR_MethodType); 267 268 static final DirectMethodHandleDesc MHR_METHODHANDLEDESC_ASTYPE 269 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.VIRTUAL, CR_MethodHandleDesc, "asType", 270 CR_MethodHandleDesc, CR_MethodTypeDesc); 271 272 static final DirectMethodHandleDesc MHR_DYNAMICCONSTANTDESC_FACTORY 273 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_DynamicConstantDesc, "of", 274 CR_DynamicConstantDesc, CR_DirectMethodHandleDesc, CR_ConstantDesc.arrayType()); 275 276 static final DirectMethodHandleDesc MHR_DYNAMICCONSTANTDESC_NAMED_FACTORY 277 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_DynamicConstantDesc, "ofNamed", 278 CR_DynamicConstantDesc, CR_DirectMethodHandleDesc, CR_String, CR_String, CR_ConstantDesc.arrayType()); 279 280 /** {@link MethodHandleDesc} representing {@link EnumDesc#ofDescriptor(String, String)} */ 281 public static final DirectMethodHandleDesc MHR_ENUMDESC_FACTORY 282 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_EnumDesc, "ofDescriptor", 283 CR_EnumDesc, CR_String, CR_String); 284 285 /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofField(ClassDesc, String, ClassDesc)} */ 286 public static final DirectMethodHandleDesc MHR_VARHANDLEDESC_OFFIELD 287 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofField", 288 CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc); 289 /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofStaticField(ClassDesc, String, ClassDesc)} */ 290 public static final DirectMethodHandleDesc MHR_VARHANDLEDESC_OFSTATIC 291 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofStaticField", 292 CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc); 293 294 /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofArray(ClassDesc)} */ 295 public static final DirectMethodHandleDesc MHR_VARHANDLEDESC_OFARRAY 296 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofArray", 297 CR_VarHandleDesc, CR_ClassDesc); 298 299 static final DirectMethodHandleDesc BSM_METHODHANDLEDESC 300 = ConstantDescs.ofConstantBootstrap(CR_DirectMethodHandleDesc, 301 "constantBootstrap", CR_DirectMethodHandleDesc, 302 CR_String, CR_String, CR_String, CR_String); 303 304 static final DirectMethodHandleDesc BSM_DYNAMICCONSTANTDESC 305 = ConstantDescs.ofConstantBootstrap(CR_DynamicConstantDesc, 306 "constantBootstrap", 307 CR_DynamicConstantDesc, 308 CR_DirectMethodHandleDesc, CR_String, CR_String, CR_ConstantDesc.arrayType()); 309 310 /** 311 * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for 312 * an {@code invokedynamic} callsite, which is a static method whose leading 313 * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}. 314 * 315 * @param clazz the class declaring the method 316 * @param name the name of the method, as per JVMS 4.2.2 317 * @param returnType the return type of the method 318 * @param paramTypes the types of the static bootstrap arguments, if any 319 * @return the {@link MethodHandleDesc} 320 * @throws NullPointerException if any of the arguments are null 321 * @jvms 4.2.2 Unqualified Names 322 */ 323 public static DirectMethodHandleDesc ofCallsiteBootstrap(ClassDesc clazz, 324 String name, 325 ClassDesc returnType, 326 ClassDesc... paramTypes) { 327 return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes) 328 .insertParameterTypes(0, INDY_BOOTSTRAP_ARGS)); 329 } 330 331 /** 332 * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for a 333 * dynamic constant, which is a static method whose leading arguments are 334 * {@code Lookup}, {@code String}, and {@code Class}. 335 * 336 * @param clazz the class declaring the method 337 * @param name the name of the method, as per JVMS 4.2.2 338 * @param returnType the return type of the method 339 * @param paramTypes the types of the static bootstrap arguments, if any 340 * @return the {@link MethodHandleDesc} 341 * @throws NullPointerException if any of the arguments are null 342 * @jvms 4.2.2 Unqualified Names 343 */ 344 public static DirectMethodHandleDesc ofConstantBootstrap(ClassDesc clazz, 345 String name, 346 ClassDesc returnType, 347 ClassDesc... paramTypes) { 348 return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes) 349 .insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS)); 350 } 351 }