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 "binaryExpression.h"
17
18 #include "compiler/core/pandagen.h"
19 #include "compiler/core/ETSGen.h"
20 #include "checker/TSchecker.h"
21 #include "ir/astNode.h"
22 #include "ir/expression.h"
23 #include "ir/srcDump.h"
24 #include "ir/visitor/AstVisitor.h"
25
26 namespace ark::es2panda::ir {
TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)27 void BinaryExpression::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName)
28 {
29 if (auto *transformedNode = cb(left_); left_ != transformedNode) {
30 left_->SetTransformedNode(transformationName, transformedNode);
31 left_ = transformedNode->AsExpression();
32 }
33
34 if (auto *transformedNode = cb(right_); right_ != transformedNode) {
35 right_->SetTransformedNode(transformationName, transformedNode);
36 right_ = transformedNode->AsExpression();
37 }
38 }
39
Iterate(const NodeTraverser &cb) const40 void BinaryExpression::Iterate(const NodeTraverser &cb) const
41 {
42 cb(left_);
43 cb(right_);
44 }
45
Dump(ir::AstDumper *dumper) const46 void BinaryExpression::Dump(ir::AstDumper *dumper) const
47 {
48 dumper->Add({{"type", IsLogical() ? "LogicalExpression" : "BinaryExpression"},
49 {"operator", operator_},
50 {"left", left_},
51 {"right", right_}});
52 }
53
Dump(ir::SrcDumper *dumper) const54 void BinaryExpression::Dump(ir::SrcDumper *dumper) const
55 {
56 ASSERT(left_ != nullptr);
57 ASSERT(right_ != nullptr);
58 dumper->Add("((");
59 left_->Dump(dumper);
60 dumper->Add(") ");
61 dumper->Add(TokenToString(operator_));
62 dumper->Add(" (");
63 right_->Dump(dumper);
64 dumper->Add("))");
65 }
66
Compile(compiler::PandaGen *pg) const67 void BinaryExpression::Compile(compiler::PandaGen *pg) const
68 {
69 pg->GetAstCompiler()->Compile(this);
70 }
71
Compile(compiler::ETSGen *etsg) const72 void BinaryExpression::Compile(compiler::ETSGen *etsg) const
73 {
74 etsg->GetAstCompiler()->Compile(this);
75 }
76
CompileOperands(compiler::ETSGen *etsg, compiler::VReg lhs) const77 void BinaryExpression::CompileOperands(compiler::ETSGen *etsg, compiler::VReg lhs) const
78 {
79 left_->Compile(etsg);
80
81 if (operator_ == lexer::TokenType::KEYW_INSTANCEOF) {
82 etsg->StoreAccumulator(left_, lhs);
83 } else {
84 etsg->ApplyConversionAndStoreAccumulator(left_, lhs, operationType_);
85 }
86
87 right_->Compile(etsg);
88 etsg->ApplyConversion(right_, operationType_);
89 }
90
Check(checker::TSChecker *checker)91 checker::Type *BinaryExpression::Check(checker::TSChecker *checker)
92 {
93 return checker->GetAnalyzer()->Check(this);
94 }
95
Check(checker::ETSChecker *checker)96 checker::Type *BinaryExpression::Check(checker::ETSChecker *checker)
97 {
98 return checker->GetAnalyzer()->Check(this);
99 }
100
Clone(ArenaAllocator *const allocator, AstNode *const parent)101 BinaryExpression *BinaryExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent)
102 {
103 auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr;
104 auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr;
105
106 if (auto *const clone = allocator->New<BinaryExpression>(left, right, operator_); clone != nullptr) {
107 if (operationType_ != nullptr) {
108 clone->SetOperationType(operationType_);
109 }
110
111 if (right != nullptr) {
112 right->SetParent(clone);
113 }
114
115 if (left != nullptr) {
116 left->SetParent(clone);
117 }
118
119 if (parent != nullptr) {
120 clone->SetParent(parent);
121 }
122
123 clone->SetRange(Range());
124 return clone;
125 }
126
127 throw Error(ErrorType::GENERIC, "", CLONE_ALLOCATION_ERROR);
128 }
129 } // namespace ark::es2panda::ir
130