Some solution for the case when a property which is a function is called.

This commit is contained in:
pTalanov
2012-03-14 16:51:08 +04:00
committed by Pavel V. Talanov
parent 94f80b23fb
commit ad49ac158d
7 changed files with 79 additions and 14 deletions
@@ -85,9 +85,15 @@ public final class MiscTest extends AbstractExpressionTest {
checkFooBoxIsTrue("KT-817.kt");
}
//TODO: depends on KT-1198
//TODO: look into BindingContext.VARIABLE_REASSIGNMENT
public void testKt740_3() throws Exception {
checkFooBoxIsOk("KT-740-3.kt");
}
public void testFunInConstructor() throws Exception {
checkFooBoxIsTrue("funInConstructor.kt");
}
public void testPropertyAsFunCalledOnConstructor() throws Exception {
checkFooBoxIsTrue("propertyAsFunCalledOnConstructor.kt");
}
}
@@ -50,7 +50,7 @@ public final class AccessTranslationUtils {
}
@NotNull
public static JsExpression translateAsGet(@NotNull JetReferenceExpression expression,
public static JsExpression translateAsGet(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
return (getAccessTranslator(expression, context)).translateAsGet();
}
@@ -21,9 +21,12 @@ import com.google.dart.compiler.backend.js.ast.JsArrayLiteral;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableAsFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.calls.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -48,7 +51,7 @@ public final class CallExpressionTranslator extends AbstractTranslator {
@Nullable JsExpression receiver,
@NotNull CallType callType,
@NotNull TranslationContext context) {
return (new CallExpressionTranslator(expression, context)).translate(receiver, callType);
return (new CallExpressionTranslator(expression, receiver, context)).translate(callType);
}
@NotNull
@@ -56,18 +59,21 @@ public final class CallExpressionTranslator extends AbstractTranslator {
@NotNull
private final ResolvedCall<?> resolvedCall;
private final boolean isNativeFunctionCall;
@Nullable
private final JsExpression receiver;
private CallExpressionTranslator(@NotNull JetCallExpression expression,
@Nullable JsExpression receiver,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.resolvedCall = getResolvedCallForCallExpression(bindingContext(), expression);
this.receiver = receiver;
this.isNativeFunctionCall = AnnotationsUtils.isNativeObject(resolvedCall.getCandidateDescriptor());
}
@NotNull
private JsExpression translate(@Nullable JsExpression receiver,
@NotNull CallType callType) {
private JsExpression translate(@NotNull CallType callType) {
return CallBuilder.build(context())
.receiver(receiver)
.callee(getCalleeExpression())
@@ -79,12 +85,28 @@ public final class CallExpressionTranslator extends AbstractTranslator {
@Nullable
private JsExpression getCalleeExpression() {
if (resolvedCall.getCandidateDescriptor() instanceof ExpressionAsFunctionDescriptor) {
return Translation.translateAsExpression(getCallee(expression), context());
CallableDescriptor candidateDescriptor = resolvedCall.getCandidateDescriptor();
if (candidateDescriptor instanceof ExpressionAsFunctionDescriptor) {
return translateExpressionAsFunction();
}
if (candidateDescriptor instanceof VariableAsFunctionDescriptor) {
return translateVariableAsFunction();
}
return null;
}
@NotNull
private JsExpression translateVariableAsFunction() {
JetExpression callee = getCallee(expression);
assert callee instanceof JetSimpleNameExpression;
return ReferenceTranslator.getAccessTranslator((JetSimpleNameExpression) callee, receiver, context()).translateAsGet();
}
@NotNull
private JsExpression translateExpressionAsFunction() {
return Translation.translateAsExpression(getCallee(expression), context());
}
@NotNull
private List<JsExpression> translateArguments() {
List<JsExpression> result = new ArrayList<JsExpression>();
@@ -96,9 +96,6 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
/*package*/ JsExpression translate() {
if (isExpressionAsFunction()) {
return expressionAsFunctionCall();
}
if (isIntrinsic()) {
return intrinsicInvocation();
}
@@ -114,6 +111,9 @@ public final class CallTranslator extends AbstractTranslator {
if (isExtensionFunction()) {
return extensionFunctionCall();
}
if (isExpressionAsFunction()) {
return expressionAsFunctionCall();
}
return methodCall(callParameters(resolveThisObject(/*just get qualifier if null*/ true)));
}
@@ -274,6 +274,7 @@ public final class CallTranslator extends AbstractTranslator {
return new CallParameters(receiver, functionReference);
}
//TODO: inspect
@NotNull
private JsExpression functionReference() {
if (!isVariableAsFunction(descriptor)) {
@@ -19,6 +19,7 @@ package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -58,13 +59,21 @@ public final class ReferenceTranslator {
return referencedName.makeRef();
}
public static AccessTranslator getAccessTranslator(JetSimpleNameExpression referenceExpression, TranslationContext context) {
@NotNull
public static AccessTranslator getAccessTranslator(@NotNull JetSimpleNameExpression referenceExpression,
@NotNull TranslationContext context) {
return getAccessTranslator(referenceExpression, null, context);
}
@NotNull
public static AccessTranslator getAccessTranslator(@NotNull JetSimpleNameExpression referenceExpression,
@Nullable JsExpression receiver,
@NotNull TranslationContext context) {
if (isBackingFieldReference(referenceExpression)) {
return BackingFieldAccessTranslator.newInstance(referenceExpression, context);
}
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
return PropertyAccessTranslator.newInstance(referenceExpression,
null, CallType.NORMAL, context);
return PropertyAccessTranslator.newInstance(referenceExpression, receiver, CallType.NORMAL, context);
}
return ReferenceAccessTranslator.newInstance(referenceExpression, context);
}
@@ -0,0 +1,17 @@
package foo
class A() {
fun lold() = true
val p = {{lold()}()}
}
fun box() : Boolean {
return A().p()
}
fun main(arg : Array<String>) {
println(box())
}
@@ -0,0 +1,10 @@
package foo
class A() {
val p = {true}
}
fun box() : Boolean {
return A().p()
}