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