1 /**
2  * Copyright (c) 2021 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 "spreadElement.h"
17 
18 #include <ir/astDump.h>
19 #include <ir/expressions/arrayExpression.h>
20 #include <ir/expressions/objectExpression.h>
21 
22 namespace panda::es2panda::ir {
23 
ValidateExpression()24 ValidationInfo SpreadElement::ValidateExpression()
25 {
26     ValidationInfo info;
27 
28     switch (argument_->Type()) {
29         case AstNodeType::OBJECT_EXPRESSION: {
30             info = argument_->AsObjectExpression()->ValidateExpression();
31             break;
32         }
33         case AstNodeType::ARRAY_EXPRESSION: {
34             info = argument_->AsArrayExpression()->ValidateExpression();
35             break;
36         }
37         default: {
38             break;
39         }
40     }
41 
42     return info;
43 }
44 
ConvertibleToRest(bool isDeclaration, bool allowPattern)45 bool SpreadElement::ConvertibleToRest(bool isDeclaration, bool allowPattern)
46 {
47     bool convResult = true;
48 
49     switch (argument_->Type()) {
50         case AstNodeType::ARRAY_EXPRESSION: {
51             convResult = allowPattern && argument_->AsArrayExpression()->ConvertibleToArrayPattern();
52             break;
53         }
54         case AstNodeType::OBJECT_EXPRESSION: {
55             convResult = allowPattern && argument_->AsObjectExpression()->ConvertibleToObjectPattern();
56             break;
57         }
58         case AstNodeType::META_PROPERTY_EXPRESSION:
59         case AstNodeType::CHAIN_EXPRESSION:
60         case AstNodeType::ASSIGNMENT_EXPRESSION: {
61             convResult = false;
62             break;
63         }
64         case AstNodeType::MEMBER_EXPRESSION: {
65             convResult = !isDeclaration;
66             break;
67         }
68         default: {
69             break;
70         }
71     }
72 
73     SetType(AstNodeType::REST_ELEMENT);
74     return convResult;
75 }
76 
SetTsTypeAnnotation(Expression *typeAnnotation)77 void SpreadElement::SetTsTypeAnnotation(Expression *typeAnnotation)
78 {
79     typeAnnotation_ = typeAnnotation;
80 }
81 
Iterate(const NodeTraverser &cb) const82 void SpreadElement::Iterate(const NodeTraverser &cb) const
83 {
84     cb(argument_);
85 
86     if (typeAnnotation_) {
87         cb(typeAnnotation_);
88     }
89 }
90 
Dump(ir::AstDumper *dumper) const91 void SpreadElement::Dump(ir::AstDumper *dumper) const
92 {
93     dumper->Add({{"type", (type_ == AstNodeType::SPREAD_ELEMENT) ? "SpreadElement" : "RestElement"},
94                  {"argument", argument_},
95                  {"typeAnnotation", AstDumper::Optional(typeAnnotation_)}});
96 }
97 
Compile([[maybe_unused]] compiler::PandaGen *pg) const98 void SpreadElement::Compile([[maybe_unused]] compiler::PandaGen *pg) const {}
99 
Check([[maybe_unused]] checker::Checker *checker) const100 checker::Type *SpreadElement::Check([[maybe_unused]] checker::Checker *checker) const
101 {
102     return nullptr;
103 }
104 
UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder)105 void SpreadElement::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder)
106 {
107     argument_ = std::get<ir::AstNode *>(cb(argument_))->AsExpression();
108     if (typeAnnotation_) {
109         typeAnnotation_ = std::get<ir::AstNode *>(cb(typeAnnotation_))->AsExpression();
110     }
111 }
112 
113 }  // namespace panda::es2panda::ir
114