• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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