From 8bfb2ddcce85024805a06174bcd55805feb7c83c Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 10 Oct 2012 20:24:31 +0400 Subject: [PATCH] Generate bridges for properties declared in constructor #KT-2926 Fixed #KT-2833 Fixed --- .../jet/codegen/ClassBodyCodegen.java | 7 +---- .../jet/codegen/PropertyCodegen.java | 27 +++++++++++-------- .../codegen/bridges/propertyInConstructor.kt | 11 ++++++++ .../testData/codegen/regressions/kt2833.kt | 17 ++++++++++++ .../jet/codegen/BridgeMethodGenTest.java | 10 +++++++ 5 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/codegen/bridges/propertyInConstructor.kt create mode 100644 compiler/testData/codegen/regressions/kt2833.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index b49bde17457..3135f4e8051 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -98,12 +98,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen { PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); if (propertyDescriptor != null) { if (!isAnnotation) { - propertyCodegen.generateBackingField(p, propertyDescriptor); - int accessFlags = getVisibilityAccessFlag(propertyDescriptor) | getModalityAccessFlag(propertyDescriptor); - propertyCodegen.generateDefaultGetter(propertyDescriptor, accessFlags, p); - if (propertyDescriptor.isVar()) { - propertyCodegen.generateDefaultSetter(propertyDescriptor, accessFlags, p); - } + propertyCodegen.generatePrimaryConstructorProperty(p, propertyDescriptor); } else { Type type = state.getTypeMapper().mapType(propertyDescriptor); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 58871f608a1..16d6742071d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -79,7 +79,16 @@ public class PropertyCodegen extends GenerationStateAware { generateSetter(p, propertyDescriptor); } - public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) { + public void generatePrimaryConstructorProperty(JetParameter p, PropertyDescriptor descriptor) { + generateBackingField(p, descriptor); + int accessFlags = getVisibilityAccessFlag(descriptor) | getModalityAccessFlag(descriptor); + generateDefaultGetter(descriptor, accessFlags, p); + if (descriptor.isVar()) { + generateDefaultSetter(descriptor, accessFlags, p); + } + } + + private void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) { //noinspection ConstantConditions if (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); @@ -125,10 +134,6 @@ public class PropertyCodegen extends GenerationStateAware { int flags = getVisibilityAccessFlag(propertyDescriptor); flags |= getModalityAccessFlag(propertyDescriptor); generateDefaultGetter(propertyDescriptor, flags, p); - - JvmPropertyAccessorSignature signature = typeMapper.mapGetterSignature(propertyDescriptor, kind); - FunctionCodegen.generateBridgeIfNeeded(context, state, v, signature.getJvmMethodSignature().getAsmMethod(), - propertyDescriptor.getGetter(), kind); } } @@ -149,14 +154,10 @@ public class PropertyCodegen extends GenerationStateAware { int flags = setterDescriptor == null ? getVisibilityAccessFlag(propertyDescriptor) : getVisibilityAccessFlag(setterDescriptor); flags |= getModalityAccessFlag(propertyDescriptor); generateDefaultSetter(propertyDescriptor, flags, p); - - JvmPropertyAccessorSignature signature = typeMapper.mapSetterSignature(propertyDescriptor, kind); - FunctionCodegen.generateBridgeIfNeeded(context, state, v, signature.getJvmMethodSignature().getAsmMethod(), - setterDescriptor, kind); } } - public void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { + private void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { checkMustGenerateCode(propertyDescriptor); if (kind == OwnerKind.TRAIT_IMPL) { @@ -225,6 +226,8 @@ public class PropertyCodegen extends GenerationStateAware { } } FunctionCodegen.endVisit(mv, "getter", origin); + + FunctionCodegen.generateBridgeIfNeeded(context, state, v, jvmMethodSignature.getAsmMethod(), getter, kind); } public static void generateJetPropertyAnnotation( @@ -245,7 +248,7 @@ public class PropertyCodegen extends GenerationStateAware { aw.visitEnd(); } - public void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { + private void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { checkMustGenerateCode(propertyDescriptor); if (kind == OwnerKind.TRAIT_IMPL) { @@ -315,6 +318,8 @@ public class PropertyCodegen extends GenerationStateAware { } } FunctionCodegen.endVisit(mv, "setter", origin); + + FunctionCodegen.generateBridgeIfNeeded(context, state, v, jvmMethodSignature.getAsmMethod(), setter, kind); } } diff --git a/compiler/testData/codegen/bridges/propertyInConstructor.kt b/compiler/testData/codegen/bridges/propertyInConstructor.kt new file mode 100644 index 00000000000..1bc200b1b5c --- /dev/null +++ b/compiler/testData/codegen/bridges/propertyInConstructor.kt @@ -0,0 +1,11 @@ +trait A { + var x: T +} + +class B(override var x: String) : A + +fun box(): String { + val a: A = B("Fail") + a.x = "OK" + return a.x +} diff --git a/compiler/testData/codegen/regressions/kt2833.kt b/compiler/testData/codegen/regressions/kt2833.kt new file mode 100644 index 00000000000..c5d90cbede8 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2833.kt @@ -0,0 +1,17 @@ +package test + +public trait FunDependencyEdge { + val from: FunctionNode +} + +public trait FunctionNode + +public class FunctionNodeImpl : FunctionNode + +class FunDependencyEdgeImpl(override val from: FunctionNodeImpl): FunDependencyEdge { +} + +fun box(): String { + (FunDependencyEdgeImpl(FunctionNodeImpl()) as FunDependencyEdge).from + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java index f42e8385f48..edfa98ced97 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/BridgeMethodGenTest.java @@ -174,4 +174,14 @@ public class BridgeMethodGenTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("bridges/propertyAccessorsWithoutBody.kt"); } + + public void testPropertyInConstructor() { + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + blackBoxFile("bridges/propertyInConstructor.kt"); + } + + public void testKt2833() { + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + blackBoxFile("regressions/kt2833.kt"); + } }