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 }