Generate bridges for properties declared in constructor

#KT-2926 Fixed
 #KT-2833 Fixed
This commit is contained in:
Alexander Udalov
2012-10-10 20:24:31 +04:00
parent 5bc9291d61
commit 8bfb2ddcce
5 changed files with 55 additions and 17 deletions
@@ -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);
@@ -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);
}
}
@@ -0,0 +1,11 @@
trait A<T> {
var x: T
}
class B(override var x: String) : A<String>
fun box(): String {
val a: A<String> = B("Fail")
a.x = "OK"
return a.x
}
@@ -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"
}
@@ -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");
}
}