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