1 /*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "expressionLambdaLowering.h"
17 #include "checker/ETSchecker.h"
18
19 namespace ark::es2panda::compiler {
ConvertExpression(public_lib::Context * ctx,ir::ArrowFunctionExpression * const arrow)20 static ir::AstNode *ConvertExpression(public_lib::Context *ctx, ir::ArrowFunctionExpression *const arrow)
21 {
22 auto *const function = arrow->Function();
23 auto *const scope = function->Scope();
24 auto *const expr = function->Body()->AsExpression();
25 auto *const allocator = ctx->Allocator();
26 auto const adapter = allocator->Adapter();
27
28 ArenaVector<ir::Statement *> statements(adapter);
29
30 if ((function->ReturnTypeAnnotation() != nullptr && function->ReturnTypeAnnotation()->IsETSPrimitiveType() &&
31 function->ReturnTypeAnnotation()->AsETSPrimitiveType()->GetPrimitiveType() == ir::PrimitiveType::VOID)) {
32 statements.emplace_back(ctx->AllocNode<ir::ExpressionStatement>(expr));
33 } else {
34 statements.emplace_back(ctx->AllocNode<ir::ReturnStatement>(expr));
35 function->AddFlag(ir::ScriptFunctionFlags::HAS_RETURN);
36 }
37
38 auto *const block = ctx->AllocNode<ir::BlockStatement>(allocator, std::move(statements));
39
40 ES2PANDA_ASSERT(block);
41 block->SetScope(scope);
42 block->SetParent(function);
43
44 function->SetBody(block);
45
46 return arrow;
47 }
48
49 using AstNodePtr = ir::AstNode *;
50
PerformForModule(public_lib::Context * ctx,parser::Program * program)51 bool ExpressionLambdaConstructionPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program)
52 {
53 program->Ast()->TransformChildrenRecursively(
54 [ctx](ir::AstNode *const node) -> AstNodePtr {
55 if (node->IsArrowFunctionExpression() &&
56 node->AsArrowFunctionExpression()->Function()->Body()->IsExpression()) {
57 return ConvertExpression(ctx, node->AsArrowFunctionExpression());
58 }
59
60 return node;
61 },
62 Name());
63
64 return true;
65 }
66
PostconditionForModule(public_lib::Context * ctx,const parser::Program * program)67 bool ExpressionLambdaConstructionPhase::PostconditionForModule([[maybe_unused]] public_lib::Context *ctx,
68 const parser::Program *program)
69 {
70 return !program->Ast()->IsAnyChild([](const ir::AstNode *node) {
71 return node->IsArrowFunctionExpression() &&
72 node->AsArrowFunctionExpression()->Function()->Body()->IsExpression();
73 });
74 }
75
76 } // namespace ark::es2panda::compiler
77