• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 "bigintLowering.h"
17 
18 #include "compiler/lowering/scopesInit/scopesInitPhase.h"
19 #include "compiler/lowering/util.h"
20 
21 namespace ark::es2panda::compiler {
22 
Name() const23 std::string_view BigIntLowering::Name() const
24 {
25     return "BigIntLowering";
26 }
27 
CreateBigInt(public_lib::Context * ctx,ir::BigIntLiteral * literal)28 ir::Expression *CreateBigInt(public_lib::Context *ctx, ir::BigIntLiteral *literal)
29 {
30     auto parser = ctx->parser->AsETSParser();
31     auto checker = ctx->checker->AsETSChecker();
32 
33     // This will change the bigint literal node into the new class instance expression:
34     // 123456n => new BigInt("123456")
35     std::string src {"new "};
36     src += Signatures::BUILTIN_BIGINT_CLASS;
37     src += "(\"";
38     src += literal->Str().Utf8();
39     src += "\")";
40 
41     auto loweringResult = parser->CreateExpression(src);
42     loweringResult->SetParent(literal->Parent());
43 
44     InitScopesPhaseETS::RunExternalNode(loweringResult, checker->VarBinder());
45     checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(loweringResult, NearestScope(loweringResult));
46     loweringResult->Check(checker);
47 
48     return loweringResult;
49 }
50 
ReplaceStrictEqualByNormalEqual(ir::BinaryExpression * expr)51 bool ReplaceStrictEqualByNormalEqual(ir::BinaryExpression *expr)
52 {
53     auto left = expr->Left()->TsType();
54     auto isBigintLeft = (left != nullptr && left->IsETSBigIntType()) || expr->Left()->IsBigIntLiteral();
55     auto right = expr->Right()->TsType();
56     auto isBigintRight = (right != nullptr && right->IsETSBigIntType()) || expr->Right()->IsBigIntLiteral();
57     if (!isBigintLeft && !isBigintRight) {
58         return false;
59     }
60 
61     if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_STRICT_EQUAL) {
62         expr->SetOperator(lexer::TokenType::PUNCTUATOR_EQUAL);
63     } else if (expr->OperatorType() == lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL) {
64         expr->SetOperator(lexer::TokenType::PUNCTUATOR_NOT_EQUAL);
65     } else {
66         return false;
67     }
68 
69     return true;
70 }
71 
72 // Currently there are no compile time operations for bigint.
RemoveConst(ir::BinaryExpression * expr)73 bool RemoveConst(ir::BinaryExpression *expr)
74 {
75     bool isRemoved = false;
76     auto left = expr->Left()->TsType();
77     if (left != nullptr && left->IsETSBigIntType()) {
78         left->RemoveTypeFlag(checker::TypeFlag::CONSTANT);
79         isRemoved = true;
80     }
81 
82     auto right = expr->Right()->TsType();
83     if (right != nullptr && right->IsETSBigIntType()) {
84         right->RemoveTypeFlag(checker::TypeFlag::CONSTANT);
85         isRemoved = true;
86     }
87 
88     return isRemoved;
89 }
90 
PerformForModule(public_lib::Context * const ctx,parser::Program * const program)91 bool BigIntLowering::PerformForModule(public_lib::Context *const ctx, parser::Program *const program)
92 {
93     auto checker = ctx->checker->AsETSChecker();
94 
95     program->Ast()->TransformChildrenRecursively(
96         // CC-OFFNXT(G.FMT.14-CPP) project code style
97         [ctx, checker](ir::AstNode *ast) -> ir::AstNode * {
98             if (ast->IsBigIntLiteral() && ast->Parent() != nullptr && ast->Parent()->IsClassProperty()) {
99                 return CreateBigInt(ctx, ast->AsBigIntLiteral());
100             }
101 
102             if (ast->IsBinaryExpression()) {
103                 auto expr = ast->AsBinaryExpression();
104                 bool doCheck = ReplaceStrictEqualByNormalEqual(expr);
105                 doCheck |= RemoveConst(expr);
106                 if (doCheck) {
107                     expr->Check(checker);
108                 }
109             }
110 
111             return ast;
112         },
113         Name());
114 
115     return true;
116 }
117 
118 }  // namespace ark::es2panda::compiler
119