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#ifndef ES2PANDA_IR_ASTDUMP_H 173af6ab5fSopenharmony_ci#define ES2PANDA_IR_ASTDUMP_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 <util/ustring.h> 233af6ab5fSopenharmony_ci 243af6ab5fSopenharmony_ci#include <sstream> 253af6ab5fSopenharmony_ci#include <variant> 263af6ab5fSopenharmony_ci 273af6ab5fSopenharmony_cinamespace panda::es2panda::ir { 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_ciclass AstDumper { 303af6ab5fSopenharmony_cipublic: 313af6ab5fSopenharmony_ci class Nullable { 323af6ab5fSopenharmony_ci public: 333af6ab5fSopenharmony_ci explicit Nullable(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 ir::AstNode *, bool>; 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 const Val &Value() const 523af6ab5fSopenharmony_ci { 533af6ab5fSopenharmony_ci return value_; 543af6ab5fSopenharmony_ci } 553af6ab5fSopenharmony_ci 563af6ab5fSopenharmony_ci private: 573af6ab5fSopenharmony_ci Val value_; 583af6ab5fSopenharmony_ci }; 593af6ab5fSopenharmony_ci 603af6ab5fSopenharmony_ci class Property { 613af6ab5fSopenharmony_ci public: 623af6ab5fSopenharmony_ci class Ignore { 633af6ab5fSopenharmony_ci public: 643af6ab5fSopenharmony_ci Ignore() = default; 653af6ab5fSopenharmony_ci }; 663af6ab5fSopenharmony_ci 673af6ab5fSopenharmony_ci enum class Constant { 683af6ab5fSopenharmony_ci PROP_NULL, 693af6ab5fSopenharmony_ci EMPTY_ARRAY, 703af6ab5fSopenharmony_ci }; 713af6ab5fSopenharmony_ci 723af6ab5fSopenharmony_ci using Val = 733af6ab5fSopenharmony_ci std::variant<const char *, lexer::TokenType, std::initializer_list<Property>, util::StringView, bool, 743af6ab5fSopenharmony_ci double, const ir::AstNode *, std::vector<const ir::AstNode *>, Constant, Nullable, Ignore>; 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_ci Property(const char *key, const char *string) : key_(key), value_(string) {} 773af6ab5fSopenharmony_ci Property(const char *key, util::StringView str) : key_(key), value_(str) {} 783af6ab5fSopenharmony_ci Property(const char *key, bool boolean) : key_(key), value_(boolean) {} 793af6ab5fSopenharmony_ci Property(const char *key, double number) : key_(key), value_(number) {} 803af6ab5fSopenharmony_ci Property(const char *key, lexer::TokenType token) : key_(key), value_(token) {} 813af6ab5fSopenharmony_ci Property(const char *key, std::initializer_list<Property> props) : key_(key), value_(props) {} 823af6ab5fSopenharmony_ci Property(const char *key, const ir::AstNode *node) : key_(key), value_(const_cast<ir::AstNode *>(node)) {} 833af6ab5fSopenharmony_ci 843af6ab5fSopenharmony_ci Property(const char *key, Constant constant) : key_(key), value_(constant) {} 853af6ab5fSopenharmony_ci Property(const char *key, Nullable nullable) : key_(key) 863af6ab5fSopenharmony_ci { 873af6ab5fSopenharmony_ci if (nullable.Node()) { 883af6ab5fSopenharmony_ci value_ = nullable.Node(); 893af6ab5fSopenharmony_ci } else { 903af6ab5fSopenharmony_ci value_ = Property::Constant::PROP_NULL; 913af6ab5fSopenharmony_ci } 923af6ab5fSopenharmony_ci } 933af6ab5fSopenharmony_ci 943af6ab5fSopenharmony_ci Property(const char *key, Optional optional) : key_(key) 953af6ab5fSopenharmony_ci { 963af6ab5fSopenharmony_ci const auto &value = optional.Value(); 973af6ab5fSopenharmony_ci if (std::holds_alternative<const ir::AstNode *>(value) && std::get<const ir::AstNode *>(value)) { 983af6ab5fSopenharmony_ci value_ = std::get<const ir::AstNode *>(value); 993af6ab5fSopenharmony_ci return; 1003af6ab5fSopenharmony_ci } 1013af6ab5fSopenharmony_ci 1023af6ab5fSopenharmony_ci if (std::holds_alternative<const char *>(value) && std::get<const char *>(value)) { 1033af6ab5fSopenharmony_ci value_ = std::get<const char *>(value); 1043af6ab5fSopenharmony_ci return; 1053af6ab5fSopenharmony_ci } 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ci if (std::holds_alternative<bool>(value) && std::get<bool>(value)) { 1083af6ab5fSopenharmony_ci value_ = std::get<bool>(value); 1093af6ab5fSopenharmony_ci return; 1103af6ab5fSopenharmony_ci } 1113af6ab5fSopenharmony_ci 1123af6ab5fSopenharmony_ci value_ = Ignore(); 1133af6ab5fSopenharmony_ci } 1143af6ab5fSopenharmony_ci 1153af6ab5fSopenharmony_ci template <typename T> 1163af6ab5fSopenharmony_ci Property(const char *key, const ArenaVector<T> &array) : key_(key) 1173af6ab5fSopenharmony_ci { 1183af6ab5fSopenharmony_ci if (array.empty()) { 1193af6ab5fSopenharmony_ci value_ = Constant::EMPTY_ARRAY; 1203af6ab5fSopenharmony_ci return; 1213af6ab5fSopenharmony_ci } 1223af6ab5fSopenharmony_ci 1233af6ab5fSopenharmony_ci std::vector<const ir::AstNode *> nodes; 1243af6ab5fSopenharmony_ci nodes.reserve(array.size()); 1253af6ab5fSopenharmony_ci 1263af6ab5fSopenharmony_ci for (auto &it : array) { 1273af6ab5fSopenharmony_ci nodes.push_back(it); 1283af6ab5fSopenharmony_ci } 1293af6ab5fSopenharmony_ci 1303af6ab5fSopenharmony_ci value_ = std::move(nodes); 1313af6ab5fSopenharmony_ci } 1323af6ab5fSopenharmony_ci 1333af6ab5fSopenharmony_ci const char *Key() const 1343af6ab5fSopenharmony_ci { 1353af6ab5fSopenharmony_ci return key_; 1363af6ab5fSopenharmony_ci } 1373af6ab5fSopenharmony_ci 1383af6ab5fSopenharmony_ci const Val &Value() const 1393af6ab5fSopenharmony_ci { 1403af6ab5fSopenharmony_ci return value_; 1413af6ab5fSopenharmony_ci } 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci private: 1443af6ab5fSopenharmony_ci const char *key_; 1453af6ab5fSopenharmony_ci Val value_ {false}; 1463af6ab5fSopenharmony_ci }; 1473af6ab5fSopenharmony_ci 1483af6ab5fSopenharmony_ci explicit AstDumper(const BlockStatement *program, util::StringView sourceCode); 1493af6ab5fSopenharmony_ci explicit AstDumper(const ir::AstNode *node); 1503af6ab5fSopenharmony_ci 1513af6ab5fSopenharmony_ci void SerializeNode(const ir::AstNode *node); 1523af6ab5fSopenharmony_ci 1533af6ab5fSopenharmony_ci void Add(std::initializer_list<Property> props); 1543af6ab5fSopenharmony_ci void Add(const AstDumper::Property &prop); 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_ci static const char *ModifierToString(ModifierFlags flags); 1573af6ab5fSopenharmony_ci static const char *TypeOperatorToString(TSOperatorType operatorType); 1583af6ab5fSopenharmony_ci 1593af6ab5fSopenharmony_ci std::string Str() const 1603af6ab5fSopenharmony_ci { 1613af6ab5fSopenharmony_ci return ss_.str(); 1623af6ab5fSopenharmony_ci } 1633af6ab5fSopenharmony_ci 1643af6ab5fSopenharmony_ciprivate: 1653af6ab5fSopenharmony_ci using WrapperCb = std::function<void()>; 1663af6ab5fSopenharmony_ci 1673af6ab5fSopenharmony_ci template <typename T> 1683af6ab5fSopenharmony_ci void AddList(T props) 1693af6ab5fSopenharmony_ci { 1703af6ab5fSopenharmony_ci for (auto it = props.begin(); it != props.end();) { 1713af6ab5fSopenharmony_ci Serialize(*it); 1723af6ab5fSopenharmony_ci 1733af6ab5fSopenharmony_ci do { 1743af6ab5fSopenharmony_ci if (++it == props.end()) { 1753af6ab5fSopenharmony_ci return; 1763af6ab5fSopenharmony_ci } 1773af6ab5fSopenharmony_ci } while (std::holds_alternative<Property::Ignore>((*it).Value())); 1783af6ab5fSopenharmony_ci 1793af6ab5fSopenharmony_ci ss_ << ','; 1803af6ab5fSopenharmony_ci } 1813af6ab5fSopenharmony_ci } 1823af6ab5fSopenharmony_ci 1833af6ab5fSopenharmony_ci void Indent(); 1843af6ab5fSopenharmony_ci 1853af6ab5fSopenharmony_ci void Serialize(const AstDumper::Property &prop); 1863af6ab5fSopenharmony_ci void SerializePropKey(const char *str); 1873af6ab5fSopenharmony_ci void SerializeString(const char *str); 1883af6ab5fSopenharmony_ci void SerializeString(const util::StringView &str); 1893af6ab5fSopenharmony_ci void SerializeNumber(size_t number); 1903af6ab5fSopenharmony_ci void SerializeNumber(double number); 1913af6ab5fSopenharmony_ci void SerializeBoolean(bool boolean); 1923af6ab5fSopenharmony_ci void SerializeObject(const ir::AstNode *object); 1933af6ab5fSopenharmony_ci void SerializeToken(lexer::TokenType token); 1943af6ab5fSopenharmony_ci void SerializePropList(std::initializer_list<AstDumper::Property> props); 1953af6ab5fSopenharmony_ci void SerializeConstant(Property::Constant constant); 1963af6ab5fSopenharmony_ci void Wrap(const WrapperCb &cb, char delimStart = '{', char delimEnd = '}'); 1973af6ab5fSopenharmony_ci 1983af6ab5fSopenharmony_ci void SerializeLoc(const lexer::SourceRange &loc); 1993af6ab5fSopenharmony_ci void SerializeSourcePosition(const lexer::SourcePosition &pos); 2003af6ab5fSopenharmony_ci 2013af6ab5fSopenharmony_ci void SerializeArray(std::vector<const ir::AstNode *> array); 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_ci lexer::LineIndex index_; 2043af6ab5fSopenharmony_ci std::stringstream ss_; 2053af6ab5fSopenharmony_ci int32_t indent_; 2063af6ab5fSopenharmony_ci bool dumpNodeOnly_ = false; 2073af6ab5fSopenharmony_ci}; 2083af6ab5fSopenharmony_ci} // namespace panda::es2panda::ir 2093af6ab5fSopenharmony_ci 2103af6ab5fSopenharmony_ci#endif // ASTDUMP_H 211