KJS: support default arguments for expected declarations
This commit is contained in:
committed by
Alexander Udalov
parent
db4ce703a6
commit
e0245a9dc7
+23
-10
@@ -82,37 +82,50 @@ public final class FunctionBodyTranslator extends AbstractTranslator {
|
|||||||
@NotNull FunctionDescriptor descriptor,
|
@NotNull FunctionDescriptor descriptor,
|
||||||
@NotNull TranslationContext context
|
@NotNull TranslationContext context
|
||||||
) {
|
) {
|
||||||
List<ValueParameterDescriptor> originalParameters = descriptor.getValueParameters();
|
List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
|
||||||
List<ValueParameterDescriptor> valueParameters;
|
List<ValueParameterDescriptor> valueParametersForDefaultValue;
|
||||||
if (descriptor.isActual() && CollectionsKt.none(originalParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
if (descriptor.isActual() && CollectionsKt.none(valueParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
||||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
||||||
if (expected != null) {
|
if (expected != null) {
|
||||||
valueParameters = expected.getValueParameters();
|
valueParametersForDefaultValue = expected.getValueParameters();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||||
assert element != null : "No element found for descriptor: " + descriptor;
|
assert element != null : "No element found for descriptor: " + descriptor;
|
||||||
context.bindingTrace().report(Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(element));
|
context.bindingTrace().report(Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(element));
|
||||||
valueParameters = originalParameters;
|
valueParametersForDefaultValue = valueParameters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
valueParameters = originalParameters;
|
valueParametersForDefaultValue = valueParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<JsStatement> result = new ArrayList<>(valueParameters.size());
|
List<JsStatement> result = new ArrayList<>(valueParameters.size());
|
||||||
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
for (int i = 0; i < valueParameters.size(); i++) {
|
||||||
if (!valueParameter.declaresDefaultValue()) continue;
|
ValueParameterDescriptor valueParameter = valueParameters.get(i);
|
||||||
|
ValueParameterDescriptor valueParameterForDefaultValue = valueParametersForDefaultValue.get(i);
|
||||||
|
|
||||||
|
if (!valueParameterForDefaultValue.declaresDefaultValue()) continue;
|
||||||
|
|
||||||
JsExpression jsNameRef = ReferenceTranslator.translateAsValueReference(valueParameter, context);
|
JsExpression jsNameRef = ReferenceTranslator.translateAsValueReference(valueParameter, context);
|
||||||
KtExpression defaultArgument = BindingUtils.getDefaultArgument(valueParameter);
|
|
||||||
|
KtExpression defaultArgument = BindingUtils.getDefaultArgument(valueParameterForDefaultValue);
|
||||||
JsBlock defaultArgBlock = new JsBlock();
|
JsBlock defaultArgBlock = new JsBlock();
|
||||||
JsExpression defaultValue = Translation.translateAsExpression(defaultArgument, context, defaultArgBlock);
|
JsExpression defaultValue = Translation.translateAsExpression(defaultArgument, context, defaultArgBlock);
|
||||||
|
|
||||||
|
// parameterName = defaultValue
|
||||||
PsiElement psi = KotlinSourceElementKt.getPsi(valueParameter.getSource());
|
PsiElement psi = KotlinSourceElementKt.getPsi(valueParameter.getSource());
|
||||||
JsStatement assignStatement = assignment(jsNameRef, defaultValue).source(psi).makeStmt();
|
JsStatement assignStatement = assignment(jsNameRef, defaultValue).source(psi).makeStmt();
|
||||||
|
|
||||||
JsStatement thenStatement = JsAstUtils.mergeStatementInBlockIfNeeded(assignStatement, defaultArgBlock);
|
JsStatement thenStatement = JsAstUtils.mergeStatementInBlockIfNeeded(assignStatement, defaultArgBlock);
|
||||||
|
|
||||||
|
// parameterName === undefined
|
||||||
JsBinaryOperation checkArgIsUndefined = equality(jsNameRef, Namer.getUndefinedExpression());
|
JsBinaryOperation checkArgIsUndefined = equality(jsNameRef, Namer.getUndefinedExpression());
|
||||||
checkArgIsUndefined.source(KotlinSourceElementKt.getPsi(valueParameter.getSource()));
|
checkArgIsUndefined.source(psi);
|
||||||
|
|
||||||
|
// if (parameterName === undefined) {
|
||||||
|
// parameterName = defaultValue
|
||||||
|
// }
|
||||||
JsIf jsIf = JsAstUtils.newJsIf(checkArgIsUndefined, thenStatement);
|
JsIf jsIf = JsAstUtils.newJsIf(checkArgIsUndefined, thenStatement);
|
||||||
jsIf.setSource(checkArgIsUndefined.getSource());
|
jsIf.setSource(checkArgIsUndefined.getSource());
|
||||||
result.add(jsIf);
|
result.add(jsIf);
|
||||||
|
|||||||
Reference in New Issue
Block a user