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#ifndef ES2PANDA_IR_AST_DUMP_H 173af6ab5fSopenharmony_ci#define ES2PANDA_IR_AST_DUMP_H 183af6ab5fSopenharmony_ci 193af6ab5fSopenharmony_ci#include "ir/astNode.h" 203af6ab5fSopenharmony_ci#include "lexer/token/sourceLocation.h" 213af6ab5fSopenharmony_ci#include "lexer/token/tokenType.h" 223af6ab5fSopenharmony_ci#include "lexer/token/number.h" 233af6ab5fSopenharmony_ci#include "util/ustring.h" 243af6ab5fSopenharmony_ci 253af6ab5fSopenharmony_ci#include <sstream> 263af6ab5fSopenharmony_ci#include <variant> 273af6ab5fSopenharmony_ci 283af6ab5fSopenharmony_cinamespace ark::es2panda::ir { 293af6ab5fSopenharmony_ciclass AstDumper { 303af6ab5fSopenharmony_cipublic: 313af6ab5fSopenharmony_ci class Nullish { 323af6ab5fSopenharmony_ci public: 333af6ab5fSopenharmony_ci explicit Nullish(const ir::AstNode *node) : node_(node) {} 343af6ab5fSopenharmony_ci 353af6ab5fSopenharmony_ci const ir::AstNode *Node() const 363af6ab5fSopenharmony_ci { 373af6ab5fSopenharmony_ci return node_; 383af6ab5fSopenharmony_ci } 393af6ab5fSopenharmony_ci 403af6ab5fSopenharmony_ci private: 413af6ab5fSopenharmony_ci const ir::AstNode *node_; 423af6ab5fSopenharmony_ci }; 433af6ab5fSopenharmony_ci 443af6ab5fSopenharmony_ci class Optional { 453af6ab5fSopenharmony_ci public: 463af6ab5fSopenharmony_ci using Val = std::variant<const char *, const AstNode *, bool, std::vector<const AstNode *>>; 473af6ab5fSopenharmony_ci explicit Optional(const ir::AstNode *node) : value_(node) {} 483af6ab5fSopenharmony_ci explicit Optional(const char *string) : value_(const_cast<char *>(string)) {} 493af6ab5fSopenharmony_ci explicit Optional(bool boolean) : value_(boolean) {} 503af6ab5fSopenharmony_ci 513af6ab5fSopenharmony_ci template <typename T> 523af6ab5fSopenharmony_ci explicit Optional(const ArenaVector<T> &array) 533af6ab5fSopenharmony_ci { 543af6ab5fSopenharmony_ci std::vector<const AstNode *> nodes; 553af6ab5fSopenharmony_ci nodes.reserve(array.size()); 563af6ab5fSopenharmony_ci 573af6ab5fSopenharmony_ci for (auto &it : array) { 583af6ab5fSopenharmony_ci nodes.push_back(it); 593af6ab5fSopenharmony_ci } 603af6ab5fSopenharmony_ci 613af6ab5fSopenharmony_ci value_ = std::move(nodes); 623af6ab5fSopenharmony_ci } 633af6ab5fSopenharmony_ci 643af6ab5fSopenharmony_ci const Val &Value() const 653af6ab5fSopenharmony_ci { 663af6ab5fSopenharmony_ci return value_; 673af6ab5fSopenharmony_ci } 683af6ab5fSopenharmony_ci 693af6ab5fSopenharmony_ci private: 703af6ab5fSopenharmony_ci Val value_; 713af6ab5fSopenharmony_ci }; 723af6ab5fSopenharmony_ci 733af6ab5fSopenharmony_ci class Property { 743af6ab5fSopenharmony_ci public: 753af6ab5fSopenharmony_ci class Ignore { 763af6ab5fSopenharmony_ci public: 773af6ab5fSopenharmony_ci Ignore() = default; 783af6ab5fSopenharmony_ci }; 793af6ab5fSopenharmony_ci 803af6ab5fSopenharmony_ci enum class Constant { 813af6ab5fSopenharmony_ci PROP_NULL, 823af6ab5fSopenharmony_ci PROP_UNDEFINED, 833af6ab5fSopenharmony_ci EMPTY_ARRAY, 843af6ab5fSopenharmony_ci }; 853af6ab5fSopenharmony_ci 863af6ab5fSopenharmony_ci using Val = std::variant<const char *, lexer::TokenType, std::initializer_list<Property>, util::StringView, 873af6ab5fSopenharmony_ci bool, char16_t, lexer::Number, const ir::AstNode *, std::vector<const ir::AstNode *>, 883af6ab5fSopenharmony_ci Constant, Nullish, Ignore>; 893af6ab5fSopenharmony_ci 903af6ab5fSopenharmony_ci Property(const char *key, const char *string) : key_(key), value_(string) {} 913af6ab5fSopenharmony_ci Property(const char *key, util::StringView str) : key_(key), value_(str) {} 923af6ab5fSopenharmony_ci Property(const char *key, bool boolean) : key_(key), value_(boolean) {} 933af6ab5fSopenharmony_ci Property(const char *key, char16_t c16) : key_(key), value_(c16) {} 943af6ab5fSopenharmony_ci Property(const char *key, lexer::Number number) : key_(key), value_(number) {} 953af6ab5fSopenharmony_ci Property(const char *key, lexer::TokenType token) : key_(key), value_(token) {} 963af6ab5fSopenharmony_ci Property(const char *key, std::initializer_list<Property> props) : key_(key), value_(props) {} 973af6ab5fSopenharmony_ci Property(const char *key, const ir::AstNode *node) : key_(key), value_(const_cast<ir::AstNode *>(node)) {} 983af6ab5fSopenharmony_ci 993af6ab5fSopenharmony_ci Property(const char *key, Constant constant) : key_(key), value_(constant) {} 1003af6ab5fSopenharmony_ci Property(const char *key, Nullish nullish) : key_(key) 1013af6ab5fSopenharmony_ci { 1023af6ab5fSopenharmony_ci if (nullish.Node() != nullptr) { 1033af6ab5fSopenharmony_ci value_ = nullish.Node(); 1043af6ab5fSopenharmony_ci } else { 1053af6ab5fSopenharmony_ci value_ = Property::Constant::PROP_NULL; 1063af6ab5fSopenharmony_ci } 1073af6ab5fSopenharmony_ci } 1083af6ab5fSopenharmony_ci 1093af6ab5fSopenharmony_ci Property(const char *key, const Optional &optional) : key_(key) 1103af6ab5fSopenharmony_ci { 1113af6ab5fSopenharmony_ci const auto &value = optional.Value(); 1123af6ab5fSopenharmony_ci if (std::holds_alternative<const ir::AstNode *>(value) && 1133af6ab5fSopenharmony_ci (std::get<const ir::AstNode *>(value) != nullptr)) { 1143af6ab5fSopenharmony_ci value_ = std::get<const ir::AstNode *>(value); 1153af6ab5fSopenharmony_ci return; 1163af6ab5fSopenharmony_ci } 1173af6ab5fSopenharmony_ci 1183af6ab5fSopenharmony_ci if (std::holds_alternative<const char *>(value) && (std::get<const char *>(value) != nullptr)) { 1193af6ab5fSopenharmony_ci value_ = std::get<const char *>(value); 1203af6ab5fSopenharmony_ci return; 1213af6ab5fSopenharmony_ci } 1223af6ab5fSopenharmony_ci 1233af6ab5fSopenharmony_ci if (std::holds_alternative<bool>(value) && std::get<bool>(value)) { 1243af6ab5fSopenharmony_ci value_ = std::get<bool>(value); 1253af6ab5fSopenharmony_ci return; 1263af6ab5fSopenharmony_ci } 1273af6ab5fSopenharmony_ci 1283af6ab5fSopenharmony_ci if (std::holds_alternative<std::vector<const AstNode *>>(value)) { 1293af6ab5fSopenharmony_ci const auto &array = std::get<std::vector<const AstNode *>>(value); 1303af6ab5fSopenharmony_ci if (!array.empty()) { 1313af6ab5fSopenharmony_ci value_ = array; 1323af6ab5fSopenharmony_ci return; 1333af6ab5fSopenharmony_ci } 1343af6ab5fSopenharmony_ci } 1353af6ab5fSopenharmony_ci 1363af6ab5fSopenharmony_ci value_ = Ignore(); 1373af6ab5fSopenharmony_ci } 1383af6ab5fSopenharmony_ci 1393af6ab5fSopenharmony_ci template <typename T> 1403af6ab5fSopenharmony_ci Property(const char *key, const ArenaVector<T> &array) : key_(key) 1413af6ab5fSopenharmony_ci { 1423af6ab5fSopenharmony_ci if (array.empty()) { 1433af6ab5fSopenharmony_ci value_ = Constant::EMPTY_ARRAY; 1443af6ab5fSopenharmony_ci return; 1453af6ab5fSopenharmony_ci } 1463af6ab5fSopenharmony_ci 1473af6ab5fSopenharmony_ci std::vector<const ir::AstNode *> nodes; 1483af6ab5fSopenharmony_ci nodes.reserve(array.size()); 1493af6ab5fSopenharmony_ci 1503af6ab5fSopenharmony_ci for (auto &it : array) { 1513af6ab5fSopenharmony_ci nodes.push_back(it); 1523af6ab5fSopenharmony_ci } 1533af6ab5fSopenharmony_ci 1543af6ab5fSopenharmony_ci value_ = std::move(nodes); 1553af6ab5fSopenharmony_ci } 1563af6ab5fSopenharmony_ci 1573af6ab5fSopenharmony_ci template <typename T> 1583af6ab5fSopenharmony_ci Property(const char *key, const ArenaVector<T> &array, const std::function<bool(AstNode *)> &filter) : key_(key) 1593af6ab5fSopenharmony_ci { 1603af6ab5fSopenharmony_ci std::vector<const ir::AstNode *> nodes; 1613af6ab5fSopenharmony_ci nodes.reserve(array.size()); 1623af6ab5fSopenharmony_ci 1633af6ab5fSopenharmony_ci for (auto &it : array) { 1643af6ab5fSopenharmony_ci if (filter(it)) { 1653af6ab5fSopenharmony_ci nodes.push_back(it); 1663af6ab5fSopenharmony_ci } 1673af6ab5fSopenharmony_ci } 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_ci if (nodes.empty()) { 1703af6ab5fSopenharmony_ci value_ = Constant::EMPTY_ARRAY; 1713af6ab5fSopenharmony_ci return; 1723af6ab5fSopenharmony_ci } 1733af6ab5fSopenharmony_ci 1743af6ab5fSopenharmony_ci value_ = std::move(nodes); 1753af6ab5fSopenharmony_ci } 1763af6ab5fSopenharmony_ci 1773af6ab5fSopenharmony_ci const char *Key() const 1783af6ab5fSopenharmony_ci { 1793af6ab5fSopenharmony_ci return key_; 1803af6ab5fSopenharmony_ci } 1813af6ab5fSopenharmony_ci 1823af6ab5fSopenharmony_ci const Val &Value() const 1833af6ab5fSopenharmony_ci { 1843af6ab5fSopenharmony_ci return value_; 1853af6ab5fSopenharmony_ci } 1863af6ab5fSopenharmony_ci 1873af6ab5fSopenharmony_ci private: 1883af6ab5fSopenharmony_ci const char *key_; 1893af6ab5fSopenharmony_ci Val value_ {}; 1903af6ab5fSopenharmony_ci }; 1913af6ab5fSopenharmony_ci 1923af6ab5fSopenharmony_ci explicit AstDumper(const ir::AstNode *node, util::StringView sourceCode = ""); 1933af6ab5fSopenharmony_ci 1943af6ab5fSopenharmony_ci void Add(std::initializer_list<Property> props); 1953af6ab5fSopenharmony_ci void Add(const AstDumper::Property &prop); 1963af6ab5fSopenharmony_ci 1973af6ab5fSopenharmony_ci static const char *ModifierToString(ModifierFlags flags); 1983af6ab5fSopenharmony_ci static const char *TypeOperatorToString(TSOperatorType operatorType); 1993af6ab5fSopenharmony_ci 2003af6ab5fSopenharmony_ci std::string Str() const 2013af6ab5fSopenharmony_ci { 2023af6ab5fSopenharmony_ci return ss_.str(); 2033af6ab5fSopenharmony_ci } 2043af6ab5fSopenharmony_ci 2053af6ab5fSopenharmony_ciprivate: 2063af6ab5fSopenharmony_ci using WrapperCb = std::function<void()>; 2073af6ab5fSopenharmony_ci 2083af6ab5fSopenharmony_ci template <typename T> 2093af6ab5fSopenharmony_ci void AddList(T props) 2103af6ab5fSopenharmony_ci { 2113af6ab5fSopenharmony_ci for (auto it = props.begin(); it != props.end();) { 2123af6ab5fSopenharmony_ci Serialize(*it); 2133af6ab5fSopenharmony_ci 2143af6ab5fSopenharmony_ci do { 2153af6ab5fSopenharmony_ci if (++it == props.end()) { 2163af6ab5fSopenharmony_ci return; 2173af6ab5fSopenharmony_ci } 2183af6ab5fSopenharmony_ci } while (std::holds_alternative<Property::Ignore>((*it).Value())); 2193af6ab5fSopenharmony_ci 2203af6ab5fSopenharmony_ci ss_ << ','; 2213af6ab5fSopenharmony_ci } 2223af6ab5fSopenharmony_ci } 2233af6ab5fSopenharmony_ci 2243af6ab5fSopenharmony_ci void Indent(); 2253af6ab5fSopenharmony_ci 2263af6ab5fSopenharmony_ci void Serialize(const AstDumper::Property &prop); 2273af6ab5fSopenharmony_ci void SerializePropKey(const char *str); 2283af6ab5fSopenharmony_ci void SerializeString(const char *str); 2293af6ab5fSopenharmony_ci void SerializeString(const util::StringView &str); 2303af6ab5fSopenharmony_ci void SerializeNumber(size_t number); 2313af6ab5fSopenharmony_ci void SerializeNumber(lexer::Number number); 2323af6ab5fSopenharmony_ci void SerializeChar16(char16_t c16); 2333af6ab5fSopenharmony_ci void SerializeBoolean(bool boolean); 2343af6ab5fSopenharmony_ci void SerializeObject(const ir::AstNode *object); 2353af6ab5fSopenharmony_ci void SerializeToken(lexer::TokenType token); 2363af6ab5fSopenharmony_ci void SerializePropList(std::initializer_list<AstDumper::Property> props); 2373af6ab5fSopenharmony_ci void SerializeConstant(Property::Constant constant); 2383af6ab5fSopenharmony_ci void Wrap(const WrapperCb &cb, char delimStart = '{', char delimEnd = '}'); 2393af6ab5fSopenharmony_ci 2403af6ab5fSopenharmony_ci void SerializeLoc(const lexer::SourceRange &loc); 2413af6ab5fSopenharmony_ci void SerializeSourcePosition(const lexer::SourcePosition &pos); 2423af6ab5fSopenharmony_ci 2433af6ab5fSopenharmony_ci void SerializeArray(std::vector<const ir::AstNode *> array); 2443af6ab5fSopenharmony_ci 2453af6ab5fSopenharmony_ci const lexer::LineIndex index_; 2463af6ab5fSopenharmony_ci std::stringstream ss_; 2473af6ab5fSopenharmony_ci int32_t indent_ {}; 2483af6ab5fSopenharmony_ci bool isSrcEmpty_ = false; 2493af6ab5fSopenharmony_ci}; 2503af6ab5fSopenharmony_ci} // namespace ark::es2panda::ir 2513af6ab5fSopenharmony_ci 2523af6ab5fSopenharmony_ci#endif // AST_DUMP_H 253