diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index f65624403fc3729cdfc8f288d56c51e2771783cf..822dcc6a0884ec7fb469d6cc9271756d7122ab08 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -17,7 +17,7 @@ #include "compiler/lowering/util.h" #include "ir/astNode.h" #include "ir/expressions/arrayExpression.h" - +#include "ir/expressions/literals/undefinedLiteral.h" #include #include @@ -86,7 +86,8 @@ static ir::BlockExpression *ConvertSpreadToBlockExpression(public_lib::Context * static bool ShouldProcessRestParameters(checker::Signature *signature, const ArenaVector &arguments) { return signature != nullptr && signature->HasRestParameter() && !signature->RestVar()->TsType()->IsETSArrayType() && - arguments.size() >= signature->Params().size() && !signature->RestVar()->TsType()->IsETSTupleType(); + (arguments.size() >= signature->Params().size() || arguments.size() >= 0) && + !signature->RestVar()->TsType()->IsETSTupleType(); } static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVector &arguments, @@ -97,7 +98,8 @@ static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVe auto *checker = context->GetChecker()->AsETSChecker(); // Handle single spread element case - const size_t extraArgs = arguments.size() - signature->Params().size(); + const int diffArgs = arguments.size() - signature->Params().size(); + const size_t extraArgs = diffArgs < 0 ? 0 : diffArgs; if (extraArgs == 1 && arguments.back()->IsSpreadElement()) { return ConvertSpreadToBlockExpression(context, arguments.back()->AsSpreadElement()); } @@ -140,9 +142,16 @@ static ir::CallExpression *RebuildCallExpression(public_lib::Context *context, i auto *allocator = context->allocator; auto *varbinder = context->GetChecker()->VarBinder()->AsETSBinder(); ArenaVector newArgs(allocator->Adapter()); - - for (size_t i = 0; i < signature->Params().size(); ++i) { - newArgs.push_back(originalCall->Arguments()[i]); + if (originalCall->Arguments().size() > 0) { + for (size_t i = 0; i < signature->Params().size(); ++i) { + newArgs.push_back(originalCall->Arguments()[i]); + } + } + if (originalCall->Arguments().size() < 1 && signature->Params().size() > 0) { + auto *checker = context->GetChecker()->AsETSChecker(); + auto *undefinedExpr = checker->AllocNode(); + undefinedExpr->SetTsType(signature->Params()[0]->TsType()); + newArgs.push_back(undefinedExpr); } newArgs.push_back(restArgsArray); diff --git a/ets2panda/test/compiler/ets/rest_parameter_with_optional.ets b/ets2panda/test/compiler/ets/rest_parameter_with_optional.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a4c92e1facfb7eae97e90df41cfa8adfe86c8c6 --- /dev/null +++ b/ets2panda/test/compiler/ets/rest_parameter_with_optional.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(a?: number, ...rest: string[]): number { + if (a === undefined && rest.length === 0) { + return 0; + } else { + return 1; + } +} + +function main(): void { + arktest.assertEQ(foo(), 0); + arktest.assertEQ(foo(10), 1); + arktest.assertEQ(foo(10, "a", "b"), 1); +} \ No newline at end of file