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.MethodType; 28 import java.lang.invoke.TypeDescriptor; 29 import java.util.List; 30 import java.util.stream.Collectors; 31 import java.util.stream.Stream; 32 33 import static java.lang.constant.ConstantUtils.getDisplayDescriptor; 34 35 36 /** 37 * A <a href="package-summary.html#nominal">nominal descriptor</a> for a 38 * {@linkplain MethodType} constant. 39 * 40 * @apiNote In the future, if the Java language permits, {@linkplain MethodTypeDesc} 41 * may become a {@code sealed} interface, which would prohibit subclassing except 42 * by explicitly permitted types. Non-platform classes should not implement 43 * {@linkplain MethodTypeDesc} directly. 44 * 45 * @since 12 46 */ 47 public interface MethodTypeDesc 48 extends ConstantDesc, 49 TypeDescriptor.OfMethod<ClassDesc, MethodTypeDesc> { 50 /** 51 * Creates a {@linkplain MethodTypeDesc} given a method descriptor string. 52 * 53 * @param descriptor a method descriptor string 54 * @return a {@linkplain MethodTypeDesc} describing the desired method type 55 * @throws NullPointerException if any argument is {@code null} 56 * @throws IllegalArgumentException if the descriptor string is not a valid 57 * method descriptor 58 * @jvms 4.3.3 Method Descriptors 59 */ 60 static MethodTypeDesc ofDescriptor(String descriptor) { 61 return MethodTypeDescImpl.ofDescriptor(descriptor); 62 } 63 64 /** 65 * Returns a {@linkplain MethodTypeDesc} given the return type and parameter 66 * types. 67 * 68 * @param returnDesc a {@linkplain ClassDesc} describing the return type 69 * @param paramDescs {@linkplain ClassDesc}s describing the argument types 70 * @return a {@linkplain MethodTypeDesc} describing the desired method type 71 * @throws NullPointerException if any argument is {@code null} 72 */ 73 static MethodTypeDesc of(ClassDesc returnDesc, ClassDesc... paramDescs) { 74 return new MethodTypeDescImpl(returnDesc, paramDescs); 75 } 76 77 /** 78 * Gets the return type of the method type described by this {@linkplain MethodTypeDesc}. 79 * 80 * @return a {@link ClassDesc} describing the return type of the method type 81 */ 82 ClassDesc returnType(); 83 84 /** 85 * Returns the number of parameters of the method type described by 86 * this {@linkplain MethodTypeDesc}. 87 * @return the number of parameters 88 */ 89 int parameterCount(); 90 91 /** 92 * Returns the parameter type of the {@code index}'th parameter of the method type 93 * described by this {@linkplain MethodTypeDesc}. 94 * 95 * @param index the index of the parameter to retrieve 96 * @return a {@link ClassDesc} describing the desired parameter type 97 * @throws IndexOutOfBoundsException if the index is outside the half-open 98 * range {[0, parameterCount())} 99 */ 100 ClassDesc parameterType(int index); 101 102 /** 103 * Returns the parameter types as an immutable {@link List}. 104 * 105 * @return a {@link List} of {@link ClassDesc} describing the parameter types 106 */ 107 List<ClassDesc> parameterList(); 108 109 /** 110 * Returns the parameter types as an array. 111 * 112 * @return an array of {@link ClassDesc} describing the parameter types 113 */ 114 ClassDesc[] parameterArray(); 115 116 /** 117 * Returns a {@linkplain MethodTypeDesc} that is identical to 118 * this one, except with the specified return type. 119 * 120 * @param returnType a {@link ClassDesc} describing the new return type 121 * @return a {@linkplain MethodTypeDesc} describing the desired method type 122 * @throws NullPointerException if any argument is {@code null} 123 */ 124 MethodTypeDesc changeReturnType(ClassDesc returnType); 125 126 /** 127 * Returns a {@linkplain MethodTypeDesc} that is identical to this one, 128 * except that a single parameter type has been changed to the specified type. 129 * 130 * @param index the index of the parameter to change 131 * @param paramType a {@link ClassDesc} describing the new parameter type 132 * @return a {@linkplain MethodTypeDesc} describing the desired method type 133 * @throws NullPointerException if any argument is {@code null} 134 * @throws IndexOutOfBoundsException if the index is outside the half-open 135 * range {[0, parameterCount)} 136 */ 137 MethodTypeDesc changeParameterType(int index, ClassDesc paramType); 138 139 /** 140 * Returns a {@linkplain MethodTypeDesc} that is identical to this one, 141 * except that a range of parameter types have been removed. 142 * 143 * @param start the index of the first parameter to remove 144 * @param end the index after the last parameter to remove 145 * @return a {@linkplain MethodTypeDesc} describing the desired method type 146 * @throws IndexOutOfBoundsException if {@code start} is outside the half-open 147 * range {[0, parameterCount)}, or {@code end} is outside the closed range 148 * {@code [0, parameterCount]} 149 */ 150 MethodTypeDesc dropParameterTypes(int start, int end); 151 152 /** 153 * Returns a {@linkplain MethodTypeDesc} that is identical to this one, 154 * except that a range of additional parameter types have been inserted. 155 * 156 * @param pos the index at which to insert the first inserted parameter 157 * @param paramTypes {@link ClassDesc}s describing the new parameter types 158 * to insert 159 * @return a {@linkplain MethodTypeDesc} describing the desired method type 160 * @throws NullPointerException if any argument is {@code null} 161 * @throws IndexOutOfBoundsException if {@code pos} is outside the closed 162 * range {[0, parameterCount]} 163 */ 164 MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes); 165 166 /** 167 * Returns the method type descriptor string. 168 * 169 * @return the method type descriptor string 170 * @jvms 4.3.3 Method Descriptors 171 */ 172 default String descriptorString() { 173 return String.format("(%s)%s", 174 Stream.of(parameterArray()) 175 .map(ClassDesc::descriptorString) 176 .collect(Collectors.joining()), 177 returnType().descriptorString()); 178 } 179 180 /** 181 * Returns a human-readable descriptor for this method type, using the 182 * canonical names for parameter and return types. 183 * 184 * @return the human-readable descriptor for this method type 185 */ 186 default String displayDescriptor() { 187 return getDisplayDescriptor(this, false); 188 } 189 190 /** 191 * Returns a human-readable descriptor for this method type, using the 192 * fully qualified canonical names for parameter and return types. 193 * 194 * @return the human-readable descriptor for this method type 195 */ 196 default String displayFullDescriptor() { 197 return getDisplayDescriptor(this, true); 198 } 199 200 /** 201 * Compares the specified object with this descriptor for equality. Returns 202 * {@code true} if and only if the specified object is also a 203 * {@linkplain MethodTypeDesc} both have the same arity, their return types 204 * are equal, and each pair of corresponding parameter types are equal. 205 * 206 * @param o the other object 207 * @return whether this descriptor is equal to the other object 208 */ 209 boolean equals(Object o); 210 }