Generate bridges for properties declared in constructor
#KT-2926 Fixed #KT-2833 Fixed
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user