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