JS backend: Fix Delegate property - use new CallTranslator

This commit is contained in:
Erokhin Stanislav
2013-12-26 18:26:23 +04:00
parent 42437eb755
commit 46a045f969
5 changed files with 29 additions and 45 deletions
@@ -55,7 +55,6 @@ public final class Namer {
private static final String DELEGATE_POSTFIX = "$delegate";
private static final String PROPERTY_METADATA = "PropertyMetadata";
@NotNull
public static String getReceiverParameterName() {
@@ -231,11 +230,6 @@ public final class Namer {
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
}
@NotNull
public JsNameRef propertyMetadataRef() {
return new JsNameRef(PROPERTY_METADATA, kotlinObject());
}
@NotNull
private JsNameRef kotlin(@NotNull JsName name) {
return new JsNameRef(name, kotlinObject());
@@ -129,7 +129,7 @@ public class TranslationContext {
}
@NotNull
public TranslationContext innerContextWithThisAliased(@NotNull DeclarationDescriptor correspondingDescriptor, @NotNull JsNameRef alias) {
public TranslationContext innerContextWithAliased(@NotNull DeclarationDescriptor correspondingDescriptor, @NotNull JsNameRef alias) {
return new TranslationContext(this, aliasingContext.inner(correspondingDescriptor, alias));
}
@@ -29,13 +29,10 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.expression.FunctionTranslator;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.reference.CallBuilder;
import org.jetbrains.k2js.translate.reference.CallType;
import org.jetbrains.k2js.translate.reference.ReferencePackage;
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.k2js.translate.context.Namer.getDelegateNameRef;
@@ -135,21 +132,6 @@ public final class PropertyTranslator extends AbstractTranslator {
return generateDefaultAccessor(getterDescriptor, generateDefaultGetterFunction(getterDescriptor));
}
private JsExpression createPropertyMetadata() {
JsNameRef propertyMetadataRef = context().namer().propertyMetadataRef();
JsExpression argument = context().program().getStringLiteral(getPropertyName());
return new JsNew(propertyMetadataRef, Collections.singletonList(argument));
}
private JsExpression getDelegateCall(ResolvedCall<FunctionDescriptor> call, List<JsExpression> args) {
return CallBuilder.build(context())
.receiver(getDelegateNameRef(getPropertyName()))
.args(args)
.resolvedCall(call)
.type(CallType.NORMAL)
.translate();
}
private String getPropertyName() {
return descriptor.getName().asString();
}
@@ -159,24 +141,13 @@ public final class PropertyTranslator extends AbstractTranslator {
JsExpression value;
ResolvedCall<FunctionDescriptor> delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor);
if (delegatedCall != null) {
value = getDelegateCall(delegatedCall, getDelegateCallArgs(null));
value = ReferencePackage.buildCall(context(), delegatedCall, getDelegateNameRef(getPropertyName()));
} else {
value = backingFieldReference(context(), this.descriptor);
}
return simpleReturnFunction(context().getScopeForDescriptor(getterDescriptor.getContainingDeclaration()), value);
}
@NotNull
private List<JsExpression> getDelegateCallArgs(@Nullable JsExpression valueExpression) {
List<JsExpression> args = new ArrayList<JsExpression>();
args.add(JsLiteral.THIS);
args.add(createPropertyMetadata());
if (valueExpression != null) {
args.add(valueExpression);
}
return args;
}
@NotNull
private JsPropertyInitializer generateDefaultSetter() {
PropertySetterDescriptor setterDescriptor = descriptor.getSetter();
@@ -187,16 +158,22 @@ public final class PropertyTranslator extends AbstractTranslator {
@NotNull
private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor setterDescriptor) {
JsFunction fun = new JsFunction(context().getScopeForDescriptor(setterDescriptor.getContainingDeclaration()));
JsParameter defaultParameter = new JsParameter(fun.getScope().declareTemporary());
fun.getParameters().add(defaultParameter);
JsExpression setExpression;
ResolvedCall<FunctionDescriptor> delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor);
assert setterDescriptor.getValueParameters().size() == 1 : "Setter must have 1 parameter";
ValueParameterDescriptor valueParameterDescriptor = setterDescriptor.getValueParameters().get(0);
JsParameter defaultParameter = new JsParameter(fun.getScope().declareTemporary());
JsNameRef defaultParameterRef = defaultParameter.getName().makeRef();
fun.getParameters().add(defaultParameter);
TranslationContext contextWithAliased = context().innerContextWithAliased(valueParameterDescriptor, defaultParameterRef);
JsExpression setExpression;
ResolvedCall<FunctionDescriptor> delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL,
setterDescriptor);
if (delegatedCall != null) {
setExpression = getDelegateCall(delegatedCall, getDelegateCallArgs(defaultParameterRef));
setExpression = ReferencePackage.buildCall(contextWithAliased, delegatedCall, getDelegateNameRef(getPropertyName()));
} else {
setExpression = assignmentToBackingField(context(), descriptor, defaultParameterRef);
setExpression = assignmentToBackingField(contextWithAliased, descriptor, defaultParameterRef);
}
fun.setBody(new JsBlock(setExpression.makeStmt()));
return fun;
@@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
@@ -119,6 +120,17 @@ public final class TopLevelFIF extends CompositeFIF {
}
};
private static final FunctionIntrinsic PROPERTY_METADATA_IMPL = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(
@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments, @NotNull TranslationContext context
) {
JsNameRef functionRef = new JsNameRef("PropertyMetadata", Namer.KOTLIN_NAME);
return new JsNew(functionRef, arguments);
}
};
@NotNull
public static final KotlinFunctionIntrinsic TO_STRING = new KotlinFunctionIntrinsic("toString");
@@ -132,6 +144,7 @@ public final class TopLevelFIF extends CompositeFIF {
add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), EQUALS);
add(pattern("String|Boolean|Char|Number.equals"), EQUALS);
add(pattern("jet", "arrayOfNulls"), new KotlinFunctionIntrinsic("nullArray"));
add(pattern("jet", "PropertyMetadataImpl", "<init>"), PROPERTY_METADATA_IMPL);
add(pattern("jet", "iterator").receiverExists(), RETURN_RECEIVER_INTRINSIC);
add(pattern("jet", "Map", "get").checkOverridden(), NATIVE_MAP_GET);
@@ -137,7 +137,7 @@ public final class InlinedCallExpressionTranslator extends AbstractCallExpressio
TemporaryVariable aliasForReceiver = context().declareTemporary(aliasExpression);
assert descriptorToAlias != null;
TranslationContext newContext =
contextWithAliasForThisExpression.innerContextWithThisAliased(descriptorToAlias, aliasForReceiver.reference());
contextWithAliasForThisExpression.innerContextWithAliased(descriptorToAlias, aliasForReceiver.reference());
newContext.addStatementToCurrentBlock(aliasForReceiver.assignmentExpression().makeStmt());
return newContext;
}