Refactoring: property processing generalization
This commit is contained in:
@@ -1535,18 +1535,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
// descriptor = ((VariableAsFunctionDescriptor) descriptor).getVariableDescriptor();
|
||||
//}
|
||||
|
||||
IntrinsicMethod intrinsic = null;
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
|
||||
memberDescriptor = unwrapFakeOverride(memberDescriptor);
|
||||
|
||||
intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
|
||||
}
|
||||
if (intrinsic != null) {
|
||||
Type expectedType = expressionType(expression);
|
||||
return intrinsic.generate(this, v, expectedType, expression, Collections.<JetExpression>emptyList(), receiver, state);
|
||||
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
|
||||
if (intrinsic != null) {
|
||||
Type expectedType = expressionType(expression);
|
||||
return intrinsic.generate(this, v, expectedType, expression, Collections.<JetExpression>emptyList(), receiver, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assert descriptor != null;
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
|
||||
@@ -1699,22 +1699,25 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
boolean forceField,
|
||||
@Nullable JetSuperExpression superExpression
|
||||
) {
|
||||
boolean isSuper = superExpression != null;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
assert containingDeclaration != null;
|
||||
containingDeclaration = containingDeclaration.getOriginal();
|
||||
|
||||
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
||||
boolean isSuper = superExpression != null;
|
||||
boolean overridesTrait = isOverrideForTrait(propertyDescriptor);
|
||||
boolean isFakeOverride = propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
|
||||
|
||||
PropertyDescriptor initialDescriptor = propertyDescriptor;
|
||||
propertyDescriptor = initialDescriptor.getOriginal();
|
||||
boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context);
|
||||
boolean isInsideModule = isCallInsideSameModuleAsDeclared(propertyDescriptor, context);
|
||||
boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null;
|
||||
|
||||
Method getter = null;
|
||||
Method setter = null;
|
||||
|
||||
if (!forceField) {
|
||||
//noinspection ConstantConditions
|
||||
if (isInsideClass &&
|
||||
@@ -1744,87 +1747,69 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
|
||||
}
|
||||
|
||||
getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||
|
||||
if (propertyDescriptor.getGetter() == null) {
|
||||
getter = null;
|
||||
if (propertyDescriptor.getGetter() != null) {
|
||||
getter = typeMapper.
|
||||
mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).
|
||||
getJvmMethodSignature().getAsmMethod();
|
||||
}
|
||||
|
||||
if (getter == null && propertyDescriptor.getReceiverParameter() != null) {
|
||||
if (getter == null && isExtensionProperty) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
if (!propertyDescriptor.isVar() || isInsideClass && !isExtensionProperty &&
|
||||
(propertyDescriptor.getSetter() == null ||
|
||||
!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
|
||||
propertyDescriptor.getSetter().isDefault() &&
|
||||
propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
||||
setter = null;
|
||||
}
|
||||
else {
|
||||
JvmPropertyAccessorSignature jvmMethodSignature =
|
||||
typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null;
|
||||
|
||||
if (propertyDescriptor.getSetter() == null) {
|
||||
setter = null;
|
||||
if (propertyDescriptor.isVar()) {
|
||||
if (propertyDescriptor.getSetter() != null) {
|
||||
if (isInsideClass && !isExtensionProperty &&
|
||||
(!DescriptorUtils.isExternallyAccessible(propertyDescriptor) ||
|
||||
propertyDescriptor.getSetter().isDefault() &&
|
||||
propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
||||
setter = null;
|
||||
}
|
||||
else {
|
||||
setter = typeMapper.
|
||||
mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).
|
||||
getJvmMethodSignature().getAsmMethod();
|
||||
}
|
||||
}
|
||||
|
||||
if (setter == null && propertyDescriptor.isVar() && propertyDescriptor.getReceiverParameter() != null) {
|
||||
if (setter == null && isExtensionProperty) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getterInvokeOpcode;
|
||||
int setterInvokeOpcode;
|
||||
int getterInvokeOpcode = getOpcodeForPropertyDescriptorWithoutAccessor(propertyDescriptor);
|
||||
int setterInvokeOpcode = getterInvokeOpcode;
|
||||
|
||||
CallableMethod callableGetter = null;
|
||||
CallableMethod callableSetter = null;
|
||||
|
||||
if (getter != null) {
|
||||
callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, isInsideClass, isInsideModule, contextKind());
|
||||
getterInvokeOpcode = callableGetter.getInvokeOpcode();
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper, isInsideClass, isInsideModule, contextKind());
|
||||
setterInvokeOpcode = callableSetter.getInvokeOpcode();
|
||||
}
|
||||
|
||||
JvmClassName owner;
|
||||
JvmClassName ownerParam;
|
||||
boolean isInterface;
|
||||
if (isStatic) {
|
||||
isInterface = overridesTrait;
|
||||
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule);
|
||||
CallableMethod callableMethod = callableGetter != null ? callableGetter : callableSetter;
|
||||
|
||||
getterInvokeOpcode = INVOKESTATIC;
|
||||
setterInvokeOpcode = INVOKESTATIC;
|
||||
if (callableMethod == null) {
|
||||
owner = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule);
|
||||
}
|
||||
else {
|
||||
isInterface = isInterface(containingDeclaration) || overridesTrait;
|
||||
CallableMethod callableGetter = null;
|
||||
CallableMethod callableSetter = null;
|
||||
if (getter == null) {
|
||||
getterInvokeOpcode = getOpcodeForPropertyDescriptorWithoutAccessor(propertyDescriptor);
|
||||
}
|
||||
else {
|
||||
callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, isInsideClass, isInsideModule, contextKind());
|
||||
getterInvokeOpcode = callableGetter.getInvokeOpcode();
|
||||
}
|
||||
|
||||
if (setter == null) {
|
||||
setterInvokeOpcode = getOpcodeForPropertyDescriptorWithoutAccessor(propertyDescriptor);
|
||||
}
|
||||
else {
|
||||
callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper, isInsideClass, isInsideModule, contextKind());
|
||||
setterInvokeOpcode = callableSetter.getInvokeOpcode();
|
||||
}
|
||||
|
||||
CallableMethod callableMethod = callableGetter != null ? callableGetter : callableSetter;
|
||||
if (callableMethod == null) {
|
||||
owner = ownerParam = typeMapper.getOwner(propertyDescriptor, contextKind(), isInsideModule);
|
||||
}
|
||||
else {
|
||||
owner = isFakeOverride && !overridesTrait && !isInterface(initialDescriptor.getContainingDeclaration())
|
||||
? JvmClassName.byType(typeMapper.mapType(
|
||||
((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), JetTypeMapperMode.IMPL))
|
||||
: callableMethod.getOwner();
|
||||
ownerParam = callableMethod.getDefaultImplParam();
|
||||
}
|
||||
owner = isFakeOverride && !overridesTrait && !isInterface(initialDescriptor.getContainingDeclaration())
|
||||
? JvmClassName.byType(typeMapper.mapType(
|
||||
((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), JetTypeMapperMode.IMPL))
|
||||
: callableMethod.getOwner();
|
||||
}
|
||||
|
||||
return StackValue.property(propertyDescriptor, owner, ownerParam, asmType(propertyDescriptor.getType()),
|
||||
isStatic, isInterface, isSuper, getter, setter, getterInvokeOpcode, setterInvokeOpcode, state);
|
||||
return StackValue.property(propertyDescriptor, owner, asmType(propertyDescriptor.getType()),
|
||||
isStatic, getter, setter, getterInvokeOpcode, setterInvokeOpcode, state);
|
||||
}
|
||||
|
||||
private static int getOpcodeForPropertyDescriptorWithoutAccessor(PropertyDescriptor descriptor) {
|
||||
|
||||
@@ -1620,8 +1620,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
// @todo write directly to the field. Fix test excloset.jet::test6
|
||||
JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION, isCallInsideSameModuleAsDeclared(propertyDescriptor, codegen.context));
|
||||
Type propType = typeMapper.mapType(jetType);
|
||||
StackValue.property(propertyDescriptor, owner, owner,
|
||||
propType, false, false, false, null, null, 0, 0, state).store(propType, iv);
|
||||
StackValue.property(propertyDescriptor, owner,
|
||||
propType, false, null, null, 0, 0, state).store(propType, iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,18 +137,15 @@ public abstract class StackValue {
|
||||
public static Property property(
|
||||
PropertyDescriptor descriptor,
|
||||
JvmClassName methodOwner,
|
||||
JvmClassName methodOwnerParam,
|
||||
Type type,
|
||||
boolean isStatic,
|
||||
boolean isInterface,
|
||||
boolean isSuper,
|
||||
@Nullable Method getter,
|
||||
@Nullable Method setter,
|
||||
int getterInvokeOpcode,
|
||||
int setterInvokeOpcode,
|
||||
GenerationState state
|
||||
) {
|
||||
return new Property(descriptor, methodOwner, methodOwnerParam, getter, setter, isStatic, isInterface, isSuper, type, getterInvokeOpcode, setterInvokeOpcode,
|
||||
return new Property(descriptor, methodOwner, getter, setter, isStatic, type, getterInvokeOpcode, setterInvokeOpcode,
|
||||
state);
|
||||
}
|
||||
|
||||
@@ -866,11 +863,7 @@ public abstract class StackValue {
|
||||
private final Method setter;
|
||||
@NotNull
|
||||
public final JvmClassName methodOwner;
|
||||
@NotNull
|
||||
private final JvmClassName methodOwnerParam;
|
||||
|
||||
private final boolean isInterface;
|
||||
private final boolean isSuper;
|
||||
private final int getterInvokeOpcode;
|
||||
private final int setterInvokeOpcode;
|
||||
@NotNull
|
||||
@@ -879,17 +872,14 @@ public abstract class StackValue {
|
||||
private final GenerationState state;
|
||||
|
||||
public Property(
|
||||
@NotNull PropertyDescriptor descriptor, @NotNull JvmClassName methodOwner, @NotNull JvmClassName methodOwnerParam,
|
||||
@Nullable Method getter, @Nullable Method setter, boolean isStatic, boolean isInterface, boolean isSuper,
|
||||
@NotNull PropertyDescriptor descriptor, @NotNull JvmClassName methodOwner,
|
||||
@Nullable Method getter, @Nullable Method setter, boolean isStatic,
|
||||
@NotNull Type type, int getterInvokeOpcode, int setterInvokeOpcode, @NotNull GenerationState state
|
||||
) {
|
||||
super(type, isStatic);
|
||||
this.methodOwner = methodOwner;
|
||||
this.methodOwnerParam = methodOwnerParam;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.isInterface = isInterface;
|
||||
this.isSuper = isSuper;
|
||||
this.getterInvokeOpcode = getterInvokeOpcode;
|
||||
this.setterInvokeOpcode = setterInvokeOpcode;
|
||||
this.descriptor = descriptor;
|
||||
@@ -904,20 +894,13 @@ public abstract class StackValue {
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
if (isSuper && isInterface) {
|
||||
assert getter != null;
|
||||
v.visitMethodInsn(INVOKESTATIC, methodOwner.getInternalName(), getter.getName(),
|
||||
getter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor()));
|
||||
if (getter == null) {
|
||||
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, methodOwner.getInternalName(), descriptor.getName().getName(),
|
||||
this.type.getDescriptor());
|
||||
genNotNullAssertionForField(v, state, descriptor);
|
||||
}
|
||||
else {
|
||||
if (getter == null) {
|
||||
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, methodOwner.getInternalName(), descriptor.getName().getName(),
|
||||
this.type.getDescriptor());
|
||||
genNotNullAssertionForField(v, state, descriptor);
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(getterInvokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||
}
|
||||
v.visitMethodInsn(getterInvokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||
}
|
||||
coerceTo(type, v);
|
||||
}
|
||||
@@ -925,15 +908,9 @@ public abstract class StackValue {
|
||||
@Override
|
||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
if (isSuper && isInterface) {
|
||||
assert setter != null;
|
||||
v.visitMethodInsn(INVOKESTATIC, methodOwner.getInternalName(), setter.getName(),
|
||||
setter.getDescriptor().replace("(", "(" + methodOwnerParam.getDescriptor()));
|
||||
}
|
||||
else if (setter == null) {
|
||||
if (setter == null) {
|
||||
v.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, methodOwner.getInternalName(), descriptor.getName().getName(),
|
||||
this.type.getDescriptor());
|
||||
}
|
||||
this.type.getDescriptor()); }
|
||||
else {
|
||||
v.visitMethodInsn(setterInvokeOpcode, methodOwner.getInternalName(), setter.getName(), setter.getDescriptor());
|
||||
}
|
||||
|
||||
@@ -159,6 +159,9 @@ public class DescriptorUtils {
|
||||
@Nullable
|
||||
public static DeclarationDescriptor findTopLevelParent(@NotNull DeclarationDescriptor declarationDescriptor) {
|
||||
DeclarationDescriptor descriptor = declarationDescriptor;
|
||||
if (declarationDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
descriptor = ((PropertyAccessorDescriptor)descriptor).getCorrespondingProperty();
|
||||
}
|
||||
while (!(descriptor == null || isTopLevelDeclaration(descriptor))) {
|
||||
descriptor = descriptor.getContainingDeclaration();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user