13af6ab5fSopenharmony_ci/** 23af6ab5fSopenharmony_ci * Copyright (c) 2021-2024 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#include "util/helpers.h" 203af6ab5fSopenharmony_ci 213af6ab5fSopenharmony_ci#include <cmath> 223af6ab5fSopenharmony_ci#include <iostream> 233af6ab5fSopenharmony_ci 243af6ab5fSopenharmony_cinamespace ark::es2panda::ir { 253af6ab5fSopenharmony_ciAstDumper::AstDumper(const ir::AstNode *node, util::StringView sourceCode) : index_(sourceCode) 263af6ab5fSopenharmony_ci{ 273af6ab5fSopenharmony_ci isSrcEmpty_ = sourceCode.Empty(); 283af6ab5fSopenharmony_ci SerializeObject(node); 293af6ab5fSopenharmony_ci} 303af6ab5fSopenharmony_ci 313af6ab5fSopenharmony_civoid AstDumper::Add(std::initializer_list<AstDumper::Property> props) 323af6ab5fSopenharmony_ci{ 333af6ab5fSopenharmony_ci AddList<std::initializer_list<AstDumper::Property>>(props); 343af6ab5fSopenharmony_ci} 353af6ab5fSopenharmony_ci 363af6ab5fSopenharmony_civoid AstDumper::Add(const AstDumper::Property &prop) 373af6ab5fSopenharmony_ci{ 383af6ab5fSopenharmony_ci Serialize(prop); 393af6ab5fSopenharmony_ci} 403af6ab5fSopenharmony_ci 413af6ab5fSopenharmony_ciconst char *AstDumper::ModifierToString(ModifierFlags flags) 423af6ab5fSopenharmony_ci{ 433af6ab5fSopenharmony_ci if ((flags & ModifierFlags::INTERNAL) != 0) { 443af6ab5fSopenharmony_ci return "internal"; 453af6ab5fSopenharmony_ci } 463af6ab5fSopenharmony_ci 473af6ab5fSopenharmony_ci if ((flags & ModifierFlags::PRIVATE) != 0) { 483af6ab5fSopenharmony_ci return "private"; 493af6ab5fSopenharmony_ci } 503af6ab5fSopenharmony_ci 513af6ab5fSopenharmony_ci if ((flags & ModifierFlags::PROTECTED) != 0) { 523af6ab5fSopenharmony_ci return "protected"; 533af6ab5fSopenharmony_ci } 543af6ab5fSopenharmony_ci 553af6ab5fSopenharmony_ci if ((flags & ModifierFlags::PUBLIC) != 0) { 563af6ab5fSopenharmony_ci return "public"; 573af6ab5fSopenharmony_ci } 583af6ab5fSopenharmony_ci 593af6ab5fSopenharmony_ci return nullptr; 603af6ab5fSopenharmony_ci} 613af6ab5fSopenharmony_ci 623af6ab5fSopenharmony_ciconst char *AstDumper::TypeOperatorToString(TSOperatorType operatorType) 633af6ab5fSopenharmony_ci{ 643af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::KEYOF) { 653af6ab5fSopenharmony_ci return "keyof"; 663af6ab5fSopenharmony_ci } 673af6ab5fSopenharmony_ci 683af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::READONLY) { 693af6ab5fSopenharmony_ci return "readonly"; 703af6ab5fSopenharmony_ci } 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ci if (operatorType == TSOperatorType::UNIQUE) { 733af6ab5fSopenharmony_ci return "unique"; 743af6ab5fSopenharmony_ci } 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_ci return nullptr; 773af6ab5fSopenharmony_ci} 783af6ab5fSopenharmony_ci 793af6ab5fSopenharmony_civoid AstDumper::Serialize(const AstDumper::Property &prop) 803af6ab5fSopenharmony_ci{ 813af6ab5fSopenharmony_ci SerializePropKey(prop.Key()); 823af6ab5fSopenharmony_ci const auto &value = prop.Value(); 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci if (std::holds_alternative<const char *>(value)) { 853af6ab5fSopenharmony_ci SerializeString(std::get<const char *>(value)); 863af6ab5fSopenharmony_ci } else if (std::holds_alternative<util::StringView>(value)) { 873af6ab5fSopenharmony_ci SerializeString(std::get<util::StringView>(value)); 883af6ab5fSopenharmony_ci } else if (std::holds_alternative<bool>(value)) { 893af6ab5fSopenharmony_ci SerializeBoolean(std::get<bool>(value)); 903af6ab5fSopenharmony_ci } else if (std::holds_alternative<lexer::Number>(value)) { 913af6ab5fSopenharmony_ci SerializeNumber(std::get<lexer::Number>(value)); 923af6ab5fSopenharmony_ci } else if (std::holds_alternative<char16_t>(value)) { 933af6ab5fSopenharmony_ci SerializeChar16(std::get<char16_t>(value)); 943af6ab5fSopenharmony_ci } else if (std::holds_alternative<const ir::AstNode *>(value)) { 953af6ab5fSopenharmony_ci SerializeObject(std::get<const ir::AstNode *>(value)); 963af6ab5fSopenharmony_ci } else if (std::holds_alternative<std::vector<const ir::AstNode *>>(value)) { 973af6ab5fSopenharmony_ci SerializeArray(std::get<std::vector<const ir::AstNode *>>(value)); 983af6ab5fSopenharmony_ci } else if (std::holds_alternative<lexer::TokenType>(value)) { 993af6ab5fSopenharmony_ci SerializeToken(std::get<lexer::TokenType>(value)); 1003af6ab5fSopenharmony_ci } else if (std::holds_alternative<std::initializer_list<Property>>(value)) { 1013af6ab5fSopenharmony_ci SerializePropList(std::get<std::initializer_list<Property>>(value)); 1023af6ab5fSopenharmony_ci } else if (std::holds_alternative<Property::Constant>(value)) { 1033af6ab5fSopenharmony_ci SerializeConstant(std::get<Property::Constant>(value)); 1043af6ab5fSopenharmony_ci } 1053af6ab5fSopenharmony_ci} 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_civoid AstDumper::SerializeToken(lexer::TokenType token) 1083af6ab5fSopenharmony_ci{ 1093af6ab5fSopenharmony_ci ss_ << "\"" << lexer::TokenToString(token) << "\""; 1103af6ab5fSopenharmony_ci} 1113af6ab5fSopenharmony_ci 1123af6ab5fSopenharmony_civoid AstDumper::SerializePropKey(const char *str) 1133af6ab5fSopenharmony_ci{ 1143af6ab5fSopenharmony_ci ss_ << std::endl; 1153af6ab5fSopenharmony_ci Indent(); 1163af6ab5fSopenharmony_ci SerializeString(str); 1173af6ab5fSopenharmony_ci ss_ << ": "; 1183af6ab5fSopenharmony_ci} 1193af6ab5fSopenharmony_ci 1203af6ab5fSopenharmony_civoid AstDumper::SerializeString(const char *str) 1213af6ab5fSopenharmony_ci{ 1223af6ab5fSopenharmony_ci ss_ << "\"" << str << "\""; 1233af6ab5fSopenharmony_ci} 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_civoid AstDumper::SerializeString(const util::StringView &str) 1263af6ab5fSopenharmony_ci{ 1273af6ab5fSopenharmony_ci ss_ << "\"" << str.Utf8() << "\""; 1283af6ab5fSopenharmony_ci} 1293af6ab5fSopenharmony_ci 1303af6ab5fSopenharmony_civoid AstDumper::SerializeNumber(size_t number) 1313af6ab5fSopenharmony_ci{ 1323af6ab5fSopenharmony_ci ss_ << number; 1333af6ab5fSopenharmony_ci} 1343af6ab5fSopenharmony_ci 1353af6ab5fSopenharmony_civoid AstDumper::SerializeNumber(lexer::Number number) 1363af6ab5fSopenharmony_ci{ 1373af6ab5fSopenharmony_ci if (number.IsInt()) { 1383af6ab5fSopenharmony_ci ss_ << number.GetInt(); 1393af6ab5fSopenharmony_ci } else if (number.IsLong()) { 1403af6ab5fSopenharmony_ci ss_ << number.GetLong(); 1413af6ab5fSopenharmony_ci } else if (number.IsFloat()) { 1423af6ab5fSopenharmony_ci if (std::isinf(number.GetFloat())) { 1433af6ab5fSopenharmony_ci ss_ << "\"Infinity\""; 1443af6ab5fSopenharmony_ci } else { 1453af6ab5fSopenharmony_ci ss_ << number.GetFloat(); 1463af6ab5fSopenharmony_ci } 1473af6ab5fSopenharmony_ci } else { 1483af6ab5fSopenharmony_ci if (std::isinf(number.GetDouble())) { 1493af6ab5fSopenharmony_ci ss_ << "\"Infinity\""; 1503af6ab5fSopenharmony_ci } else { 1513af6ab5fSopenharmony_ci ss_ << number.GetDouble(); 1523af6ab5fSopenharmony_ci } 1533af6ab5fSopenharmony_ci } 1543af6ab5fSopenharmony_ci} 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_civoid AstDumper::SerializeChar16(char16_t c16) 1573af6ab5fSopenharmony_ci{ 1583af6ab5fSopenharmony_ci SerializeString(util::Helpers::UTF16toUTF8(c16).c_str()); 1593af6ab5fSopenharmony_ci} 1603af6ab5fSopenharmony_ci 1613af6ab5fSopenharmony_civoid AstDumper::SerializeBoolean(bool boolean) 1623af6ab5fSopenharmony_ci{ 1633af6ab5fSopenharmony_ci ss_ << (boolean ? "true" : "false"); 1643af6ab5fSopenharmony_ci} 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_civoid AstDumper::SerializeConstant(Property::Constant constant) 1673af6ab5fSopenharmony_ci{ 1683af6ab5fSopenharmony_ci switch (constant) { 1693af6ab5fSopenharmony_ci case Property::Constant::PROP_NULL: { 1703af6ab5fSopenharmony_ci ss_ << "null"; 1713af6ab5fSopenharmony_ci break; 1723af6ab5fSopenharmony_ci } 1733af6ab5fSopenharmony_ci case Property::Constant::PROP_UNDEFINED: { 1743af6ab5fSopenharmony_ci ss_ << "undefined"; 1753af6ab5fSopenharmony_ci break; 1763af6ab5fSopenharmony_ci } 1773af6ab5fSopenharmony_ci case Property::Constant::EMPTY_ARRAY: { 1783af6ab5fSopenharmony_ci ss_ << "[]"; 1793af6ab5fSopenharmony_ci break; 1803af6ab5fSopenharmony_ci } 1813af6ab5fSopenharmony_ci default: { 1823af6ab5fSopenharmony_ci UNREACHABLE(); 1833af6ab5fSopenharmony_ci } 1843af6ab5fSopenharmony_ci } 1853af6ab5fSopenharmony_ci} 1863af6ab5fSopenharmony_ci 1873af6ab5fSopenharmony_civoid AstDumper::SerializePropList(std::initializer_list<AstDumper::Property> props) 1883af6ab5fSopenharmony_ci{ 1893af6ab5fSopenharmony_ci Wrap([this, &props]() -> void { 1903af6ab5fSopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 1913af6ab5fSopenharmony_ci for (const auto *it = props.begin(); it != props.end(); ++it) { 1923af6ab5fSopenharmony_ci Serialize(*it); 1933af6ab5fSopenharmony_ci if (std::next(it) != props.end()) { 1943af6ab5fSopenharmony_ci ss_ << ','; 1953af6ab5fSopenharmony_ci } 1963af6ab5fSopenharmony_ci } 1973af6ab5fSopenharmony_ci }); 1983af6ab5fSopenharmony_ci} 1993af6ab5fSopenharmony_ci 2003af6ab5fSopenharmony_civoid AstDumper::SerializeArray(std::vector<const ir::AstNode *> array) 2013af6ab5fSopenharmony_ci{ 2023af6ab5fSopenharmony_ci Wrap( 2033af6ab5fSopenharmony_ci [this, &array]() -> void { 2043af6ab5fSopenharmony_ci for (auto it = array.begin(); it != array.end(); ++it) { 2053af6ab5fSopenharmony_ci ss_ << std::endl; 2063af6ab5fSopenharmony_ci Indent(); 2073af6ab5fSopenharmony_ci 2083af6ab5fSopenharmony_ci SerializeObject(*it); 2093af6ab5fSopenharmony_ci 2103af6ab5fSopenharmony_ci if (std::next(it) != array.end()) { 2113af6ab5fSopenharmony_ci ss_ << ','; 2123af6ab5fSopenharmony_ci } 2133af6ab5fSopenharmony_ci } 2143af6ab5fSopenharmony_ci }, 2153af6ab5fSopenharmony_ci '[', ']'); 2163af6ab5fSopenharmony_ci} 2173af6ab5fSopenharmony_ci 2183af6ab5fSopenharmony_civoid AstDumper::SerializeObject(const ir::AstNode *object) 2193af6ab5fSopenharmony_ci{ 2203af6ab5fSopenharmony_ci Wrap([this, object]() -> void { 2213af6ab5fSopenharmony_ci object->Dump(this); 2223af6ab5fSopenharmony_ci if (!isSrcEmpty_) { 2233af6ab5fSopenharmony_ci SerializeLoc(object->Range()); 2243af6ab5fSopenharmony_ci } 2253af6ab5fSopenharmony_ci }); 2263af6ab5fSopenharmony_ci} 2273af6ab5fSopenharmony_ci 2283af6ab5fSopenharmony_civoid AstDumper::Wrap(const WrapperCb &cb, char delimStart, char delimEnd) 2293af6ab5fSopenharmony_ci{ 2303af6ab5fSopenharmony_ci ss_ << delimStart; 2313af6ab5fSopenharmony_ci indent_++; 2323af6ab5fSopenharmony_ci 2333af6ab5fSopenharmony_ci cb(); 2343af6ab5fSopenharmony_ci ss_ << std::endl; 2353af6ab5fSopenharmony_ci indent_--; 2363af6ab5fSopenharmony_ci Indent(); 2373af6ab5fSopenharmony_ci ss_ << delimEnd; 2383af6ab5fSopenharmony_ci} 2393af6ab5fSopenharmony_ci 2403af6ab5fSopenharmony_civoid AstDumper::SerializeLoc(const lexer::SourceRange &loc) 2413af6ab5fSopenharmony_ci{ 2423af6ab5fSopenharmony_ci ss_ << ','; 2433af6ab5fSopenharmony_ci SerializePropKey("loc"); 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci Wrap([this, &loc]() -> void { 2463af6ab5fSopenharmony_ci SerializePropKey("start"); 2473af6ab5fSopenharmony_ci SerializeSourcePosition(loc.start); 2483af6ab5fSopenharmony_ci ss_ << ','; 2493af6ab5fSopenharmony_ci SerializePropKey("end"); 2503af6ab5fSopenharmony_ci SerializeSourcePosition(loc.end); 2513af6ab5fSopenharmony_ci }); 2523af6ab5fSopenharmony_ci} 2533af6ab5fSopenharmony_ci 2543af6ab5fSopenharmony_civoid AstDumper::SerializeSourcePosition(const lexer::SourcePosition &pos) 2553af6ab5fSopenharmony_ci{ 2563af6ab5fSopenharmony_ci lexer::SourceLocation loc = index_.GetLocation(pos); 2573af6ab5fSopenharmony_ci 2583af6ab5fSopenharmony_ci Wrap([this, &loc]() -> void { 2593af6ab5fSopenharmony_ci SerializePropKey("line"); 2603af6ab5fSopenharmony_ci SerializeNumber(loc.line); 2613af6ab5fSopenharmony_ci ss_ << ','; 2623af6ab5fSopenharmony_ci SerializePropKey("column"); 2633af6ab5fSopenharmony_ci SerializeNumber(loc.col); 2643af6ab5fSopenharmony_ci }); 2653af6ab5fSopenharmony_ci} 2663af6ab5fSopenharmony_ci 2673af6ab5fSopenharmony_civoid AstDumper::Indent() 2683af6ab5fSopenharmony_ci{ 2693af6ab5fSopenharmony_ci for (int32_t i = 0; i < indent_; i++) { 2703af6ab5fSopenharmony_ci ss_ << " "; 2713af6ab5fSopenharmony_ci } 2723af6ab5fSopenharmony_ci} 2733af6ab5fSopenharmony_ci} // namespace ark::es2panda::ir 274