13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ci#include "astDump.h" 173af6ab5fSopenharmony_ci 183af6ab5fSopenharmony_ci#include <ir/astNode.h> 193af6ab5fSopenharmony_ci 203af6ab5fSopenharmony_ci#include <cmath> 213af6ab5fSopenharmony_ci#include <iostream> 223af6ab5fSopenharmony_ci 233af6ab5fSopenharmony_cinamespace panda::es2panda::ir { 243af6ab5fSopenharmony_ci 253af6ab5fSopenharmony_ciAstDumper::AstDumper(const BlockStatement *program, util::StringView sourceCode) : index_(sourceCode), indent_(0) 263af6ab5fSopenharmony_ci{ 273af6ab5fSopenharmony_ci SerializeObject(reinterpret_cast<const ir::AstNode *>(program)); 283af6ab5fSopenharmony_ci} 293af6ab5fSopenharmony_ci 303af6ab5fSopenharmony_ciAstDumper::AstDumper(const ir::AstNode *node) : indent_(0), dumpNodeOnly_(true) 313af6ab5fSopenharmony_ci{ 323af6ab5fSopenharmony_ci SerializeNode(node); 333af6ab5fSopenharmony_ci} 343af6ab5fSopenharmony_ci 353af6ab5fSopenharmony_civoid AstDumper::SerializeNode(const ir::AstNode *node) 363af6ab5fSopenharmony_ci{ 373af6ab5fSopenharmony_ci Wrap([this, node]() -> void { 383af6ab5fSopenharmony_ci node->Dump(this); 393af6ab5fSopenharmony_ci }); 403af6ab5fSopenharmony_ci} 413af6ab5fSopenharmony_ci 423af6ab5fSopenharmony_civoid AstDumper::Add(std::initializer_list<AstDumper::Property> props) 433af6ab5fSopenharmony_ci{ 443af6ab5fSopenharmony_ci AddList<std::initializer_list<AstDumper::Property>>(props); 453af6ab5fSopenharmony_ci} 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_civoid AstDumper::Add(const AstDumper::Property &prop) 483af6ab5fSopenharmony_ci{ 493af6ab5fSopenharmony_ci Serialize(prop); 503af6ab5fSopenharmony_ci} 513af6ab5fSopenharmony_ci 523af6ab5fSopenharmony_ciconst char *AstDumper::ModifierToString(ModifierFlags flags) 533af6ab5fSopenharmony_ci{ 543af6ab5fSopenharmony_ci if (flags & ModifierFlags::PRIVATE) { 553af6ab5fSopenharmony_ci return "private"; 563af6ab5fSopenharmony_ci } 573af6ab5fSopenharmony_ci 583af6ab5fSopenharmony_ci if (flags & ModifierFlags::PROTECTED) { 593af6ab5fSopenharmony_ci return "protected"; 603af6ab5fSopenharmony_ci } 613af6ab5fSopenharmony_ci 623af6ab5fSopenharmony_ci if (flags & ModifierFlags::PUBLIC) { 633af6ab5fSopenharmony_ci return "public"; 643af6ab5fSopenharmony_ci } 653af6ab5fSopenharmony_ci 663af6ab5fSopenharmony_ci return nullptr; 673af6ab5fSopenharmony_ci} 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_ciconst char *AstDumper::TypeOperatorToString(TSOperatorType operatorType) 703af6ab5fSopenharmony_ci{ 713af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::KEYOF) { 723af6ab5fSopenharmony_ci return "keyof"; 733af6ab5fSopenharmony_ci } 743af6ab5fSopenharmony_ci 753af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::READONLY) { 763af6ab5fSopenharmony_ci return "readonly"; 773af6ab5fSopenharmony_ci } 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::UNIQUE) { 803af6ab5fSopenharmony_ci return "unique"; 813af6ab5fSopenharmony_ci } 823af6ab5fSopenharmony_ci 833af6ab5fSopenharmony_ci return nullptr; 843af6ab5fSopenharmony_ci} 853af6ab5fSopenharmony_ci 863af6ab5fSopenharmony_civoid AstDumper::Serialize(const AstDumper::Property &prop) 873af6ab5fSopenharmony_ci{ 883af6ab5fSopenharmony_ci SerializePropKey(prop.Key()); 893af6ab5fSopenharmony_ci const auto &value = prop.Value(); 903af6ab5fSopenharmony_ci 913af6ab5fSopenharmony_ci if (std::holds_alternative<const char *>(value)) { 923af6ab5fSopenharmony_ci SerializeString(std::get<const char *>(value)); 933af6ab5fSopenharmony_ci } else if (std::holds_alternative<util::StringView>(value)) { 943af6ab5fSopenharmony_ci SerializeString(std::get<util::StringView>(value)); 953af6ab5fSopenharmony_ci } else if (std::holds_alternative<bool>(value)) { 963af6ab5fSopenharmony_ci SerializeBoolean(std::get<bool>(value)); 973af6ab5fSopenharmony_ci } else if (std::holds_alternative<double>(value)) { 983af6ab5fSopenharmony_ci SerializeNumber(std::get<double>(value)); 993af6ab5fSopenharmony_ci } else if (std::holds_alternative<const ir::AstNode *>(value)) { 1003af6ab5fSopenharmony_ci if (dumpNodeOnly_) { 1013af6ab5fSopenharmony_ci SerializeNode(std::get<const ir::AstNode *>(value)); 1023af6ab5fSopenharmony_ci } else { 1033af6ab5fSopenharmony_ci SerializeObject(std::get<const ir::AstNode *>(value)); 1043af6ab5fSopenharmony_ci } 1053af6ab5fSopenharmony_ci } else if (std::holds_alternative<std::vector<const ir::AstNode *>>(value)) { 1063af6ab5fSopenharmony_ci SerializeArray(std::get<std::vector<const ir::AstNode *>>(value)); 1073af6ab5fSopenharmony_ci } else if (std::holds_alternative<lexer::TokenType>(value)) { 1083af6ab5fSopenharmony_ci SerializeToken(std::get<lexer::TokenType>(value)); 1093af6ab5fSopenharmony_ci } else if (std::holds_alternative<std::initializer_list<Property>>(value)) { 1103af6ab5fSopenharmony_ci SerializePropList(std::get<std::initializer_list<Property>>(value)); 1113af6ab5fSopenharmony_ci } else if (std::holds_alternative<Property::Constant>(value)) { 1123af6ab5fSopenharmony_ci SerializeConstant(std::get<Property::Constant>(value)); 1133af6ab5fSopenharmony_ci } 1143af6ab5fSopenharmony_ci} 1153af6ab5fSopenharmony_ci 1163af6ab5fSopenharmony_civoid AstDumper::SerializeToken(lexer::TokenType token) 1173af6ab5fSopenharmony_ci{ 1183af6ab5fSopenharmony_ci ss_ << "\"" << lexer::TokenToString(token) << "\""; 1193af6ab5fSopenharmony_ci} 1203af6ab5fSopenharmony_ci 1213af6ab5fSopenharmony_civoid AstDumper::SerializePropKey(const char *str) 1223af6ab5fSopenharmony_ci{ 1233af6ab5fSopenharmony_ci if (dumpNodeOnly_) { 1243af6ab5fSopenharmony_ci return; 1253af6ab5fSopenharmony_ci } 1263af6ab5fSopenharmony_ci ss_ << std::endl; 1273af6ab5fSopenharmony_ci Indent(); 1283af6ab5fSopenharmony_ci SerializeString(str); 1293af6ab5fSopenharmony_ci ss_ << ": "; 1303af6ab5fSopenharmony_ci} 1313af6ab5fSopenharmony_ci 1323af6ab5fSopenharmony_civoid AstDumper::SerializeString(const char *str) 1333af6ab5fSopenharmony_ci{ 1343af6ab5fSopenharmony_ci ss_ << "\"" << str << "\""; 1353af6ab5fSopenharmony_ci} 1363af6ab5fSopenharmony_ci 1373af6ab5fSopenharmony_civoid AstDumper::SerializeString(const util::StringView &str) 1383af6ab5fSopenharmony_ci{ 1393af6ab5fSopenharmony_ci ss_ << "\"" << str.Utf8() << "\""; 1403af6ab5fSopenharmony_ci} 1413af6ab5fSopenharmony_ci 1423af6ab5fSopenharmony_civoid AstDumper::SerializeNumber(size_t number) 1433af6ab5fSopenharmony_ci{ 1443af6ab5fSopenharmony_ci ss_ << number; 1453af6ab5fSopenharmony_ci} 1463af6ab5fSopenharmony_ci 1473af6ab5fSopenharmony_civoid AstDumper::SerializeNumber(double number) 1483af6ab5fSopenharmony_ci{ 1493af6ab5fSopenharmony_ci if (std::isinf(number)) { 1503af6ab5fSopenharmony_ci ss_ << "\"Infinity\""; 1513af6ab5fSopenharmony_ci } else { 1523af6ab5fSopenharmony_ci ss_ << number; 1533af6ab5fSopenharmony_ci } 1543af6ab5fSopenharmony_ci} 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_civoid AstDumper::SerializeBoolean(bool boolean) 1573af6ab5fSopenharmony_ci{ 1583af6ab5fSopenharmony_ci ss_ << (boolean ? "true" : "false"); 1593af6ab5fSopenharmony_ci} 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_civoid AstDumper::SerializeConstant(Property::Constant constant) 1623af6ab5fSopenharmony_ci{ 1633af6ab5fSopenharmony_ci switch (constant) { 1643af6ab5fSopenharmony_ci case Property::Constant::PROP_NULL: { 1653af6ab5fSopenharmony_ci ss_ << "null"; 1663af6ab5fSopenharmony_ci break; 1673af6ab5fSopenharmony_ci } 1683af6ab5fSopenharmony_ci case Property::Constant::EMPTY_ARRAY: { 1693af6ab5fSopenharmony_ci ss_ << "[]"; 1703af6ab5fSopenharmony_ci break; 1713af6ab5fSopenharmony_ci } 1723af6ab5fSopenharmony_ci default: { 1733af6ab5fSopenharmony_ci UNREACHABLE(); 1743af6ab5fSopenharmony_ci } 1753af6ab5fSopenharmony_ci } 1763af6ab5fSopenharmony_ci} 1773af6ab5fSopenharmony_ci 1783af6ab5fSopenharmony_civoid AstDumper::SerializePropList(std::initializer_list<AstDumper::Property> props) 1793af6ab5fSopenharmony_ci{ 1803af6ab5fSopenharmony_ci Wrap([this, &props]() -> void { 1813af6ab5fSopenharmony_ci for (const auto *it = props.begin(); it != props.end(); ++it) { 1823af6ab5fSopenharmony_ci Serialize(*it); 1833af6ab5fSopenharmony_ci if (std::next(it) != props.end()) { 1843af6ab5fSopenharmony_ci ss_ << ','; 1853af6ab5fSopenharmony_ci } 1863af6ab5fSopenharmony_ci } 1873af6ab5fSopenharmony_ci }); 1883af6ab5fSopenharmony_ci} 1893af6ab5fSopenharmony_ci 1903af6ab5fSopenharmony_civoid AstDumper::SerializeArray(std::vector<const ir::AstNode *> array) 1913af6ab5fSopenharmony_ci{ 1923af6ab5fSopenharmony_ci Wrap( 1933af6ab5fSopenharmony_ci [this, &array]() -> void { 1943af6ab5fSopenharmony_ci for (auto it = array.begin(); it != array.end(); ++it) { 1953af6ab5fSopenharmony_ci if (dumpNodeOnly_) { 1963af6ab5fSopenharmony_ci SerializeNode(*it); 1973af6ab5fSopenharmony_ci } else { 1983af6ab5fSopenharmony_ci ss_ << std::endl; 1993af6ab5fSopenharmony_ci Indent(); 2003af6ab5fSopenharmony_ci SerializeObject(*it); 2013af6ab5fSopenharmony_ci } 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_ci if (std::next(it) != array.end()) { 2043af6ab5fSopenharmony_ci ss_ << ','; 2053af6ab5fSopenharmony_ci } 2063af6ab5fSopenharmony_ci } 2073af6ab5fSopenharmony_ci }, 2083af6ab5fSopenharmony_ci '[', ']'); 2093af6ab5fSopenharmony_ci} 2103af6ab5fSopenharmony_ci 2113af6ab5fSopenharmony_civoid AstDumper::SerializeObject(const ir::AstNode *object) 2123af6ab5fSopenharmony_ci{ 2133af6ab5fSopenharmony_ci Wrap([this, object]() -> void { 2143af6ab5fSopenharmony_ci object->Dump(this); 2153af6ab5fSopenharmony_ci SerializeLoc(object->Range()); 2163af6ab5fSopenharmony_ci }); 2173af6ab5fSopenharmony_ci} 2183af6ab5fSopenharmony_ci 2193af6ab5fSopenharmony_civoid AstDumper::Wrap(const WrapperCb &cb, char delimStart, char delimEnd) 2203af6ab5fSopenharmony_ci{ 2213af6ab5fSopenharmony_ci ss_ << delimStart; 2223af6ab5fSopenharmony_ci 2233af6ab5fSopenharmony_ci if (dumpNodeOnly_) { 2243af6ab5fSopenharmony_ci cb(); 2253af6ab5fSopenharmony_ci } else { 2263af6ab5fSopenharmony_ci indent_++; 2273af6ab5fSopenharmony_ci cb(); 2283af6ab5fSopenharmony_ci ss_ << std::endl; 2293af6ab5fSopenharmony_ci indent_--; 2303af6ab5fSopenharmony_ci Indent(); 2313af6ab5fSopenharmony_ci } 2323af6ab5fSopenharmony_ci 2333af6ab5fSopenharmony_ci ss_ << delimEnd; 2343af6ab5fSopenharmony_ci} 2353af6ab5fSopenharmony_ci 2363af6ab5fSopenharmony_civoid AstDumper::SerializeLoc(const lexer::SourceRange &loc) 2373af6ab5fSopenharmony_ci{ 2383af6ab5fSopenharmony_ci ss_ << ','; 2393af6ab5fSopenharmony_ci SerializePropKey("loc"); 2403af6ab5fSopenharmony_ci 2413af6ab5fSopenharmony_ci Wrap([this, &loc]() -> void { 2423af6ab5fSopenharmony_ci SerializePropKey("start"); 2433af6ab5fSopenharmony_ci SerializeSourcePosition(loc.start); 2443af6ab5fSopenharmony_ci ss_ << ','; 2453af6ab5fSopenharmony_ci SerializePropKey("end"); 2463af6ab5fSopenharmony_ci SerializeSourcePosition(loc.end); 2473af6ab5fSopenharmony_ci }); 2483af6ab5fSopenharmony_ci} 2493af6ab5fSopenharmony_ci 2503af6ab5fSopenharmony_civoid AstDumper::SerializeSourcePosition(const lexer::SourcePosition &pos) 2513af6ab5fSopenharmony_ci{ 2523af6ab5fSopenharmony_ci lexer::SourceLocation loc = index_.GetLocation(pos); 2533af6ab5fSopenharmony_ci 2543af6ab5fSopenharmony_ci Wrap([this, &loc]() -> void { 2553af6ab5fSopenharmony_ci SerializePropKey("line"); 2563af6ab5fSopenharmony_ci SerializeNumber(loc.line); 2573af6ab5fSopenharmony_ci ss_ << ','; 2583af6ab5fSopenharmony_ci SerializePropKey("column"); 2593af6ab5fSopenharmony_ci SerializeNumber(loc.col); 2603af6ab5fSopenharmony_ci }); 2613af6ab5fSopenharmony_ci} 2623af6ab5fSopenharmony_ci 2633af6ab5fSopenharmony_civoid AstDumper::Indent() 2643af6ab5fSopenharmony_ci{ 2653af6ab5fSopenharmony_ci for (int32_t i = 0; i < indent_; i++) { 2663af6ab5fSopenharmony_ci ss_ << " "; 2673af6ab5fSopenharmony_ci } 2683af6ab5fSopenharmony_ci} 2693af6ab5fSopenharmony_ci 2703af6ab5fSopenharmony_ci} // namespace panda::es2panda::ir 271