82 */ |
82 */ |
83 |
83 |
84 package jdk.internal.dynalink.beans; |
84 package jdk.internal.dynalink.beans; |
85 |
85 |
86 import java.lang.invoke.MethodHandle; |
86 import java.lang.invoke.MethodHandle; |
87 import java.lang.invoke.MethodType; |
87 import jdk.internal.dynalink.CallSiteDescriptor; |
88 import java.util.StringTokenizer; |
|
89 import jdk.internal.dynalink.linker.LinkerServices; |
88 import jdk.internal.dynalink.linker.LinkerServices; |
90 |
89 |
91 /** |
90 /** |
92 * Represents a single dynamic method. A "dynamic" method can be bound to a single Java method, or can be bound to all |
91 * Represents a single dynamic method. A "dynamic" method can be bound to a single Java method, or can be bound to all |
93 * overloaded methods of the same name on a class. Getting an invocation of a dynamic method bound to multiple |
92 * overloaded methods of the same name on a class. Getting an invocation of a dynamic method bound to multiple |
114 * invoked among the overloads, or it can identify multiple ones. In the latter case, the returned method handle |
113 * invoked among the overloads, or it can identify multiple ones. In the latter case, the returned method handle |
115 * will perform further overload resolution among these candidates at every invocation. If the method to be invoked |
114 * will perform further overload resolution among these candidates at every invocation. If the method to be invoked |
116 * is a variable arguments (vararg) method, it will pack the extra arguments in an array before the invocation of |
115 * is a variable arguments (vararg) method, it will pack the extra arguments in an array before the invocation of |
117 * the underlying method if it is not already done. |
116 * the underlying method if it is not already done. |
118 * |
117 * |
119 * @param callSiteType the method type at a call site |
118 * @param callSiteDescriptor the descriptor of the call site |
120 * @param linkerServices linker services. Used for language-specific type conversions. |
119 * @param linkerServices linker services. Used for language-specific type conversions. |
121 * @return an invocation suitable for calling the method from the specified call site. |
120 * @return an invocation suitable for calling the method from the specified call site. |
122 */ |
121 */ |
123 abstract MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices); |
122 abstract MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices); |
124 |
123 |
125 /** |
124 /** |
126 * Returns a simple dynamic method representing a single underlying Java method (possibly selected among several |
125 * Returns a single dynamic method representing a single underlying Java method (possibly selected among several |
127 * overloads) with formal parameter types exactly matching the passed signature. |
126 * overloads) with formal parameter types exactly matching the passed signature. |
128 * @param paramTypes the comma-separated list of requested parameter type names. The names will match both |
127 * @param paramTypes the comma-separated list of requested parameter type names. The names will match both |
129 * qualified and unqualified type names. |
128 * qualified and unqualified type names. |
130 * @return a simple dynamic method representing a single underlying Java method, or null if none of the Java methods |
129 * @return a single dynamic method representing a single underlying Java method, or null if none of the Java methods |
131 * behind this dynamic method exactly match the requested parameter types. |
130 * behind this dynamic method exactly match the requested parameter types. |
132 */ |
131 */ |
133 abstract SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes); |
132 abstract SingleDynamicMethod getMethodForExactParamTypes(String paramTypes); |
134 |
133 |
135 /** |
134 /** |
136 * True if this dynamic method already contains a method handle with an identical signature as the passed in method |
135 * True if this dynamic method already contains a method with an identical signature as the passed in method. |
137 * handle. |
136 * @param method the method to check |
138 * @param mh the method handle to check |
137 * @return true if it already contains an equivalent method. |
139 * @return true if it already contains an equivalent method handle. |
|
140 */ |
138 */ |
141 abstract boolean contains(MethodHandle mh); |
139 abstract boolean contains(SingleDynamicMethod method); |
142 |
|
143 static boolean typeMatchesDescription(String paramTypes, MethodType type) { |
|
144 final StringTokenizer tok = new StringTokenizer(paramTypes, ", "); |
|
145 for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver |
|
146 if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) { |
|
147 return false; |
|
148 } |
|
149 } |
|
150 return !tok.hasMoreTokens(); |
|
151 } |
|
152 |
|
153 private static boolean typeNameMatches(String typeName, Class<?> type) { |
|
154 final int lastDot = typeName.lastIndexOf('.'); |
|
155 final String fullTypeName = type.getCanonicalName(); |
|
156 return lastDot != -1 && fullTypeName.endsWith(typeName.substring(lastDot)) || typeName.equals(fullTypeName); |
|
157 } |
|
158 |
140 |
159 static String getClassAndMethodName(Class<?> clazz, String name) { |
141 static String getClassAndMethodName(Class<?> clazz, String name) { |
160 final String clazzName = clazz.getCanonicalName(); |
142 final String clazzName = clazz.getCanonicalName(); |
161 return (clazzName == null ? clazz.getName() : clazzName) + "." + name; |
143 return (clazzName == null ? clazz.getName() : clazzName) + "." + name; |
162 } |
144 } |