From 57fff8e554472b88dd6468b470732afe071c2e1b Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Fri, 6 Jan 2012 16:48:40 +0400 Subject: [PATCH] switch to using descriptors on call site default arguments support --- .idea/workspace.xml | 532 +++++++++--------- .../expression/FunctionTranslator.java | 1 + .../ClassInitializerTranslator.java | 1 + .../translate/reference/CallTranslator.java | 59 +- .../k2js/translate/utils/BindingUtils.java | 18 +- .../org/jetbrains/k2js/test/FunctionTest.java | 5 + .../function/cases/defaultParameters.kt | 15 + 7 files changed, 358 insertions(+), 273 deletions(-) create mode 100644 translator/testFiles/expression/function/cases/defaultParameters.kt diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1e385a19b81..1dc84af7d6f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -14,12 +14,30 @@ - - + - - + + + + + + + + + + + + + + + + + + + + + @@ -194,51 +212,43 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + - + - + + + + + + + + + + + + + + + + + + + @@ -271,6 +281,24 @@ + + + + + + + + + + + + + + + + + + @@ -280,66 +308,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + + + + + + + + @@ -347,37 +339,66 @@ - - + + - + + + + + + + + + + + + - - + + - + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + @@ -407,12 +428,6 @@ @@ -760,28 +781,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1045,6 +993,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1281,7 +1295,7 @@ - + @@ -1325,7 +1339,7 @@ @@ -1372,37 +1386,30 @@ - + - + - + - + - + - + - + - - - - - - - - + @@ -1414,74 +1421,81 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java index c958d036c98..26aaf337245 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java @@ -31,6 +31,7 @@ public final class FunctionTranslator extends AbstractTranslator { } //TODO: implement more generic and safe way + @NotNull private static final String RECEIVER_PARAMETER_NAME = "receiver"; @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java index 50197fc11fe..ea5d4c028ac 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java @@ -72,6 +72,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla @NotNull private List translateArguments(@NotNull JetDelegatorToSuperCall superCall) { + //TODO: use the same mechanism as in call translator return TranslationUtils.translateArgumentList(context(), superCall.getValueArguments()); } diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index 94c3a35b7b7..ca02c92901c 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -8,20 +8,20 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.DefaultValueArgument; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; +import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic; import org.jetbrains.k2js.translate.utils.DescriptorUtils; import org.jetbrains.k2js.translate.utils.TranslationUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import static com.google.dart.compiler.util.AstUtil.not; -import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; -import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForCallExpression; +import static org.jetbrains.k2js.translate.utils.BindingUtils.*; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getVariableDescriptorForVariableAsFunction; import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isConstructorDescriptor; import static org.jetbrains.k2js.translate.utils.PsiUtils.isInOrNotInOperation; @@ -35,6 +35,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.*; //TODO: write tests on calling backing fields as functions public final class CallTranslator extends AbstractTranslator { + @NotNull public static JsExpression translate(@NotNull JetUnaryExpression unaryExpression, @NotNull TranslationContext context) { JsExpression receiver = TranslationUtils.translateBaseExpression(context, unaryExpression); @@ -46,6 +47,7 @@ public final class CallTranslator extends AbstractTranslator { } //TODO: method too long + @NotNull public static JsExpression translate(@NotNull JetDotQualifiedExpression dotExpression, @NotNull TranslationContext context) { JsExpression receiver = translateReceiver(context, dotExpression); @@ -53,23 +55,55 @@ public final class CallTranslator extends AbstractTranslator { JetExpression selectorExpression = dotExpression.getSelectorExpression(); assert selectorExpression instanceof JetCallExpression; JetCallExpression callExpression = (JetCallExpression) selectorExpression; - List arguments = - translateArgumentList(context, callExpression.getValueArguments()); FunctionDescriptor descriptor = getFunctionDescriptorForCallExpression(context.bindingContext(), callExpression); + List arguments = translateArgumentsForCallExpression(callExpression, context); return translate(context, receiver, arguments, descriptor); } + @NotNull + private static List translateArgumentsForCallExpression(@NotNull JetCallExpression callExpression, + @NotNull TranslationContext context) { + List result = new ArrayList(); + ResolvedCall resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression); + Map formalToActualArguments = resolvedCall.getValueArguments(); + for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) { + JetExpression argument = getActualArgument(formalToActualArguments, parameterDescriptor, context); + result.add(Translation.translateAsExpression(argument, context)); + } + return result; + } + + @NotNull + private static JetExpression getActualArgument( + @NotNull Map formalToActualArguments, + @NotNull ValueParameterDescriptor parameterDescriptor, @NotNull TranslationContext context) { + ResolvedValueArgument actualArgument = formalToActualArguments.get(parameterDescriptor); + if (actualArgument instanceof DefaultValueArgument) { + assert parameterDescriptor.hasDefaultValue() : "Unsupplied parameter must have default value."; + JetParameter psiParameter = getParameterForDescriptor(context.bindingContext(), parameterDescriptor); + JetExpression defaultValue = psiParameter.getDefaultValue(); + assert defaultValue != null : "No default value found in PSI."; + return defaultValue; + } + List argumentExpressions = actualArgument.getArgumentExpressions(); + assert !argumentExpressions.isEmpty() : "Actual arguments must be supplied."; + assert argumentExpressions.size() == 1 : "Varargs not supported."; + return argumentExpressions.get(0); + } + + @NotNull public static JsExpression translate(@NotNull JetCallExpression callExpression, @NotNull TranslationContext context) { - DeclarationDescriptor descriptor = - getFunctionDescriptorForCallExpression(context.bindingContext(), callExpression); + FunctionDescriptor descriptor = + (FunctionDescriptor) getFunctionDescriptorForCallExpression(context.bindingContext(), callExpression); JsExpression receiver = getImplicitReceiver(context, descriptor); - List arguments = translateArgumentList(context, callExpression.getValueArguments()); - return translate(context, receiver, arguments, (FunctionDescriptor) descriptor); + List arguments = translateArgumentsForCallExpression(callExpression, context); + return translate(context, receiver, arguments, descriptor); } //TODO: refactor + @NotNull public static JsExpression translate(@NotNull JetBinaryExpression binaryExpression, @NotNull TranslationContext context) { JsExpression receiver = translateLeftExpression(context, binaryExpression); @@ -94,6 +128,7 @@ public final class CallTranslator extends AbstractTranslator { } } + @NotNull private static JsExpression translateAsInOperation(@NotNull TranslationContext context, @NotNull JsExpression receiver, @NotNull List arguments, diff --git a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index 1099d0288a6..9b5513a31d6 100644 --- a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -101,6 +101,14 @@ public final class BindingUtils { return (JetDeclaration) result; } + @NotNull + public static JetParameter getParameterForDescriptor(@NotNull BindingContext context, + @NotNull ValueParameterDescriptor descriptor) { + PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); + assert result instanceof JetParameter : "ValueParameterDescriptor should have corresponding JetParameter."; + return (JetParameter) result; + } + @NotNull public static List getSuperclassDescriptors(@NotNull BindingContext context, @NotNull JetClass classDeclaration) { @@ -224,14 +232,20 @@ public final class BindingUtils { @NotNull public static FunctionDescriptor getFunctionDescriptorForCallExpression(@NotNull BindingContext context, @NotNull JetCallExpression expression) { - JetExpression calleeExpression = PsiUtils.getCallee(expression); - ResolvedCall resolvedCall = getResolvedCall(context, calleeExpression); + ResolvedCall resolvedCall = getResolvedCallForCallExpression(context, expression); CallableDescriptor descriptor = getDescriptorForResolvedCall(resolvedCall); assert descriptor instanceof FunctionDescriptor : "Callee expression must have resolved call with descriptor of type FunctionDescriptor"; return (FunctionDescriptor) descriptor; } + @NotNull + public static ResolvedCall getResolvedCallForCallExpression(@NotNull BindingContext context, + @NotNull JetCallExpression expression) { + JetExpression calleeExpression = PsiUtils.getCallee(expression); + return getResolvedCall(context, calleeExpression); + } + @NotNull private static CallableDescriptor getDescriptorForResolvedCall(@NotNull ResolvedCall resolvedCall) { return resolvedCall.getCandidateDescriptor(); diff --git a/translator/test/org/jetbrains/k2js/test/FunctionTest.java b/translator/test/org/jetbrains/k2js/test/FunctionTest.java index 6ebb655307f..7059e6b60e2 100644 --- a/translator/test/org/jetbrains/k2js/test/FunctionTest.java +++ b/translator/test/org/jetbrains/k2js/test/FunctionTest.java @@ -64,6 +64,11 @@ public class FunctionTest extends AbstractExpressionTest { testFooBoxIsTrue("implicitItParameter.kt"); } + @Test + public void defaultParameters() throws Exception { + testFooBoxIsTrue("defaultParameters.kt"); + } + @Test public void kt921() throws Exception { checkOutput("KT-921.kt", ""); diff --git a/translator/testFiles/expression/function/cases/defaultParameters.kt b/translator/testFiles/expression/function/cases/defaultParameters.kt new file mode 100644 index 00000000000..73945d0780a --- /dev/null +++ b/translator/testFiles/expression/function/cases/defaultParameters.kt @@ -0,0 +1,15 @@ +package foo + + +fun f(a : Int = 2, b : Int = 3) = a + b + +fun box() : Boolean +{ + if (f(1,2) != 3) return false; + if (f(1,3) != 4) return false; + if (f(3) != 6) return false; + if (f() != 5) return false; + + return true; +} +