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.invoke.MethodHandle;
  28 import java.lang.invoke.MethodHandleInfo;
  29 import java.lang.invoke.MethodHandles;
  30 
  31 import static java.lang.invoke.MethodHandleInfo.REF_getField;
  32 import static java.lang.invoke.MethodHandleInfo.REF_getStatic;
  33 import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface;
  34 import static java.lang.invoke.MethodHandleInfo.REF_invokeSpecial;
  35 import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
  36 import static java.lang.invoke.MethodHandleInfo.REF_invokeVirtual;
  37 import static java.lang.invoke.MethodHandleInfo.REF_newInvokeSpecial;
  38 import static java.lang.invoke.MethodHandleInfo.REF_putField;
  39 import static java.lang.invoke.MethodHandleInfo.REF_putStatic;
  40 
  41 /**
  42  * A <a href="package-summary.html#nominal">nominal descriptor</a> for a direct
  43  * {@link MethodHandle}.  A {@linkplain DirectMethodHandleDescImpl} corresponds to
  44  * a {@code Constant_MethodHandle_info} entry in the constant pool of a classfile.
  45  *
  46  * @apiNote In the future, if the Java language permits, {@linkplain DirectMethodHandleDesc}
  47  * may become a {@code sealed} interface, which would prohibit subclassing except
  48  * by explicitly permitted types.  Non-platform classes should not implement
  49  * {@linkplain DirectMethodHandleDesc} directly.
  50  */
  51 public interface DirectMethodHandleDesc extends MethodHandleDesc {
  52     /**
  53      * Kinds of method handles that can be described with {@linkplain DirectMethodHandleDesc}.
  54      */
  55     enum Kind {
  56         /** A method handle for a method invoked as with {@code invokestatic} */
  57         STATIC(REF_invokeStatic),
  58         /** A method handle for a method invoked as with {@code invokestatic} */
  59         INTERFACE_STATIC(REF_invokeStatic, true),
  60         /** A method handle for a method invoked as with {@code invokevirtual} */
  61         VIRTUAL(REF_invokeVirtual),
  62         /** A method handle for a method invoked as with {@code invokeinterface} */
  63         INTERFACE_VIRTUAL(REF_invokeInterface, true),
  64         /** A method handle for a method invoked as with {@code invokespecial} */
  65         SPECIAL(REF_invokeSpecial),
  66         /** A method handle for an interface method invoked as with {@code invokespecial} */
  67         INTERFACE_SPECIAL(REF_invokeSpecial, true),
  68         /** A method handle for a constructor */
  69         CONSTRUCTOR(REF_newInvokeSpecial),
  70         /** A method handle for a read accessor for an instance field  */
  71         GETTER(REF_getField),
  72         /** A method handle for a write accessor for an instance field  */
  73         SETTER(REF_putField),
  74         /** A method handle for a read accessor for a static field  */
  75         STATIC_GETTER(REF_getStatic),
  76         /** A method handle for a write accessor for a static field  */
  77         STATIC_SETTER(REF_putStatic);
  78 
  79         /** The corresponding {@code refKind} value for this kind of method handle,
  80          * as defined by {@link MethodHandleInfo}
  81          */
  82         public final int refKind;
  83 
  84         /** Is this an interface
  85          */
  86         public final boolean isInterface;
  87         Kind(int refKind) {
  88             this(refKind, false);
  89         }
  90 
  91         Kind(int refKind, boolean isInterface) { this.refKind = refKind; this.isInterface = isInterface; }
  92     }
  93     /**
  94      * Return the {@code kind} of the method handle described by this nominal
  95      * descriptor.
  96      *
  97      * @return the {@link Kind}
  98      */
  99     Kind kind();
 100 
 101     /**
 102      * Return the {@code refKind} of the method handle described by this nominal
 103      * reference, as defined by {@link MethodHandleInfo}.
 104      *
 105      * @return the reference kind
 106      */
 107     int refKind();
 108 
 109     /**
 110      * Indicates if the method is declared by an interface
 111      *
 112      * @return true if the method is declared by an interface
 113      */
 114     boolean isOwnerInterface();
 115 
 116     /**
 117      * Return a {@link ClassDesc} describing the class declaring the
 118      * method or field described by this nominal descriptor.
 119      *
 120      * @return the class declaring the method or field
 121      */
 122     ClassDesc owner();
 123 
 124     /**
 125      * Return the name of the method or field described by this nominal descriptor.
 126      *
 127      * @return the name of the method or field
 128      */
 129     String methodName();
 130 
 131     /**
 132      * Return a {@link MethodTypeDesc} describing the invocation type of the
 133      * method handle described by this nominal descriptor
 134      *
 135      * @return the method type
 136      */
 137     MethodTypeDesc methodType();
 138 
 139     /**
 140      * Create a {@linkplain DirectMethodHandleDesc} given descriptor strings
 141      * for its components.  Suitable for use as a constant bootstrap method
 142      * for representing a {@linkplain DirectMethodHandleDesc} in the constant
 143      * pool of a classfile.
 144      *
 145      * @param bsmKindName The name of an {@code enum} constant from {@link Kind}
 146      * @param memberOwner A field type descriptor for the class declaring the
 147      *                 method, field, or constructor, as per JVMS 4.3.2
 148      * @param memberName The name of the method or field, as per JVMS 4.2.2
 149      * @param memberType A method type descriptor for the method handle being
 150      *                described, as per JVMS 4.3.3
 151      * @return the {@linkplain MethodHandleDesc}
 152      * @jvms 4.2.2 Unqualified Names
 153      * @jvms 4.3.2 Field Descriptors
 154      * @jvms 4.3.3 Method Descriptors
 155      */
 156     static DirectMethodHandleDesc ofDescriptor(String bsmKindName,
 157                                                String memberOwner,
 158                                                String memberName,
 159                                                String memberType) {
 160         return MethodHandleDesc.of(Kind.valueOf(bsmKindName),
 161                                    ClassDesc.ofDescriptor(memberOwner), memberName,
 162                                    MethodTypeDesc.ofDescriptor(memberType));
 163     }
 164 }