Generate bridges for property accessors
Use existing FunctionCodegen.generateBridgeIfNeeded() on property getters & setters #KT-2920 Fixed
This commit is contained in:
@@ -53,12 +53,14 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
|||||||
public class PropertyCodegen extends GenerationStateAware {
|
public class PropertyCodegen extends GenerationStateAware {
|
||||||
private final FunctionCodegen functionCodegen;
|
private final FunctionCodegen functionCodegen;
|
||||||
private final ClassBuilder v;
|
private final ClassBuilder v;
|
||||||
|
private final CodegenContext context;
|
||||||
private final OwnerKind kind;
|
private final OwnerKind kind;
|
||||||
|
|
||||||
public PropertyCodegen(CodegenContext context, ClassBuilder v, FunctionCodegen functionCodegen) {
|
public PropertyCodegen(CodegenContext context, ClassBuilder v, FunctionCodegen functionCodegen) {
|
||||||
super(functionCodegen.getState());
|
super(functionCodegen.getState());
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.functionCodegen = functionCodegen;
|
this.functionCodegen = functionCodegen;
|
||||||
|
this.context = context;
|
||||||
this.kind = context.getContextKind();
|
this.kind = context.getContextKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,20 +121,17 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateGetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
private void generateGetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
||||||
final JetPropertyAccessor getter = p.getGetter();
|
JetPropertyAccessor getter = p.getGetter();
|
||||||
if (getter != null) {
|
if (getter != null && getter.getBodyExpression() != null) {
|
||||||
if (getter.getBodyExpression() != null) {
|
JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind);
|
||||||
JvmPropertyAccessorSignature signature =
|
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
||||||
typeMapper.mapGetterSignature(propertyDescriptor, kind);
|
propertyDescriptor.getGetter());
|
||||||
functionCodegen.generateMethod(getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
|
||||||
propertyDescriptor.getGetter());
|
|
||||||
}
|
|
||||||
else if (isExternallyAccessible(propertyDescriptor)) {
|
|
||||||
generateDefaultGetter(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isExternallyAccessible(propertyDescriptor)) {
|
else if (isExternallyAccessible(propertyDescriptor)) {
|
||||||
generateDefaultGetter(p);
|
generateDefaultGetter(p);
|
||||||
|
JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind);
|
||||||
|
FunctionCodegen.generateBridgeIfNeeded(context, state, v, signature.getJvmMethodSignature().getAsmMethod(),
|
||||||
|
propertyDescriptor.getGetter(), kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,22 +141,17 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
||||||
final JetPropertyAccessor setter = p.getSetter();
|
JetPropertyAccessor setter = p.getSetter();
|
||||||
if (setter != null) {
|
if (setter != null && setter.getBodyExpression() != null) {
|
||||||
if (setter.getBodyExpression() != null) {
|
JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind);
|
||||||
final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
|
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
||||||
assert setterDescriptor != null;
|
propertyDescriptor.getSetter());
|
||||||
JvmPropertyAccessorSignature signature =
|
|
||||||
typeMapper.mapSetterSignature(propertyDescriptor, kind);
|
|
||||||
functionCodegen.generateMethod(setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(),
|
|
||||||
setterDescriptor);
|
|
||||||
}
|
|
||||||
else if (isExternallyAccessible(propertyDescriptor)) {
|
|
||||||
generateDefaultSetter(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isExternallyAccessible(propertyDescriptor) && propertyDescriptor.isVar()) {
|
else if (isExternallyAccessible(propertyDescriptor) && propertyDescriptor.isVar()) {
|
||||||
generateDefaultSetter(p);
|
generateDefaultSetter(p);
|
||||||
|
JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind);
|
||||||
|
FunctionCodegen.generateBridgeIfNeeded(context, state, v, signature.getJvmMethodSignature().getAsmMethod(),
|
||||||
|
propertyDescriptor.getSetter(), kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
open class A<T> {
|
||||||
|
open var x: T = "Fail" as T
|
||||||
|
get
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A<String>() {
|
||||||
|
override var x: String = "Fail"
|
||||||
|
set
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a: A<String> = B()
|
||||||
|
a.x = "OK"
|
||||||
|
return a.x
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
trait A<O, K> {
|
||||||
|
val o: O
|
||||||
|
val k: K
|
||||||
|
}
|
||||||
|
|
||||||
|
trait B<K> : A<String, K>
|
||||||
|
|
||||||
|
trait C<O> : A<O, String>
|
||||||
|
|
||||||
|
class D : B<String>, C<String> {
|
||||||
|
override val o = "O"
|
||||||
|
override val k = "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a: A<String, String> = D()
|
||||||
|
return a.o + a.k
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
trait A<T> {
|
||||||
|
var v: T
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A<String> {
|
||||||
|
override var v: String = "Fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a: A<String> = B()
|
||||||
|
a.v = "OK"
|
||||||
|
return a.v
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
open class A<T>(val t: T) {
|
||||||
|
open val foo: T = t
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B : A<String>("Fail")
|
||||||
|
|
||||||
|
class Z : B() {
|
||||||
|
override val foo = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box() = (Z() : A<String>).foo
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
trait Tr<T> {
|
||||||
|
val v: T
|
||||||
|
}
|
||||||
|
|
||||||
|
class C : Tr<String> {
|
||||||
|
override val v = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = C().v
|
||||||
@@ -149,4 +149,29 @@ public class BridgeMethodGenTest extends CodegenTestCase {
|
|||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt2702.kt");
|
blackBoxFile("regressions/kt2702.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt2920() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("regressions/kt2920.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSubstitutionInSuperClassProperty() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/substitutionInSuperClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPropertySetter() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/propertySetter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPropertyDiamond() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/propertyDiamond.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPropertyAccessorsWithoutBody() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("bridges/propertyAccessorsWithoutBody.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user