• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "astDump.h"
17 
18 namespace panda::es2panda::ir {
19 
AstDumper(const BlockStatement * program,util::StringView sourceCode)20 AstDumper::AstDumper(const BlockStatement *program, util::StringView sourceCode) : index_(sourceCode), indent_(0)
21 {
22     SerializeObject(reinterpret_cast<const ir::AstNode *>(program));
23 }
24 
AstDumper(const ir::AstNode * node)25 AstDumper::AstDumper(const ir::AstNode *node) : indent_(0), dumpNodeOnly_(true)
26 {
27     SerializeNode(node);
28 }
29 
SerializeNode(const ir::AstNode * node)30 void AstDumper::SerializeNode(const ir::AstNode *node)
31 {
32     Wrap([this, node]() -> void {
33         node->Dump(this);
34     });
35 }
36 
Add(std::initializer_list<AstDumper::Property> props)37 void AstDumper::Add(std::initializer_list<AstDumper::Property> props)
38 {
39     AddList<std::initializer_list<AstDumper::Property>>(props);
40 }
41 
Add(const AstDumper::Property & prop)42 void AstDumper::Add(const AstDumper::Property &prop)
43 {
44     Serialize(prop);
45 }
46 
ModifierToString(ModifierFlags flags)47 const char *AstDumper::ModifierToString(ModifierFlags flags)
48 {
49     if (flags & ModifierFlags::PRIVATE) {
50         return "private";
51     }
52 
53     if (flags & ModifierFlags::PROTECTED) {
54         return "protected";
55     }
56 
57     if (flags & ModifierFlags::PUBLIC) {
58         return "public";
59     }
60 
61     return nullptr;
62 }
63 
TypeOperatorToString(TSOperatorType operatorType)64 const char *AstDumper::TypeOperatorToString(TSOperatorType operatorType)
65 {
66     if (operatorType == TSOperatorType::KEYOF) {
67         return "keyof";
68     }
69 
70     if (operatorType == TSOperatorType::READONLY) {
71         return "readonly";
72     }
73 
74     if (operatorType == TSOperatorType::UNIQUE) {
75         return "unique";
76     }
77 
78     return nullptr;
79 }
80 
Serialize(const AstDumper::Property & prop)81 void AstDumper::Serialize(const AstDumper::Property &prop)
82 {
83     SerializePropKey(prop.Key());
84     const auto &value = prop.Value();
85 
86     if (std::holds_alternative<const char *>(value)) {
87         SerializeString(std::get<const char *>(value));
88     } else if (std::holds_alternative<util::StringView>(value)) {
89         SerializeString(std::get<util::StringView>(value));
90     } else if (std::holds_alternative<bool>(value)) {
91         SerializeBoolean(std::get<bool>(value));
92     } else if (std::holds_alternative<double>(value)) {
93         SerializeNumber(std::get<double>(value));
94     } else if (std::holds_alternative<const ir::AstNode *>(value)) {
95         if (dumpNodeOnly_) {
96             SerializeNode(std::get<const ir::AstNode *>(value));
97         } else {
98             SerializeObject(std::get<const ir::AstNode *>(value));
99         }
100     } else if (std::holds_alternative<std::vector<const ir::AstNode *>>(value)) {
101         SerializeArray(std::get<std::vector<const ir::AstNode *>>(value));
102     } else if (std::holds_alternative<lexer::TokenType>(value)) {
103         SerializeToken(std::get<lexer::TokenType>(value));
104     } else if (std::holds_alternative<std::initializer_list<Property>>(value)) {
105         SerializePropList(std::get<std::initializer_list<Property>>(value));
106     } else if (std::holds_alternative<Property::Constant>(value)) {
107         SerializeConstant(std::get<Property::Constant>(value));
108     }
109 }
110 
SerializeToken(lexer::TokenType token)111 void AstDumper::SerializeToken(lexer::TokenType token)
112 {
113     ss_ << "\"" << lexer::TokenToString(token) << "\"";
114 }
115 
SerializePropKey(const char * str)116 void AstDumper::SerializePropKey(const char *str)
117 {
118     if (dumpNodeOnly_) {
119         return;
120     }
121     ss_ << std::endl;
122     Indent();
123     SerializeString(str);
124     ss_ << ": ";
125 }
126 
SerializeString(const char * str)127 void AstDumper::SerializeString(const char *str)
128 {
129     ss_ << "\"" << str << "\"";
130 }
131 
SerializeString(const util::StringView & str)132 void AstDumper::SerializeString(const util::StringView &str)
133 {
134     ss_ << "\"" << str.Utf8() << "\"";
135 }
136 
SerializeNumber(size_t number)137 void AstDumper::SerializeNumber(size_t number)
138 {
139     ss_ << number;
140 }
141 
SerializeNumber(double number)142 void AstDumper::SerializeNumber(double number)
143 {
144     if (std::isinf(number)) {
145         ss_ << "\"Infinity\"";
146     } else {
147         ss_ << number;
148     }
149 }
150 
SerializeBoolean(bool boolean)151 void AstDumper::SerializeBoolean(bool boolean)
152 {
153     ss_ << (boolean ? "true" : "false");
154 }
155 
SerializeConstant(Property::Constant constant)156 void AstDumper::SerializeConstant(Property::Constant constant)
157 {
158     switch (constant) {
159         case Property::Constant::PROP_NULL: {
160             ss_ << "null";
161             break;
162         }
163         case Property::Constant::EMPTY_ARRAY: {
164             ss_ << "[]";
165             break;
166         }
167         default: {
168             UNREACHABLE();
169         }
170     }
171 }
172 
SerializePropList(std::initializer_list<AstDumper::Property> props)173 void AstDumper::SerializePropList(std::initializer_list<AstDumper::Property> props)
174 {
175     Wrap([this, &props]() -> void {
176         for (const auto *it = props.begin(); it != props.end(); ++it) {
177             Serialize(*it);
178             if (std::next(it) != props.end()) {
179                 ss_ << ',';
180             }
181         }
182     });
183 }
184 
SerializeArray(std::vector<const ir::AstNode * > array)185 void AstDumper::SerializeArray(std::vector<const ir::AstNode *> array)
186 {
187     Wrap(
188         [this, &array]() -> void {
189             for (auto it = array.begin(); it != array.end(); ++it) {
190                 if (dumpNodeOnly_) {
191                     SerializeNode(*it);
192                 } else {
193                     ss_ << std::endl;
194                     Indent();
195                     SerializeObject(*it);
196                 }
197 
198                 if (std::next(it) != array.end()) {
199                     ss_ << ',';
200                 }
201             }
202         },
203         '[', ']');
204 }
205 
SerializeObject(const ir::AstNode * object)206 void AstDumper::SerializeObject(const ir::AstNode *object)
207 {
208     Wrap([this, object]() -> void {
209         object->Dump(this);
210         SerializeLoc(object->Range());
211     });
212 }
213 
Wrap(const WrapperCb & cb,char delimStart,char delimEnd)214 void AstDumper::Wrap(const WrapperCb &cb, char delimStart, char delimEnd)
215 {
216     ss_ << delimStart;
217 
218     if (dumpNodeOnly_) {
219         cb();
220     } else {
221         indent_++;
222         cb();
223         ss_ << std::endl;
224         indent_--;
225         Indent();
226     }
227 
228     ss_ << delimEnd;
229 }
230 
SerializeLoc(const lexer::SourceRange & loc)231 void AstDumper::SerializeLoc(const lexer::SourceRange &loc)
232 {
233     ss_ << ',';
234     SerializePropKey("loc");
235 
236     Wrap([this, &loc]() -> void {
237         SerializePropKey("start");
238         SerializeSourcePosition(loc.start);
239         ss_ << ',';
240         SerializePropKey("end");
241         SerializeSourcePosition(loc.end);
242     });
243 }
244 
SerializeSourcePosition(const lexer::SourcePosition & pos)245 void AstDumper::SerializeSourcePosition(const lexer::SourcePosition &pos)
246 {
247     lexer::SourceLocation loc = index_.GetLocation(pos);
248 
249     Wrap([this, &loc]() -> void {
250         SerializePropKey("line");
251         SerializeNumber(loc.line);
252         ss_ << ',';
253         SerializePropKey("column");
254         SerializeNumber(loc.col);
255     });
256 }
257 
Indent()258 void AstDumper::Indent()
259 {
260     for (int32_t i = 0; i < indent_; i++) {
261         ss_ << "  ";
262     }
263 }
264 
265 }  // namespace panda::es2panda::ir
266