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.*;
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
ConstantDescs()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     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class) ConstantBootstraps.nullConstant} */
198     public static final DirectMethodHandleDesc BSM_NULL_CONSTANT
199             = ofConstantBootstrap(CD_ConstantBootstraps, "nullConstant",
200                                   ConstantDescs.CD_Object);
201 
202     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.fieldVarHandle} */
203     public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD
204             = ofConstantBootstrap(CD_ConstantBootstraps, "fieldVarHandle",
205             CD_VarHandle, CD_Class, CD_Class);
206 
207     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.staticVarHandle} */
208     public static final DirectMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD
209             = ofConstantBootstrap(CD_ConstantBootstraps, "staticFieldVarHandle",
210             CD_VarHandle, CD_Class, CD_Class);
211 
212     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class) ConstantBootstraps.arrayVarHandle} */
213     public static final DirectMethodHandleDesc BSM_VARHANDLE_ARRAY
214             = ofConstantBootstrap(CD_ConstantBootstraps, "arrayVarHandle",
215             CD_VarHandle, CD_Class);
216 
217     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...) ConstantBootstraps.invoke} */
218     public static final DirectMethodHandleDesc BSM_INVOKE
219             = ofConstantBootstrap(CD_ConstantBootstraps, "invoke",
220             CD_Object, CD_MethodHandle, CD_Object.arrayType());
221 
222     /** {@link ClassDesc} representing the primitive type {@code int} */
223     public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I");
224 
225     /** {@link ClassDesc} representing the primitive type {@code long} */
226     public static final ClassDesc CD_long = ClassDesc.ofDescriptor("J");
227 
228     /** {@link ClassDesc} representing the primitive type {@code float} */
229     public static final ClassDesc CD_float = ClassDesc.ofDescriptor("F");
230 
231     /** {@link ClassDesc} representing the primitive type {@code double} */
232     public static final ClassDesc CD_double = ClassDesc.ofDescriptor("D");
233 
234     /** {@link ClassDesc} representing the primitive type {@code short} */
235     public static final ClassDesc CD_short = ClassDesc.ofDescriptor("S");
236 
237     /** {@link ClassDesc} representing the primitive type {@code byte} */
238     public static final ClassDesc CD_byte = ClassDesc.ofDescriptor("B");
239 
240     /** {@link ClassDesc} representing the primitive type {@code char} */
241     public static final ClassDesc CD_char = ClassDesc.ofDescriptor("C");
242 
243     /** {@link ClassDesc} representing the primitive type {@code boolean} */
244     public static final ClassDesc CD_boolean = ClassDesc.ofDescriptor("Z");
245 
246     /** {@link ClassDesc} representing the primitive type {@code void} */
247     public static final ClassDesc CD_void = ClassDesc.ofDescriptor("V");
248 
249     /** Nominal descriptor representing the constant {@code null} */
250     public static final ConstantDesc NULL
251             = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT,
252                                           DEFAULT_NAME, ConstantDescs.CD_Object);
253 
254     static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
255             = MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
256                                         MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
257     /**
258      * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for
259      * an {@code invokedynamic} callsite, which is a static method whose leading
260      * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}.
261      *
262      * @param owner the class declaring the method
263      * @param name the unqualified name of the method
264      * @param returnType the return type of the method
265      * @param paramTypes the types of the static bootstrap arguments, if any
266      * @return the {@link MethodHandleDesc}
267      * @throws NullPointerException if any of the arguments are null
268      * @jvms 4.2.2 Unqualified Names
269      */
ofCallsiteBootstrap(ClassDesc owner, String name, ClassDesc returnType, ClassDesc... paramTypes)270     public static DirectMethodHandleDesc ofCallsiteBootstrap(ClassDesc owner,
271                                                              String name,
272                                                              ClassDesc returnType,
273                                                              ClassDesc... paramTypes) {
274         return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes)
275                                                                             .insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
276     }
277 
278     /**
279      * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for a
280      * dynamic constant, which is a static method whose leading arguments are
281      * {@code Lookup}, {@code String}, and {@code Class}.
282      *
283      * @param owner the class declaring the method
284      * @param name the unqualified name of the method
285      * @param returnType the return type of the method
286      * @param paramTypes the types of the static bootstrap arguments, if any
287      * @return the {@link MethodHandleDesc}
288      * @throws NullPointerException if any of the arguments are null
289      * @jvms 4.2.2 Unqualified Names
290      */
ofConstantBootstrap(ClassDesc owner, String name, ClassDesc returnType, ClassDesc... paramTypes)291     public static DirectMethodHandleDesc ofConstantBootstrap(ClassDesc owner,
292                                                              String name,
293                                                              ClassDesc returnType,
294                                                              ClassDesc... paramTypes) {
295         return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes)
296                                                                             .insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
297     }
298 }
299