• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "assignmentExpression.h"
17 
18 #include "compiler/base/lreference.h"
19 #include "compiler/core/pandagen.h"
20 #include "compiler/core/ETSGen.h"
21 #include "checker/TSchecker.h"
22 
23 namespace ark::es2panda::ir {
24 
ConvertibleToAssignmentPatternLeft(bool mustBePattern)25 bool AssignmentExpression::ConvertibleToAssignmentPatternLeft(bool mustBePattern)
26 {
27     switch (left_->Type()) {
28         case AstNodeType::ARRAY_EXPRESSION: {
29             return left_->AsArrayExpression()->ConvertibleToArrayPattern();
30         }
31         case AstNodeType::SPREAD_ELEMENT: {
32             return mustBePattern && left_->AsSpreadElement()->ConvertibleToRest(false);
33         }
34         case AstNodeType::OBJECT_EXPRESSION: {
35             return left_->AsObjectExpression()->ConvertibleToObjectPattern();
36         }
37         case AstNodeType::ASSIGNMENT_EXPRESSION: {
38             return left_->AsAssignmentExpression()->ConvertibleToAssignmentPattern(mustBePattern);
39         }
40         case AstNodeType::META_PROPERTY_EXPRESSION:
41         case AstNodeType::CHAIN_EXPRESSION: {
42             return false;
43         }
44         default: {
45             return true;
46         }
47     }
48 }
49 
ConvertibleToAssignmentPatternRight()50 bool AssignmentExpression::ConvertibleToAssignmentPatternRight()
51 {
52     switch (right_->Type()) {
53         case AstNodeType::ARRAY_EXPRESSION: {
54             return right_->AsArrayExpression()->ConvertibleToArrayPattern();
55         }
56         case AstNodeType::CHAIN_EXPRESSION:
57         case AstNodeType::SPREAD_ELEMENT: {
58             return false;
59         }
60         case AstNodeType::OBJECT_EXPRESSION: {
61             return right_->AsObjectExpression()->ConvertibleToObjectPattern();
62         }
63         case AstNodeType::ASSIGNMENT_EXPRESSION: {
64             return right_->AsAssignmentExpression()->ConvertibleToAssignmentPattern(false);
65         }
66         default: {
67             return true;
68         }
69     }
70 }
71 
ConvertibleToAssignmentPattern(bool mustBePattern)72 bool AssignmentExpression::ConvertibleToAssignmentPattern(bool mustBePattern)
73 {
74     bool convResult = ConvertibleToAssignmentPatternLeft(mustBePattern);
75     if (mustBePattern) {
76         SetType(AstNodeType::ASSIGNMENT_PATTERN);
77     }
78 
79     if (!right_->IsAssignmentExpression()) {
80         return convResult;
81     }
82     return ConvertibleToAssignmentPatternRight();
83 }
84 
TransformChildren(const NodeTransformer & cb,std::string_view transformationName)85 void AssignmentExpression::TransformChildren(const NodeTransformer &cb, std::string_view transformationName)
86 {
87     if (auto *transformedNode = cb(left_); left_ != transformedNode) {
88         left_->SetTransformedNode(transformationName, transformedNode);
89         left_ = transformedNode->AsExpression();
90     }
91 
92     if (auto *transformedNode = cb(right_); right_ != transformedNode) {
93         right_->SetTransformedNode(transformationName, transformedNode);
94         right_ = transformedNode->AsExpression();
95     }
96 }
97 
Iterate(const NodeTraverser & cb) const98 void AssignmentExpression::Iterate(const NodeTraverser &cb) const
99 {
100     cb(left_);
101     cb(right_);
102 }
103 
Dump(ir::AstDumper * dumper) const104 void AssignmentExpression::Dump(ir::AstDumper *dumper) const
105 {
106     if (type_ == AstNodeType::ASSIGNMENT_EXPRESSION) {
107         dumper->Add({{"type", "AssignmentExpression"}, {"operator", operator_}, {"left", left_}, {"right", right_}});
108     } else {
109         dumper->Add({{"type", "AssignmentPattern"}, {"left", left_}, {"right", right_}});
110     }
111 }
112 
Dump(ir::SrcDumper * dumper) const113 void AssignmentExpression::Dump(ir::SrcDumper *dumper) const
114 {
115     ES2PANDA_ASSERT(left_);
116     left_->Dump(dumper);
117     dumper->Add(" ");
118     dumper->Add(TokenToString(operator_));
119     dumper->Add(" ");
120     ES2PANDA_ASSERT(right_);
121     right_->Dump(dumper);
122 }
123 
Compile(compiler::PandaGen * pg) const124 void AssignmentExpression::Compile(compiler::PandaGen *pg) const
125 {
126     pg->GetAstCompiler()->Compile(this);
127 }
128 
Compile(compiler::ETSGen * etsg) const129 void AssignmentExpression::Compile(compiler::ETSGen *etsg) const
130 {
131     etsg->GetAstCompiler()->Compile(this);
132 }
133 
CompilePattern(compiler::PandaGen * pg) const134 void AssignmentExpression::CompilePattern(compiler::PandaGen *pg) const
135 {
136     compiler::RegScope rs(pg);
137     auto lref = compiler::JSLReference::Create(pg, left_, false);
138     right_->Compile(pg);
139     lref.SetValue();
140 }
141 
Check(checker::TSChecker * checker)142 checker::Type *AssignmentExpression::Check(checker::TSChecker *checker)
143 {
144     return checker->GetAnalyzer()->Check(this);
145 }
146 
Check(checker::ETSChecker * checker)147 checker::VerifiedType AssignmentExpression::Check([[maybe_unused]] checker::ETSChecker *checker)
148 {
149     return {this, checker->GetAnalyzer()->Check(this)};
150 }
151 
AssignmentExpression(Tag const tag,AssignmentExpression const & other,Expression * const left,Expression * const right)152 AssignmentExpression::AssignmentExpression([[maybe_unused]] Tag const tag, AssignmentExpression const &other,
153                                            Expression *const left, Expression *const right)
154     : AssignmentExpression(other)
155 {
156     left_ = left;
157     if (left_ != nullptr) {
158         left_->SetParent(this);
159     }
160 
161     right_ = right;
162     if (right_ != nullptr) {
163         right_->SetParent(this);
164     }
165 }
166 
Clone(ArenaAllocator * const allocator,AstNode * const parent)167 AssignmentExpression *AssignmentExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent)
168 {
169     auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr;
170     auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr;
171     auto *const clone = allocator->New<AssignmentExpression>(Tag {}, *this, left, right);
172     ES2PANDA_ASSERT(clone);
173 
174     if (parent != nullptr) {
175         clone->SetParent(parent);
176     }
177 
178     clone->SetRange(Range());
179     return clone;
180 }
181 }  // namespace ark::es2panda::ir
182