下面列出了java.lang.invoke.MethodType#equals ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_Object() {
System.out.println("equals");
Object x = null;
MethodType instance = mt_viS;
boolean expResult = false;
boolean result = instance.equals(x);
assertEquals(expResult, result);
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_Object() {
System.out.println("equals");
Object x = null;
MethodType instance = mt_viS;
boolean expResult = false;
boolean result = instance.equals(x);
assertEquals(expResult, result);
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_Object() {
System.out.println("equals");
Object x = null;
MethodType instance = mt_viS;
boolean expResult = false;
boolean result = instance.equals(x);
assertEquals(expResult, result);
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_MethodType() {
System.out.println("equals");
MethodType that = mt_viS;
MethodType instance = mt_viS;
boolean expResult = true;
boolean result = instance.equals(that);
assertEquals(expResult, result);
}
boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
if (other.equals(this.callSiteType)) {
return true;
}
final MethodType type = type();
final int fnParamCount = getParamCount(type);
final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
if (isVarArg) {
return pickVarArg;
}
final int csParamCount = getParamCount(other);
final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
if (csIsVarArg && isApplyToCall()) {
return false; // apply2call function must be called with exact number of parameters
}
final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
// We must match all incoming parameters, including "this". "this" will usually be Object, but there
// are exceptions, e.g. when calling functions with primitive "this" in strict mode or through call/apply.
for(int i = 0; i < minParams; ++i) {
final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
if(!fnType.isEquivalentTo(csType)) {
return false;
}
}
// Must match any undefined parameters to Object type.
for(int i = minParams; i < fnParamCountNoCallee; ++i) {
if(!Type.typeFor(type.parameterType(i + thisThisIndex)).isEquivalentTo(Type.OBJECT)) {
return false;
}
}
return true;
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_MethodType() {
System.out.println("equals");
MethodType that = mt_viS;
MethodType instance = mt_viS;
boolean expResult = true;
boolean result = instance.equals(that);
assertEquals(expResult, result);
}
boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
if (other.equals(this.callSiteType)) {
return true;
}
final MethodType type = type();
final int fnParamCount = getParamCount(type);
final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
if (isVarArg) {
return pickVarArg;
}
final int csParamCount = getParamCount(other);
final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
// We must match all incoming parameters, including "this". "this" will usually be Object, but there
// are exceptions, e.g. when calling functions with primitive "this" in strict mode or through call/apply.
for(int i = 0; i < minParams; ++i) {
final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
if(!fnType.isEquivalentTo(csType)) {
return false;
}
}
// Must match any undefined parameters to Object type.
for(int i = minParams; i < fnParamCountNoCallee; ++i) {
if(!Type.typeFor(type.parameterType(i + thisThisIndex)).isEquivalentTo(Type.OBJECT)) {
return false;
}
}
return true;
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_MethodType() {
System.out.println("equals");
MethodType that = mt_viS;
MethodType instance = mt_viS;
boolean expResult = true;
boolean result = instance.equals(that);
assertEquals(expResult, result);
}
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
// we can not use MethodBuilder here, it will introduce a cycle when retro-weaving
Method method = context.method();
MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
MethodHandle endPoint = target;
if (!methodType.equals(target.type())) {
endPoint = endPoint.asType(methodType.insertParameterTypes(0, capturedTypes));
}
return new ConstantCallSite(MethodHandles.dropArguments(endPoint, 0, Object.class));
}
boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
if (other.equals(this.callSiteType)) {
return true;
}
final MethodType type = type();
final int fnParamCount = getParamCount(type);
final boolean isVarArg = fnParamCount == Integer.MAX_VALUE;
if (isVarArg) {
return pickVarArg;
}
final int csParamCount = getParamCount(other);
final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
if (csIsVarArg && isApplyToCall()) {
return false; // apply2call function must be called with exact number of parameters
}
final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
// We must match all incoming parameters, including "this". "this" will usually be Object, but there
// are exceptions, e.g. when calling functions with primitive "this" in strict mode or through call/apply.
for(int i = 0; i < minParams; ++i) {
final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
if(!fnType.isEquivalentTo(csType)) {
return false;
}
}
// Must match any undefined parameters to Object type.
for(int i = minParams; i < fnParamCountNoCallee; ++i) {
if(!Type.typeFor(type.parameterType(i + thisThisIndex)).isEquivalentTo(Type.OBJECT)) {
return false;
}
}
return true;
}
/**
* Test of equals method, of class MethodType.
*/
@Test
public void testEquals_MethodType() {
System.out.println("equals");
MethodType that = mt_viS;
MethodType instance = mt_viS;
boolean expResult = true;
boolean result = instance.equals(that);
assertEquals(expResult, result);
}
/**
* Make sure arguments are paired correctly, with respect to more parameters than declared,
* fewer parameters than declared and other things that JavaScript allows. This might involve
* creating collectors.
*
* Make sure arguments are paired correctly.
* @param methodHandle MethodHandle to adjust.
* @param callType MethodType of the call site.
* @param callerVarArg true if the caller is vararg, false otherwise, null if it should be inferred from the
* {@code callType}; basically, if the last parameter type of the call site is an array, it'll be considered a
* variable arity call site. These are ordinarily rare; Nashorn code generator creates variable arity call sites
* when the call has more than {@link LinkerCallSite#ARGLIMIT} parameters.
*
* @return method handle with adjusted arguments
*/
public static MethodHandle pairArguments(final MethodHandle methodHandle, final MethodType callType, final Boolean callerVarArg) {
final MethodType methodType = methodHandle.type();
if (methodType.equals(callType.changeReturnType(methodType.returnType()))) {
return methodHandle;
}
final int parameterCount = methodType.parameterCount();
final int callCount = callType.parameterCount();
final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
callType.parameterType(callCount - 1).isArray();
if (isCalleeVarArg) {
return isCallerVarArg ?
methodHandle :
MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
}
if (isCallerVarArg) {
return adaptHandleToVarArgCallSite(methodHandle, callCount);
}
if (callCount < parameterCount) {
final int missingArgs = parameterCount - callCount;
final Object[] fillers = new Object[missingArgs];
Arrays.fill(fillers, UNDEFINED);
if (isCalleeVarArg) {
fillers[missingArgs - 1] = ScriptRuntime.EMPTY_ARRAY;
}
return MH.insertArguments(
methodHandle,
parameterCount - missingArgs,
fillers);
}
if (callCount > parameterCount) {
final int discardedArgs = callCount - parameterCount;
final Class<?>[] discards = new Class<?>[discardedArgs];
Arrays.fill(discards, Object.class);
return MH.dropArguments(methodHandle, callCount - discardedArgs, discards);
}
return methodHandle;
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle composeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final boolean isVarArg = ScriptFunctionData.isVarArg(mh);
final int paramCount = isVarArg ? type.parameterCount() - 1 : type.parameterCount();
MethodType newType = MethodType.genericMethodType(paramCount, isVarArg);
if (ScriptFunctionData.needsCallee(mh)) {
newType = newType.changeParameterType(0, ScriptFunction.class);
}
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle composeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final boolean isVarArg = ScriptFunctionData.isVarArg(mh);
final int paramCount = isVarArg ? type.parameterCount() - 1 : type.parameterCount();
MethodType newType = MethodType.genericMethodType(paramCount, isVarArg);
if (ScriptFunctionData.needsCallee(mh)) {
newType = newType.changeParameterType(0, ScriptFunction.class);
}
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
protected MethodHandle composeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
MethodType newType = type.generic();
if (isVarArg(mh)) {
newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class);
}
if (needsCallee(mh)) {
newType = newType.changeParameterType(0, ScriptFunction.class);
}
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle makeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final MethodType newType = makeGenericType(type);
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle makeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final MethodType newType = makeGenericType(type);
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle makeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final MethodType newType = makeGenericType(type);
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle makeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final MethodType newType = makeGenericType(type);
return type.equals(newType) ? mh : mh.asType(newType);
}
/**
* Takes a method handle, and returns a potentially different method handle that can be used in
* {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}.
* The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into
* {@code Object} as well, except for the following ones:
* <ul>
* <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li>
* <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself
* (callee) as an argument.</li>
* </ul>
*
* @param mh the original method handle
*
* @return the new handle, conforming to the rules above.
*/
private static MethodHandle makeGenericMethod(final MethodHandle mh) {
final MethodType type = mh.type();
final MethodType newType = makeGenericType(type);
return type.equals(newType) ? mh : mh.asType(newType);
}