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 }