Substitute superClassExpression with superCallClass in synthetic accessors

This commit is contained in:
Michael Bogdanov
2015-10-27 11:02:56 +03:00
parent 21d927b7a4
commit 0a70c80af3
8 changed files with 72 additions and 76 deletions
@@ -19,12 +19,12 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.psi.KtSuperExpression; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
public interface AccessorForCallableDescriptor<T extends CallableMemberDescriptor> { public interface AccessorForCallableDescriptor<T extends CallableMemberDescriptor> {
@NotNull @NotNull
T getCalleeDescriptor(); T getCalleeDescriptor();
@Nullable @Nullable
KtSuperExpression getSuperCallExpression(); ClassDescriptor getSuperCallTarget();
} }
@@ -18,14 +18,13 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
public class AccessorForConstructorDescriptor( public class AccessorForConstructorDescriptor(
private val calleeDescriptor: ConstructorDescriptor, private val calleeDescriptor: ConstructorDescriptor,
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
private val superCallExpression: KtSuperExpression? private val superCallTarget: ClassDescriptor?
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>")), ) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>")),
ConstructorDescriptor, ConstructorDescriptor,
AccessorForCallableDescriptor<ConstructorDescriptor> { AccessorForCallableDescriptor<ConstructorDescriptor> {
@@ -37,7 +36,7 @@ public class AccessorForConstructorDescriptor(
override fun getReturnType(): KotlinType = super.getReturnType()!! override fun getReturnType(): KotlinType = super.getReturnType()!!
override fun getSuperCallExpression(): KtSuperExpression? = superCallExpression override fun getSuperCallTarget(): ClassDescriptor? = superCallTarget
init { init {
initialize( initialize(
@@ -20,24 +20,23 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtSuperExpression;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDescriptor implements AccessorForCallableDescriptor<FunctionDescriptor> { public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDescriptor implements AccessorForCallableDescriptor<FunctionDescriptor> {
private final FunctionDescriptor calleeDescriptor; private final FunctionDescriptor calleeDescriptor;
private final KtSuperExpression superCallExpression; private final ClassDescriptor superCallTarget;
public AccessorForFunctionDescriptor( public AccessorForFunctionDescriptor(
@NotNull FunctionDescriptor descriptor, @NotNull FunctionDescriptor descriptor,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix @NotNull String nameSuffix
) { ) {
super(containingDeclaration, super(containingDeclaration,
Name.identifier("access$" + nameSuffix)); Name.identifier("access$" + nameSuffix));
this.calleeDescriptor = descriptor; this.calleeDescriptor = descriptor;
this.superCallExpression = superCallExpression; this.superCallTarget = superCallTarget;
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()), initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
descriptor instanceof ConstructorDescriptor || AnnotationUtilKt.isPlatformStaticInObjectOrClass(descriptor) descriptor instanceof ConstructorDescriptor || AnnotationUtilKt.isPlatformStaticInObjectOrClass(descriptor)
@@ -57,7 +56,7 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
} }
@Override @Override
public KtSuperExpression getSuperCallExpression() { public ClassDescriptor getSuperCallTarget() {
return superCallExpression; return superCallTarget;
} }
} }
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtSuperExpression;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
@@ -33,7 +32,7 @@ import java.util.Collections;
public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implements AccessorForCallableDescriptor<PropertyDescriptor> { public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implements AccessorForCallableDescriptor<PropertyDescriptor> {
private final PropertyDescriptor calleeDescriptor; private final PropertyDescriptor calleeDescriptor;
private final KtSuperExpression superCallExpression; private final ClassDescriptor superCallTarget;
@NotNull private final String nameSuffix; @NotNull private final String nameSuffix;
private final boolean withSyntheticGetterAccessor; private final boolean withSyntheticGetterAccessor;
private final boolean withSyntheticSetterAccessor; private final boolean withSyntheticSetterAccessor;
@@ -41,13 +40,13 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
public AccessorForPropertyDescriptor( public AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor property, @NotNull PropertyDescriptor property,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix, @NotNull String nameSuffix,
boolean getterAccessorRequired, boolean getterAccessorRequired,
boolean setterAccessorRequired boolean setterAccessorRequired
) { ) {
this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()), this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
property.getDispatchReceiverParameter(), containingDeclaration, superCallExpression, nameSuffix, property.getDispatchReceiverParameter(), containingDeclaration, superCallTarget, nameSuffix,
getterAccessorRequired, setterAccessorRequired); getterAccessorRequired, setterAccessorRequired);
} }
@@ -57,10 +56,10 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
@Nullable KotlinType receiverType, @Nullable KotlinType receiverType,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter, @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix @NotNull String nameSuffix
) { ) {
this(original, propertyType, receiverType, dispatchReceiverParameter, containingDeclaration, superCallExpression, nameSuffix, true, true); this(original, propertyType, receiverType, dispatchReceiverParameter, containingDeclaration, superCallTarget, nameSuffix, true, true);
} }
protected AccessorForPropertyDescriptor( protected AccessorForPropertyDescriptor(
@@ -69,7 +68,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
@Nullable KotlinType receiverType, @Nullable KotlinType receiverType,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter, @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix, @NotNull String nameSuffix,
boolean getterAccessorRequired, boolean getterAccessorRequired,
boolean setterAccessorRequired boolean setterAccessorRequired
@@ -79,7 +78,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
Kind.DECLARATION, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false); Kind.DECLARATION, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false);
this.calleeDescriptor = original; this.calleeDescriptor = original;
this.superCallExpression = superCallExpression; this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix; this.nameSuffix = nameSuffix;
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType); setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType);
@@ -109,10 +108,10 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getGetter(); return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getGetter();
} }
@Nullable
@Override @Override
public KtSuperExpression getSuperCallExpression() { @Nullable
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallExpression(); public ClassDescriptor getSuperCallTarget() {
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
} }
} }
@@ -133,10 +132,10 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getSetter(); return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getSetter();
} }
@Nullable
@Override @Override
public KtSuperExpression getSuperCallExpression() { @Nullable
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallExpression(); public ClassDescriptor getSuperCallTarget() {
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
} }
} }
@@ -147,8 +146,8 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
} }
@Override @Override
public KtSuperExpression getSuperCallExpression() { public ClassDescriptor getSuperCallTarget() {
return superCallExpression; return superCallTarget;
} }
@NotNull @NotNull
@@ -2008,15 +2008,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
} }
boolean directToField = isSyntheticField && contextKind() != OwnerKind.DEFAULT_IMPLS; boolean directToField = isSyntheticField && contextKind() != OwnerKind.DEFAULT_IMPLS;
KtSuperExpression superExpression = ClassDescriptor superCallTarget = resolvedCall == null ? null : getSuperCallTarget(resolvedCall.getCall());
resolvedCall == null ? null : CallResolverUtilKt.getSuperCallExpression(resolvedCall.getCall()); propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superExpression);
if (directToField) { if (directToField) {
receiver = StackValue.receiverWithoutReceiverArgument(receiver); receiver = StackValue.receiverWithoutReceiverArgument(receiver);
} }
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superExpression, false, receiver); return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superCallTarget, false, receiver);
} }
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
@@ -2056,6 +2055,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor); throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
} }
@Nullable
private ClassDescriptor getSuperCallTarget(@NotNull Call call) {
KtSuperExpression superExpression = CallResolverUtilKt.getSuperCallExpression(call);
return superExpression == null ? null : getSuperCallLabelTarget(context, superExpression);
}
@Nullable @Nullable
public StackValue findLocalOrCapturedValue(@NotNull DeclarationDescriptor descriptor) { public StackValue findLocalOrCapturedValue(@NotNull DeclarationDescriptor descriptor) {
int index = lookupLocalIndex(descriptor); int index = lookupLocalIndex(descriptor);
@@ -2134,10 +2139,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public StackValue.Property intermediateValueForProperty( public StackValue.Property intermediateValueForProperty(
@NotNull PropertyDescriptor propertyDescriptor, @NotNull PropertyDescriptor propertyDescriptor,
boolean forceField, boolean forceField,
@Nullable KtSuperExpression superExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull StackValue receiver @NotNull StackValue receiver
) { ) {
return intermediateValueForProperty(propertyDescriptor, forceField, false, superExpression, false, receiver); return intermediateValueForProperty(propertyDescriptor, forceField, false, superCallTarget, false, receiver);
} }
private CodegenContext getBackingFieldContext( private CodegenContext getBackingFieldContext(
@@ -2158,7 +2163,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull PropertyDescriptor propertyDescriptor, @NotNull PropertyDescriptor propertyDescriptor,
boolean forceField, boolean forceField,
boolean syntheticBackingField, boolean syntheticBackingField,
@Nullable KtSuperExpression superExpression, @Nullable ClassDescriptor superCallTarget,
boolean skipAccessorsForPrivateFieldInOuterClass, boolean skipAccessorsForPrivateFieldInOuterClass,
StackValue receiver StackValue receiver
) { ) {
@@ -2178,7 +2183,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
} }
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) || boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor); AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
boolean isSuper = superExpression != null; boolean isSuper = superCallTarget != null;
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null; boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
KotlinType delegateType = getPropertyDelegateType(propertyDescriptor, bindingContext); KotlinType delegateType = getPropertyDelegateType(propertyDescriptor, bindingContext);
@@ -2197,7 +2202,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (!skipPropertyAccessors) { if (!skipPropertyAccessors) {
//noinspection ConstantConditions //noinspection ConstantConditions
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor( propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(
propertyDescriptor, fieldAccessorKind, delegateType, superExpression propertyDescriptor, fieldAccessorKind, delegateType, superCallTarget
); );
assert propertyDescriptor instanceof AccessorForPropertyBackingField : assert propertyDescriptor instanceof AccessorForPropertyBackingField :
"Unexpected accessor descriptor: " + propertyDescriptor; "Unexpected accessor descriptor: " + propertyDescriptor;
@@ -2214,15 +2219,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (!skipPropertyAccessors) { if (!skipPropertyAccessors) {
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) { if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
if (isSuper && !isJvmInterface(containingDeclaration)) { if (isSuper && !isJvmInterface(containingDeclaration)) {
ClassDescriptor owner = getSuperCallLabelTarget(context, superExpression); CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
CodegenContext c = context.findParentContextWithDescriptor(owner);
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor; assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
if (c != context.getParentContext()) { if (c != context.getParentContext()) {
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superExpression); propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superCallTarget);
} }
} }
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superExpression); propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) { if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) {
@@ -2355,7 +2359,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// $default method is not private, so you need no accessor to call it // $default method is not private, so you need no accessor to call it
return usesDefaultArguments(resolvedCall) return usesDefaultArguments(resolvedCall)
? descriptor ? descriptor
: context.accessibleDescriptor(descriptor, CallResolverUtilKt.getSuperCallExpression(resolvedCall.getCall())); : context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
} }
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) { private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
@@ -2377,15 +2381,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull @NotNull
public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) { public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall); FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
KtSuperExpression superCallExpression = CallResolverUtilKt.getSuperCallExpression(call); ClassDescriptor superCallTarget = getSuperCallTarget(call);
boolean superCall = superCallExpression != null; boolean superCall = superCallTarget != null;
if (superCall && !isJvmInterface(fd.getContainingDeclaration())) { if (superCall && !isJvmInterface(fd.getContainingDeclaration())) {
ClassDescriptor owner = getSuperCallLabelTarget(context, superCallExpression); CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
CodegenContext c = context.findParentContextWithDescriptor(owner);
assert c != null : "Couldn't find a context for a super-call: " + fd; assert c != null : "Couldn't find a context for a super-call: " + fd;
if (c != context.getParentContext()) { if (c != context.getParentContext()) {
fd = (FunctionDescriptor) c.getAccessor(fd, superCallExpression); fd = (FunctionDescriptor) c.getAccessor(fd, superCallTarget);
} }
} }
@@ -639,7 +639,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration())) || syntheticBackingField; !isCompanionObject(accessor.getContainingDeclaration())) || syntheticBackingField;
StackValue property = codegen.intermediateValueForProperty( StackValue property = codegen.intermediateValueForProperty(
original, forceField, syntheticBackingField, accessor.getSuperCallExpression(), true, StackValue.none() original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), true, StackValue.none()
); );
InstructionAdapter iv = codegen.v; InstructionAdapter iv = codegen.v;
@@ -693,7 +693,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
CallableMethod callableMethod = typeMapper.mapToCallableMethod( CallableMethod callableMethod = typeMapper.mapToCallableMethod(
functionDescriptor, functionDescriptor,
accessorDescriptor instanceof AccessorForCallableDescriptor && accessorDescriptor instanceof AccessorForCallableDescriptor &&
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallExpression() != null ((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
); );
boolean isTopLevelDeclaration = isTopLevelDeclaration(functionDescriptor); boolean isTopLevelDeclaration = isTopLevelDeclaration(functionDescriptor);
@@ -64,7 +64,7 @@ class PlatformStaticGenerator(
} }
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod( val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
codegen.getContext().accessibleDescriptor(descriptor, /* superCallExpression = */ null), codegen.getContext().accessibleDescriptor(descriptor, /* superCallTarget = */ null),
false false
) )
syntheticOrOriginalMethod.genInvokeInstruction(iv) syntheticOrOriginalMethod.genInvokeInstruction(iv)
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtSuperExpression;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.LockBasedStorageManager;
@@ -88,7 +87,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private static class AccessorForPropertyDescriptorFactory { private static class AccessorForPropertyDescriptorFactory {
private final @NotNull PropertyDescriptor property; private final @NotNull PropertyDescriptor property;
private final @NotNull DeclarationDescriptor containingDeclaration; private final @NotNull DeclarationDescriptor containingDeclaration;
private final @Nullable KtSuperExpression superCallExpression; private final @Nullable ClassDescriptor superCallTarget;
private final @NotNull String nameSuffix; private final @NotNull String nameSuffix;
private AccessorForPropertyDescriptor withSyntheticGetterAndSetter = null; private AccessorForPropertyDescriptor withSyntheticGetterAndSetter = null;
@@ -98,12 +97,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
public AccessorForPropertyDescriptorFactory( public AccessorForPropertyDescriptorFactory(
@NotNull PropertyDescriptor property, @NotNull PropertyDescriptor property,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix @NotNull String nameSuffix
) { ) {
this.property = property; this.property = property;
this.containingDeclaration = containingDeclaration; this.containingDeclaration = containingDeclaration;
this.superCallExpression = superCallExpression; this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix; this.nameSuffix = nameSuffix;
} }
@@ -115,7 +114,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
else if (getterAccessorRequired && !setterAccessorRequired) { else if (getterAccessorRequired && !setterAccessorRequired) {
if (withSyntheticGetter == null) { if (withSyntheticGetter == null) {
withSyntheticGetter = new AccessorForPropertyDescriptor( withSyntheticGetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallExpression, nameSuffix, property, containingDeclaration, superCallTarget, nameSuffix,
true, false); true, false);
} }
return withSyntheticGetter; return withSyntheticGetter;
@@ -123,7 +122,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
else if (!getterAccessorRequired && setterAccessorRequired) { else if (!getterAccessorRequired && setterAccessorRequired) {
if (withSyntheticSetter == null) { if (withSyntheticSetter == null) {
withSyntheticSetter = new AccessorForPropertyDescriptor( withSyntheticSetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallExpression, nameSuffix, property, containingDeclaration, superCallTarget, nameSuffix,
false, true); false, true);
} }
return withSyntheticSetter; return withSyntheticSetter;
@@ -137,7 +136,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
public AccessorForPropertyDescriptor getOrCreateAccessorWithSyntheticGetterAndSetter() { public AccessorForPropertyDescriptor getOrCreateAccessorWithSyntheticGetterAndSetter() {
if (withSyntheticGetterAndSetter == null) { if (withSyntheticGetterAndSetter == null) {
withSyntheticGetterAndSetter = new AccessorForPropertyDescriptor( withSyntheticGetterAndSetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallExpression, nameSuffix, property, containingDeclaration, superCallTarget, nameSuffix,
true, true); true, true);
} }
return withSyntheticGetterAndSetter; return withSyntheticGetterAndSetter;
@@ -356,16 +355,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull @NotNull
private PropertyDescriptor getPropertyAccessor( private PropertyDescriptor getPropertyAccessor(
@NotNull PropertyDescriptor propertyDescriptor, @NotNull PropertyDescriptor propertyDescriptor,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
boolean getterAccessorRequired, boolean getterAccessorRequired,
boolean setterAccessorRequired boolean setterAccessorRequired
) { ) {
return getAccessor(propertyDescriptor, FieldAccessorKind.NORMAL, null, superCallExpression, getterAccessorRequired, setterAccessorRequired); return getAccessor(propertyDescriptor, FieldAccessorKind.NORMAL, null, superCallTarget, getterAccessorRequired, setterAccessorRequired);
} }
@NotNull @NotNull
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable KtSuperExpression superCallExpression) { public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallExpression); return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallTarget);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -374,11 +373,11 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull D possiblySubstitutedDescriptor, @NotNull D possiblySubstitutedDescriptor,
@NotNull FieldAccessorKind accessorKind, @NotNull FieldAccessorKind accessorKind,
@Nullable KotlinType delegateType, @Nullable KotlinType delegateType,
@Nullable KtSuperExpression superCallExpression @Nullable ClassDescriptor superCallTarget
) { ) {
// TODO this corresponds to default behavior for properties before fixing KT-9717. Is it Ok in general case? // TODO this corresponds to default behavior for properties before fixing KT-9717. Is it Ok in general case?
// Does not matter for other descriptor kinds. // Does not matter for other descriptor kinds.
return getAccessor(possiblySubstitutedDescriptor, accessorKind, delegateType, superCallExpression, return getAccessor(possiblySubstitutedDescriptor, accessorKind, delegateType, superCallTarget,
/* getterAccessorRequired */ true, /* getterAccessorRequired */ true,
/* setterAccessorRequired */ true); /* setterAccessorRequired */ true);
} }
@@ -389,7 +388,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull D possiblySubstitutedDescriptor, @NotNull D possiblySubstitutedDescriptor,
@NotNull FieldAccessorKind accessorKind, @NotNull FieldAccessorKind accessorKind,
@Nullable KotlinType delegateType, @Nullable KotlinType delegateType,
@Nullable KtSuperExpression superCallExpression, @Nullable ClassDescriptor superCallTarget,
boolean getterAccessorRequired, boolean getterAccessorRequired,
boolean setterAccessorRequired boolean setterAccessorRequired
) { ) {
@@ -401,10 +400,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
D descriptor = (D) possiblySubstitutedDescriptor.getOriginal(); D descriptor = (D) possiblySubstitutedDescriptor.getOriginal();
AccessorKey key = new AccessorKey( AccessorKey key = new AccessorKey(descriptor, superCallTarget);
descriptor,
superCallExpression == null ? null : ExpressionCodegen.getSuperCallLabelTarget(this, superCallExpression)
);
// NB should check for property accessor factory first (or change property accessor tracking under propertyAccessorFactory creation) // NB should check for property accessor factory first (or change property accessor tracking under propertyAccessorFactory creation)
AccessorForPropertyDescriptorFactory propertyAccessorFactory = propertyAccessorFactories.get(key); AccessorForPropertyDescriptorFactory propertyAccessorFactory = propertyAccessorFactories.get(key);
@@ -420,18 +416,18 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, accessorKind); String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, accessorKind);
if (descriptor instanceof SimpleFunctionDescriptor) { if (descriptor instanceof SimpleFunctionDescriptor) {
accessor = new AccessorForFunctionDescriptor( accessor = new AccessorForFunctionDescriptor(
(FunctionDescriptor) descriptor, contextDescriptor, superCallExpression, nameSuffix (FunctionDescriptor) descriptor, contextDescriptor, superCallTarget, nameSuffix
); );
} }
else if (descriptor instanceof ConstructorDescriptor) { else if (descriptor instanceof ConstructorDescriptor) {
accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallExpression); accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallTarget);
} }
else if (descriptor instanceof PropertyDescriptor) { else if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
switch (accessorKind) { switch (accessorKind) {
case NORMAL: case NORMAL:
propertyAccessorFactory = new AccessorForPropertyDescriptorFactory((PropertyDescriptor) descriptor, contextDescriptor, propertyAccessorFactory = new AccessorForPropertyDescriptorFactory((PropertyDescriptor) descriptor, contextDescriptor,
superCallExpression, nameSuffix); superCallTarget, nameSuffix);
propertyAccessorFactories.put(key, propertyAccessorFactory); propertyAccessorFactories.put(key, propertyAccessorFactory);
// Record worst case accessor for accessor methods generation. // Record worst case accessor for accessor methods generation.
@@ -511,7 +507,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull @NotNull
public <D extends CallableMemberDescriptor> D accessibleDescriptor( public <D extends CallableMemberDescriptor> D accessibleDescriptor(
@NotNull D descriptor, @NotNull D descriptor,
@Nullable KtSuperExpression superCallExpression @Nullable ClassDescriptor superCallTarget
) { ) {
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration(); DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
if (!isInlineMethodContext() && ( if (!isInlineMethodContext() && (
@@ -521,13 +517,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return descriptor; return descriptor;
} }
return accessibleDescriptorIfNeeded(descriptor, superCallExpression); return accessibleDescriptorIfNeeded(descriptor, superCallTarget);
} }
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) { public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
if (hasThisDescriptor() && Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor))) { if (hasThisDescriptor() && Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor))) {
// Not a super call because neither constructors nor private members can be targets of super calls // Not a super call because neither constructors nor private members can be targets of super calls
accessibleDescriptorIfNeeded(descriptor, /* superCallExpression = */ null); accessibleDescriptorIfNeeded(descriptor, /* superCallTarget = */ null);
} }
} }
@@ -535,7 +531,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull @NotNull
private <D extends CallableMemberDescriptor> D accessibleDescriptorIfNeeded( private <D extends CallableMemberDescriptor> D accessibleDescriptorIfNeeded(
@NotNull D descriptor, @NotNull D descriptor,
@Nullable KtSuperExpression superCallExpression @Nullable ClassDescriptor superCallTarget
) { ) {
CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor); CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor);
@@ -569,14 +565,14 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (!getterAccessorRequired && !setterAccessorRequired) { if (!getterAccessorRequired && !setterAccessorRequired) {
return descriptor; return descriptor;
} }
return (D) descriptorContext.getPropertyAccessor(propertyDescriptor, superCallExpression, getterAccessorRequired, setterAccessorRequired); return (D) descriptorContext.getPropertyAccessor(propertyDescriptor, superCallTarget, getterAccessorRequired, setterAccessorRequired);
} }
else { else {
int flag = getVisibilityAccessFlag(unwrappedDescriptor); int flag = getVisibilityAccessFlag(unwrappedDescriptor);
if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext)) { if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext)) {
return descriptor; return descriptor;
} }
return (D) descriptorContext.getAccessor(descriptor, superCallExpression); return (D) descriptorContext.getAccessor(descriptor, superCallTarget);
} }
} }