Generate bridges for delegates
This commit is contained in:
@@ -818,6 +818,8 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
iv.areturn(delegateMethod.getReturnType());
|
iv.areturn(delegateMethod.getReturnType());
|
||||||
endVisit(mv, "delegate method", descriptorToDeclaration(bindingContext, functionDescriptor));
|
endVisit(mv, "delegate method", descriptorToDeclaration(bindingContext, functionDescriptor));
|
||||||
|
|
||||||
|
generateBridgeIfNeeded(owner, state, v, jvmDelegateMethodSignature.getAsmMethod(), functionDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,17 +316,17 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.getName());
|
return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void genDelegate(PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) {
|
public void genDelegate(PropertyDescriptor delegate, PropertyDescriptor overridden, StackValue field) {
|
||||||
ClassDescriptor toClass = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration();
|
ClassDescriptor toClass = (ClassDescriptor) overridden.getContainingDeclaration();
|
||||||
|
|
||||||
JvmMethodSignature getterSignature =
|
functionCodegen.genDelegate(delegate.getGetter(), toClass, field,
|
||||||
typeMapper.mapGetterSignature(declaration.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature();
|
typeMapper.mapGetterSignature(delegate, OwnerKind.IMPLEMENTATION).getJvmMethodSignature(),
|
||||||
functionCodegen.genDelegate(declaration.getGetter(), toClass, field, getterSignature, getterSignature);
|
typeMapper.mapGetterSignature(overridden.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature());
|
||||||
|
|
||||||
if (declaration.isVar()) {
|
if (delegate.isVar()) {
|
||||||
JvmMethodSignature setterSignature =
|
functionCodegen.genDelegate(delegate.getSetter(), toClass, field,
|
||||||
typeMapper.mapSetterSignature(declaration.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature();
|
typeMapper.mapSetterSignature(delegate, OwnerKind.IMPLEMENTATION).getJvmMethodSignature(),
|
||||||
functionCodegen.genDelegate(declaration.getSetter(), toClass, field, setterSignature, setterSignature);
|
typeMapper.mapSetterSignature(overridden.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
trait A<T> {
|
||||||
|
fun foo(): T
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A<String> {
|
||||||
|
override fun foo() = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
class C(a: A<String>) : A<String> by a
|
||||||
|
|
||||||
|
fun box() = (C(B()) : A<String>).foo()
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
trait A<T> {
|
||||||
|
var result: T
|
||||||
|
}
|
||||||
|
|
||||||
|
class B(a: A<String>): A<String> by a
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val o = object : A<String> {
|
||||||
|
override var result = "Fail"
|
||||||
|
}
|
||||||
|
val b: A<String> = B(o)
|
||||||
|
b.result = "OK"
|
||||||
|
if (b.result != "OK") return "Fail"
|
||||||
|
return (b : A<String>).result
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
trait A<T> {
|
||||||
|
fun id(t: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B : A<String> {
|
||||||
|
override fun id(t: String) = t
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : B()
|
||||||
|
|
||||||
|
class D : A<String> by C()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val d = D()
|
||||||
|
if (d.id("") != "") return "Fail"
|
||||||
|
return (d : A<String>).id("OK")
|
||||||
|
}
|
||||||
@@ -30,6 +30,16 @@ public class BridgeMethodGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("regressions/kt1959.kt");
|
blackBoxFile("regressions/kt1959.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDelegation() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/delegation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDelegationProperty() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/delegationProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
public void testDelegationToTraitImpl() {
|
public void testDelegationToTraitImpl() {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("bridges/delegationToTraitImpl.kt");
|
blackBoxFile("bridges/delegationToTraitImpl.kt");
|
||||||
@@ -95,6 +105,11 @@ public class BridgeMethodGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("bridges/substitutionInSuperClass.kt");
|
blackBoxFile("bridges/substitutionInSuperClass.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testSubstitutionInSuperClassDelegation() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/substitutionInSuperClassDelegation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
public void testSubstitutionInSuperClassAbstractFun() {
|
public void testSubstitutionInSuperClassAbstractFun() {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("bridges/substitutionInSuperClassAbstractFun.kt");
|
blackBoxFile("bridges/substitutionInSuperClassAbstractFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user