103 * |
103 * |
104 * @param methods the list of methods |
104 * @param methods the list of methods |
105 * @param varArgs whether to assume the methods are varargs |
105 * @param varArgs whether to assume the methods are varargs |
106 * @return the list of maximally specific methods. |
106 * @return the list of maximally specific methods. |
107 */ |
107 */ |
108 static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs) { |
108 static List<SingleDynamicMethod> getMaximallySpecificMethods(List<SingleDynamicMethod> methods, boolean varArgs) { |
109 return getMaximallySpecificMethods(methods, varArgs, null, null); |
109 return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null); |
110 } |
110 } |
|
111 |
|
112 private abstract static class MethodTypeGetter<T> { |
|
113 abstract MethodType getMethodType(T t); |
|
114 } |
|
115 |
|
116 private static final MethodTypeGetter<MethodHandle> METHOD_HANDLE_TYPE_GETTER = |
|
117 new MethodTypeGetter<MethodHandle>() { |
|
118 @Override |
|
119 MethodType getMethodType(MethodHandle t) { |
|
120 return t.type(); |
|
121 } |
|
122 }; |
|
123 |
|
124 private static final MethodTypeGetter<SingleDynamicMethod> DYNAMIC_METHOD_TYPE_GETTER = |
|
125 new MethodTypeGetter<SingleDynamicMethod>() { |
|
126 @Override |
|
127 MethodType getMethodType(SingleDynamicMethod t) { |
|
128 return t.getMethodType(); |
|
129 } |
|
130 }; |
|
131 |
|
132 /** |
|
133 * Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime |
|
134 * specific conversion preferences. |
|
135 * |
|
136 * @param methods the list of method handles |
|
137 * @param varArgs whether to assume the method handles are varargs |
|
138 * @param argTypes concrete argument types for the invocation |
|
139 * @return the list of maximally specific method handles. |
|
140 */ |
|
141 static List<MethodHandle> getMaximallySpecificMethodHandles(List<MethodHandle> methods, boolean varArgs, |
|
142 Class<?>[] argTypes, LinkerServices ls) { |
|
143 return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER); |
|
144 } |
|
145 |
|
146 /** |
|
147 * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific |
|
148 * conversion preferences. |
|
149 * |
|
150 * @param methods the list of methods |
|
151 * @param varArgs whether to assume the methods are varargs |
|
152 * @param argTypes concrete argument types for the invocation |
|
153 * @return the list of maximally specific methods. |
|
154 */ |
|
155 static List<SingleDynamicMethod> getMaximallySpecificSingleDynamicMethods(List<SingleDynamicMethod> methods, |
|
156 boolean varArgs, Class<?>[] argTypes, LinkerServices ls) { |
|
157 return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER); |
|
158 } |
111 |
159 |
112 /** |
160 /** |
113 * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific |
161 * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific |
114 * conversion preferences. |
162 * conversion preferences. |
115 * |
163 * |
116 * @param methods the list of methods |
164 * @param methods the list of methods |
117 * @param varArgs whether to assume the methods are varargs |
165 * @param varArgs whether to assume the methods are varargs |
118 * @param argTypes concrete argument types for the invocation |
166 * @param argTypes concrete argument types for the invocation |
119 * @return the list of maximally specific methods. |
167 * @return the list of maximally specific methods. |
120 */ |
168 */ |
121 static List<MethodHandle> getMaximallySpecificMethods(List<MethodHandle> methods, boolean varArgs, |
169 private static <T> List<T> getMaximallySpecificMethods(List<T> methods, boolean varArgs, |
122 Class<?>[] argTypes, LinkerServices ls) { |
170 Class<?>[] argTypes, LinkerServices ls, MethodTypeGetter<T> methodTypeGetter) { |
123 if(methods.size() < 2) { |
171 if(methods.size() < 2) { |
124 return methods; |
172 return methods; |
125 } |
173 } |
126 final LinkedList<MethodHandle> maximals = new LinkedList<>(); |
174 final LinkedList<T> maximals = new LinkedList<>(); |
127 for(MethodHandle m: methods) { |
175 for(T m: methods) { |
128 final MethodType methodType = m.type(); |
176 final MethodType methodType = methodTypeGetter.getMethodType(m); |
129 boolean lessSpecific = false; |
177 boolean lessSpecific = false; |
130 for(Iterator<MethodHandle> maximal = maximals.iterator(); maximal.hasNext();) { |
178 for(Iterator<T> maximal = maximals.iterator(); maximal.hasNext();) { |
131 final MethodHandle max = maximal.next(); |
179 final T max = maximal.next(); |
132 switch(isMoreSpecific(methodType, max.type(), varArgs, argTypes, ls)) { |
180 switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) { |
133 case TYPE_1_BETTER: { |
181 case TYPE_1_BETTER: { |
134 maximal.remove(); |
182 maximal.remove(); |
135 break; |
183 break; |
136 } |
184 } |
137 case TYPE_2_BETTER: { |
185 case TYPE_2_BETTER: { |