Make CGLIB Enhancer compatible with Kotlin 2.2.20+

This commit refines Enhancer#emitMethods to support the changes
introduced by https://youtrack.jetbrains.com/issue/KT-76667.

See gh-35487
This commit is contained in:
Juergen Hoeller 2025-10-01 19:14:14 +02:00 committed by Sébastien Deleuze
parent b3264ec2a8
commit 3e37279db6
1 changed files with 18 additions and 15 deletions

View File

@ -1278,31 +1278,34 @@ 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
// 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); e.checkcast(retType);
} }
} }
}
else { else {
e.load_args(); e.load_args();
e.super_invoke(method.getSignature()); e.super_invoke(method.getSignature());