|
|
|
@ -1278,29 +1278,32 @@ public class Enhancer extends AbstractClassGenerator { |
|
|
|
Signature bridgeTarget = (Signature) bridgeToTarget.get(method.getSignature()); |
|
|
|
Signature bridgeTarget = (Signature) bridgeToTarget.get(method.getSignature()); |
|
|
|
if (bridgeTarget != null) { |
|
|
|
if (bridgeTarget != null) { |
|
|
|
// checkcast each argument against the target's argument types
|
|
|
|
// checkcast each argument against the target's argument types
|
|
|
|
for (int i = 0; i < bridgeTarget.getArgumentTypes().length; i++) { |
|
|
|
Type[] argTypes = method.getSignature().getArgumentTypes(); |
|
|
|
|
|
|
|
Type[] targetTypes = bridgeTarget.getArgumentTypes(); |
|
|
|
|
|
|
|
for (int i = 0; i < targetTypes.length; i++) { |
|
|
|
e.load_arg(i); |
|
|
|
e.load_arg(i); |
|
|
|
Type target = bridgeTarget.getArgumentTypes()[i]; |
|
|
|
Type argType = argTypes[i]; |
|
|
|
if (!target.equals(method.getSignature().getArgumentTypes()[i])) { |
|
|
|
Type target = targetTypes[i]; |
|
|
|
|
|
|
|
if (!target.equals(argType)) { |
|
|
|
|
|
|
|
if (!TypeUtils.isPrimitive(target)) { |
|
|
|
|
|
|
|
e.box(argType); |
|
|
|
|
|
|
|
} |
|
|
|
e.checkcast(target); |
|
|
|
e.checkcast(target); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
e.invoke_virtual_this(bridgeTarget); |
|
|
|
e.invoke_virtual_this(bridgeTarget); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Not necessary to cast if the target & bridge have the same return type.
|
|
|
|
Type retType = method.getSignature().getReturnType(); |
|
|
|
Type retType = method.getSignature().getReturnType(); |
|
|
|
// Not necessary to cast if the target & bridge have
|
|
|
|
Type target = bridgeTarget.getReturnType(); |
|
|
|
// the same return type.
|
|
|
|
if (!target.equals(retType)) { |
|
|
|
// (This conveniently includes void and primitive types,
|
|
|
|
if (!TypeUtils.isPrimitive(target)) { |
|
|
|
// which would fail if casted. It's not possible to
|
|
|
|
e.unbox(retType); |
|
|
|
// covariant from boxed to unbox (or vice versa), so no having
|
|
|
|
} |
|
|
|
// to box/unbox for bridges).
|
|
|
|
else { |
|
|
|
// TODO: It also isn't necessary to checkcast if the return is
|
|
|
|
e.checkcast(retType); |
|
|
|
// assignable from the target. (This would happen if a subclass
|
|
|
|
} |
|
|
|
// used covariant returns to narrow the return type within a bridge
|
|
|
|
|
|
|
|
// method.)
|
|
|
|
|
|
|
|
if (!retType.equals(bridgeTarget.getReturnType())) { |
|
|
|
|
|
|
|
e.checkcast(retType); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
|