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 jdk.internal.lang.annotation.Foldable;
  28 
  29 import java.lang.Enum.EnumDesc;
  30 import java.lang.invoke.CallSite;
  31 import java.lang.invoke.ConstantBootstraps;
  32 import java.lang.invoke.MethodHandle;
  33 import java.lang.invoke.MethodHandles;
  34 import java.lang.invoke.MethodHandles.Lookup;
  35 import java.lang.invoke.MethodType;
  36 import java.lang.invoke.VarHandle;
  37 import java.lang.invoke.VarHandle.VarHandleDesc;
  38 import java.util.Collection;
  39 import java.util.List;
  40 import java.util.Map;
  41 import java.util.Set;
  42 
  43 import static java.lang.constant.DirectMethodHandleDesc.*;
  44 import static java.lang.constant.DirectMethodHandleDesc.Kind.STATIC;
  45 
  46 /**
  47  * Predefined values of <a href="package-summary.html#nominal">nominal descriptor</a>
  48  * for common constants, including descriptors for primitive class types and
  49  * other common platform types, and descriptors for method handles for standard
  50  * bootstrap methods.
  51  *
  52  * @see ConstantDesc
  53  *
  54  * @since 12
  55  */
  56 public final class ConstantDescs {
  57     // No instances
  58     private ConstantDescs() { }
  59 
  60     /** Invocation name to use when no name is needed, such as the name of a
  61      * constructor, or the invocation name of a dynamic constant or dynamic
  62      * callsite when the bootstrap is known to ignore the invocation name.
  63      */
  64     public static final String DEFAULT_NAME = "_";
  65 
  66     // Don't change the order of these declarations!
  67 
  68     /** {@link ClassDesc} representing {@link Object} */
  69     @Foldable
  70     public static final ClassDesc CD_Object = ClassDesc.of("java.lang.Object");
  71 
  72     /** {@link ClassDesc} representing {@link String} */
  73     @Foldable
  74     public static final ClassDesc CD_String = ClassDesc.of("java.lang.String");
  75 
  76     /** {@link ClassDesc} representing {@link Class} */
  77     @Foldable
  78     public static final ClassDesc CD_Class = ClassDesc.of("java.lang.Class");
  79 
  80     /** {@link ClassDesc} representing {@link Number} */
  81     @Foldable
  82     public static final ClassDesc CD_Number = ClassDesc.of("java.lang.Number");
  83 
  84     /** {@link ClassDesc} representing {@link Integer} */
  85     @Foldable
  86     public static final ClassDesc CD_Integer = ClassDesc.of("java.lang.Integer");
  87 
  88     /** {@link ClassDesc} representing {@link Long} */
  89     @Foldable
  90     public static final ClassDesc CD_Long = ClassDesc.of("java.lang.Long");
  91 
  92     /** {@link ClassDesc} representing {@link Float} */
  93     @Foldable
  94     public static final ClassDesc CD_Float = ClassDesc.of("java.lang.Float");
  95 
  96     /** {@link ClassDesc} representing {@link Double} */
  97     @Foldable
  98     public static final ClassDesc CD_Double = ClassDesc.of("java.lang.Double");
  99 
 100     /** {@link ClassDesc} representing {@link Short} */
 101     @Foldable
 102     public static final ClassDesc CD_Short = ClassDesc.of("java.lang.Short");
 103 
 104     /** {@link ClassDesc} representing {@link Byte} */
 105     @Foldable
 106     public static final ClassDesc CD_Byte = ClassDesc.of("java.lang.Byte");
 107 
 108     /** {@link ClassDesc} representing {@link Character} */
 109     @Foldable
 110     public static final ClassDesc CD_Character = ClassDesc.of("java.lang.Character");
 111 
 112     /** {@link ClassDesc} representing {@link Boolean} */
 113     @Foldable
 114     public static final ClassDesc CD_Boolean = ClassDesc.of("java.lang.Boolean");
 115 
 116     /** {@link ClassDesc} representing {@link Void} */
 117     @Foldable
 118     public static final ClassDesc CD_Void = ClassDesc.of("java.lang.Void");
 119 
 120     /** {@link ClassDesc} representing {@link Throwable} */
 121     @Foldable
 122     public static final ClassDesc CD_Throwable = ClassDesc.of("java.lang.Throwable");
 123 
 124     /** {@link ClassDesc} representing {@link Exception} */
 125     @Foldable
 126     public static final ClassDesc CD_Exception = ClassDesc.of("java.lang.Exception");
 127 
 128     /** {@link ClassDesc} representing {@link Enum} */
 129     @Foldable
 130     public static final ClassDesc CD_Enum = ClassDesc.of("java.lang.Enum");
 131 
 132     /** {@link ClassDesc} representing {@link VarHandle} */
 133     @Foldable
 134     public static final ClassDesc CD_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle");
 135 
 136     /** {@link ClassDesc} representing {@link MethodHandles} */
 137     @Foldable
 138     public static final ClassDesc CD_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles");
 139 
 140     /** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
 141     @Foldable
 142     public static final ClassDesc CD_MethodHandles_Lookup = CD_MethodHandles.nested("Lookup");
 143 
 144     /** {@link ClassDesc} representing {@link MethodHandle} */
 145     @Foldable
 146     public static final ClassDesc CD_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle");
 147 
 148     /** {@link ClassDesc} representing {@link MethodType} */
 149     @Foldable
 150     public static final ClassDesc CD_MethodType = ClassDesc.of("java.lang.invoke.MethodType");
 151 
 152     /** {@link ClassDesc} representing {@link CallSite} */
 153     @Foldable
 154     public static final ClassDesc CD_CallSite = ClassDesc.of("java.lang.invoke.CallSite");
 155 
 156     /** {@link ClassDesc} representing {@link Collection} */
 157     @Foldable
 158     public static final ClassDesc CD_Collection = ClassDesc.of("java.util.Collection");
 159 
 160     /** {@link ClassDesc} representing {@link List} */
 161     @Foldable
 162     public static final ClassDesc CD_List = ClassDesc.of("java.util.List");
 163 
 164     /** {@link ClassDesc} representing {@link Set} */
 165     @Foldable
 166     public static final ClassDesc CD_Set = ClassDesc.of("java.util.Set");
 167 
 168     /** {@link ClassDesc} representing {@link Map} */
 169     @Foldable
 170     public static final ClassDesc CD_Map = ClassDesc.of("java.util.Map");
 171 
 172     /** {@link ClassDesc} representing {@link ConstantDesc} */
 173     @Foldable
 174     public static final ClassDesc CD_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc");
 175 
 176     /** {@link ClassDesc} representing {@link ClassDesc} */
 177     @Foldable
 178     public static final ClassDesc CD_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc");
 179 
 180     /** {@link ClassDesc} representing {@link EnumDesc} */
 181     @Foldable
 182     public static final ClassDesc CD_EnumDesc = CD_Enum.nested("EnumDesc");
 183 
 184     /** {@link ClassDesc} representing {@link MethodTypeDesc} */
 185     @Foldable
 186     public static final ClassDesc CD_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc");
 187 
 188     /** {@link ClassDesc} representing {@link MethodHandleDesc} */
 189     @Foldable
 190     public static final ClassDesc CD_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc");
 191 
 192     /** {@link ClassDesc} representing {@link DirectMethodHandleDesc} */
 193     @Foldable
 194     public static final ClassDesc CD_DirectMethodHandleDesc = ClassDesc.of("java.lang.constant.DirectMethodHandleDesc");
 195 
 196     /** {@link ClassDesc} representing {@link VarHandleDesc} */
 197     @Foldable
 198     public static final ClassDesc CD_VarHandleDesc = CD_VarHandle.nested("VarHandleDesc");
 199 
 200     /** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */
 201     @Foldable
 202     public static final ClassDesc CD_MethodHandleDesc_Kind = CD_DirectMethodHandleDesc.nested("Kind");
 203 
 204     /** {@link ClassDesc} representing {@link DynamicConstantDesc} */
 205     @Foldable
 206     public static final ClassDesc CD_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc");
 207 
 208     /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
 209     @Foldable
 210     public static final ClassDesc CD_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc");
 211 
 212     /** {@link ClassDesc} representing {@link ConstantBootstraps} */
 213     @Foldable
 214     public static final ClassDesc CD_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
 215 
 216     private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
 217             ConstantDescs.CD_MethodHandles_Lookup,
 218             ConstantDescs.CD_String,
 219             ConstantDescs.CD_MethodType};
 220 
 221     private static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
 222             ConstantDescs.CD_MethodHandles_Lookup,
 223             ConstantDescs.CD_String,
 224             ConstantDescs.CD_Class};
 225 
 226     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class) ConstantBootstraps.primitiveClass} */
 227     @Foldable
 228     public static final DirectMethodHandleDesc BSM_PRIMITIVE_CLASS
 229             = ofConstantBootstrap(CD_ConstantBootstraps, "primitiveClass",
 230             CD_Class);
 231 
 232     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#enumConstant(Lookup, String, Class) ConstantBootstraps.enumConstant} */
 233     @Foldable
 234     public static final DirectMethodHandleDesc BSM_ENUM_CONSTANT
 235             = ofConstantBootstrap(CD_ConstantBootstraps, "enumConstant",
 236             CD_Enum);
 237 
 238     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class) ConstantBootstraps.nullConstant} */
 239     @Foldable
 240     public static final DirectMethodHandleDesc BSM_NULL_CONSTANT
 241             = ofConstantBootstrap(CD_ConstantBootstraps, "nullConstant",
 242                                   ConstantDescs.CD_Object);
 243 
 244     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.fieldVarHandle} */
 245     @Foldable
 246     public static final DirectMethodHandleDesc BSM_VARHANDLE_FIELD
 247             = ofConstantBootstrap(CD_ConstantBootstraps, "fieldVarHandle",
 248             CD_VarHandle, CD_Class, CD_Class);
 249 
 250     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class) ConstantBootstraps.staticVarHandle} */
 251     @Foldable    
 252     public static final DirectMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD
 253             = ofConstantBootstrap(CD_ConstantBootstraps, "staticFieldVarHandle",
 254             CD_VarHandle, CD_Class, CD_Class);
 255 
 256     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class) ConstantBootstraps.arrayVarHandle} */
 257     @Foldable
 258     public static final DirectMethodHandleDesc BSM_VARHANDLE_ARRAY
 259             = ofConstantBootstrap(CD_ConstantBootstraps, "arrayVarHandle",
 260             CD_VarHandle, CD_Class);
 261 
 262     /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...) ConstantBootstraps.invoke} */
 263     @Foldable
 264     public static final DirectMethodHandleDesc BSM_INVOKE
 265             = ofConstantBootstrap(CD_ConstantBootstraps, "invoke",
 266             CD_Object, CD_MethodHandle, CD_Object.arrayType());
 267 
 268     /** {@link ClassDesc} representing the primitive type {@code int} */
 269     @Foldable
 270     public static final ClassDesc CD_int = ClassDesc.ofDescriptor("I");
 271 
 272     /** {@link ClassDesc} representing the primitive type {@code long} */
 273     @Foldable
 274     public static final ClassDesc CD_long = ClassDesc.ofDescriptor("J");
 275 
 276     /** {@link ClassDesc} representing the primitive type {@code float} */
 277     @Foldable
 278     public static final ClassDesc CD_float = ClassDesc.ofDescriptor("F");
 279 
 280     /** {@link ClassDesc} representing the primitive type {@code double} */
 281     @Foldable
 282     public static final ClassDesc CD_double = ClassDesc.ofDescriptor("D");
 283 
 284     /** {@link ClassDesc} representing the primitive type {@code short} */
 285     @Foldable
 286     public static final ClassDesc CD_short = ClassDesc.ofDescriptor("S");
 287 
 288     /** {@link ClassDesc} representing the primitive type {@code byte} */
 289     @Foldable
 290     public static final ClassDesc CD_byte = ClassDesc.ofDescriptor("B");
 291 
 292     /** {@link ClassDesc} representing the primitive type {@code char} */
 293     @Foldable
 294     public static final ClassDesc CD_char = ClassDesc.ofDescriptor("C");
 295 
 296     /** {@link ClassDesc} representing the primitive type {@code boolean} */
 297     @Foldable
 298     public static final ClassDesc CD_boolean = ClassDesc.ofDescriptor("Z");
 299 
 300     /** {@link ClassDesc} representing the primitive type {@code void} */
 301     @Foldable
 302     public static final ClassDesc CD_void = ClassDesc.ofDescriptor("V");
 303 
 304     /** Nominal descriptor representing the constant {@code null} */
 305     @Foldable
 306     public static final ConstantDesc NULL
 307             = DynamicConstantDesc.ofNamed(ConstantDescs.BSM_NULL_CONSTANT,
 308                                           DEFAULT_NAME, ConstantDescs.CD_Object);
 309 
 310     static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE
 311             = MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType",
 312                                         MethodTypeDesc.of(CD_MethodHandle, CD_MethodType));
 313     /**
 314      * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for
 315      * an {@code invokedynamic} callsite, which is a static method whose leading
 316      * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}.
 317      *
 318      * @param owner the class declaring the method
 319      * @param name the unqualified name of the method
 320      * @param returnType the return type of the method
 321      * @param paramTypes the types of the static bootstrap arguments, if any
 322      * @return the {@link MethodHandleDesc}
 323      * @throws NullPointerException if any of the arguments are null
 324      * @jvms 4.2.2 Unqualified Names
 325      */
 326     @Foldable
 327     public static DirectMethodHandleDesc ofCallsiteBootstrap(ClassDesc owner,
 328                                                              String name,
 329                                                              ClassDesc returnType,
 330                                                              ClassDesc... paramTypes) {
 331         return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes)
 332                                                                             .insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
 333     }
 334 
 335     /**
 336      * Returns a {@link MethodHandleDesc} corresponding to a bootstrap method for a
 337      * dynamic constant, which is a static method whose leading arguments are
 338      * {@code Lookup}, {@code String}, and {@code Class}.
 339      *
 340      * @param owner the class declaring the method
 341      * @param name the unqualified name of the method
 342      * @param returnType the return type of the method
 343      * @param paramTypes the types of the static bootstrap arguments, if any
 344      * @return the {@link MethodHandleDesc}
 345      * @throws NullPointerException if any of the arguments are null
 346      * @jvms 4.2.2 Unqualified Names
 347      */
 348     @Foldable
 349     public static DirectMethodHandleDesc ofConstantBootstrap(ClassDesc owner,
 350                                                              String name,
 351                                                              ClassDesc returnType,
 352                                                              ClassDesc... paramTypes) {
 353         return MethodHandleDesc.ofMethod(STATIC, owner, name, MethodTypeDesc.of(returnType, paramTypes)
 354                                                                             .insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
 355     }
 356 }