1 /*
2 * Copyright (c) 2021-2024 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 "enumPostCheckLowering.h"
17 #include "checker/types/ets/etsEnumType.h"
18 #include "checker/ETSchecker.h"
19 #include "checker/types/type.h"
20 #include "varbinder/ETSBinder.h"
21 #include "varbinder/variable.h"
22
23 namespace ark::es2panda::compiler {
24
CreateCall(checker::ETSChecker * checker,ir::ClassDefinition * const classDef,checker::ETSEnumType::Method (checker::ETSEnumType::* getMethod)()const,ir::Expression * argument)25 ir::CallExpression *EnumPostCheckLoweringPhase::CreateCall(
26 checker::ETSChecker *checker, ir::ClassDefinition *const classDef,
27 checker::ETSEnumType::Method (checker::ETSEnumType::*getMethod)() const, ir::Expression *argument)
28 {
29 auto *classId = checker->AllocNode<ir::Identifier>(classDef->Ident()->Name(), checker->Allocator());
30 auto *methodId = checker->AllocNode<ir::Identifier>(
31 (argument->TsType()->AsETSEnumType()->*getMethod)().memberProxyType->Name(), checker->Allocator());
32 methodId->SetReference();
33 auto *callee = checker->AllocNode<ir::MemberExpression>(classId, methodId,
34 ir::MemberExpressionKind::PROPERTY_ACCESS, false, false);
35
36 ArenaVector<ir::Expression *> callArguments(checker->Allocator()->Adapter());
37 callArguments.push_back(argument);
38 return checker->AllocNode<ir::CallExpression>(callee, std::move(callArguments), nullptr, false);
39 }
40
Perform(public_lib::Context * ctx,parser::Program * program)41 bool EnumPostCheckLoweringPhase::Perform(public_lib::Context *ctx, parser::Program *program)
42 {
43 if (program->Extension() != ScriptExtension::ETS) {
44 return true;
45 }
46
47 for (auto &[_, extPrograms] : program->ExternalSources()) {
48 (void)_;
49 for (auto *extProg : extPrograms) {
50 Perform(ctx, extProg);
51 }
52 }
53 program->Ast()->TransformChildrenRecursivelyPostorder(
54 // clang-format off
55 [this, ctx](ir::AstNode *const node) -> ir::AstNode* {
56 if (node->HasAstNodeFlags(ir::AstNodeFlags::RECHECK)) {
57 if (node->IsExpression()) {
58 node->AsExpression()->SetTsType(nullptr); // force recheck
59 }
60 node->Check(ctx->checker->AsETSChecker());
61 node->RemoveAstNodeFlags(ir::AstNodeFlags::RECHECK);
62 }
63 if (node->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) {
64 ASSERT(node->IsExpression());
65 auto expr = node->AsExpression();
66 auto parent = expr->Parent();
67 parent->AddAstNodeFlags(ir::AstNodeFlags::RECHECK);
68 ASSERT((node->AsExpression()->TsType()->IsETSEnumType()));
69 auto *enumIf = expr->TsType()->AsETSEnumType();
70 auto *callExpr = CreateCall(ctx->checker->AsETSChecker(), enumIf->GetDecl()->BoxedClass(),
71 &checker::ETSEnumType::ValueOfMethod, expr);
72 callExpr->SetParent(parent);
73 callExpr->Check(ctx->checker->AsETSChecker());
74 node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF);
75 return callExpr;
76 }
77 if (node->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_GET_NAME)) {
78 ASSERT(node->IsMemberExpression());
79 auto memberExpr = node->AsMemberExpression();
80
81 auto *enumIf = memberExpr->Object()->TsType()->AsETSEnumType();
82 auto *callExpr = CreateCall(ctx->checker->AsETSChecker(), enumIf->GetDecl()->BoxedClass(),
83 &checker::ETSEnumType::GetNameMethod, memberExpr->Property());
84
85 callExpr->SetParent(node->Parent());
86 callExpr->Check(ctx->checker->AsETSChecker());
87 node->RemoveAstNodeFlags(ir::AstNodeFlags::GENERATE_GET_NAME);
88 return callExpr;
89 }
90 return node;
91 },
92 // clang-format on
93 Name());
94 return true;
95 }
96
97 } // namespace ark::es2panda::compiler
98