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 "astNode.h"
173af6ab5fSopenharmony_ci#include "ir/astDump.h"
183af6ab5fSopenharmony_ci#include "ir/srcDump.h"
193af6ab5fSopenharmony_ci
203af6ab5fSopenharmony_cinamespace ark::es2panda::ir {
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_ciAstNode::AstNode(AstNode const &other)
233af6ab5fSopenharmony_ci{
243af6ab5fSopenharmony_ci    range_ = other.range_;
253af6ab5fSopenharmony_ci    type_ = other.type_;
263af6ab5fSopenharmony_ci    if (other.variable_ != nullptr) {
273af6ab5fSopenharmony_ci        variable_ = other.variable_;
283af6ab5fSopenharmony_ci    }
293af6ab5fSopenharmony_ci    flags_ = other.flags_;
303af6ab5fSopenharmony_ci    astNodeFlags_ = other.astNodeFlags_;
313af6ab5fSopenharmony_ci    // boxing_unboxing_flags_ {};  leave default value!
323af6ab5fSopenharmony_ci}
333af6ab5fSopenharmony_ci
343af6ab5fSopenharmony_ci[[nodiscard]] bool AstNode::IsExported() const noexcept
353af6ab5fSopenharmony_ci{
363af6ab5fSopenharmony_ci    if (UNLIKELY(IsClassDefinition())) {
373af6ab5fSopenharmony_ci        return parent_->IsExported();
383af6ab5fSopenharmony_ci    }
393af6ab5fSopenharmony_ci
403af6ab5fSopenharmony_ci    return (flags_ & ModifierFlags::EXPORT) != 0;
413af6ab5fSopenharmony_ci}
423af6ab5fSopenharmony_ci
433af6ab5fSopenharmony_ci[[nodiscard]] bool AstNode::IsDefaultExported() const noexcept
443af6ab5fSopenharmony_ci{
453af6ab5fSopenharmony_ci    if (UNLIKELY(IsClassDefinition())) {
463af6ab5fSopenharmony_ci        return parent_->IsDefaultExported();
473af6ab5fSopenharmony_ci    }
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_ci    return (flags_ & ModifierFlags::DEFAULT_EXPORT) != 0;
503af6ab5fSopenharmony_ci}
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci[[nodiscard]] bool AstNode::IsExportedType() const noexcept
533af6ab5fSopenharmony_ci{
543af6ab5fSopenharmony_ci    if (UNLIKELY(IsClassDefinition())) {
553af6ab5fSopenharmony_ci        return this->parent_->IsExportedType();
563af6ab5fSopenharmony_ci    }
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_ci    return (flags_ & ModifierFlags::EXPORT_TYPE) != 0;
593af6ab5fSopenharmony_ci}
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ci[[nodiscard]] bool AstNode::HasExportAlias() const noexcept
623af6ab5fSopenharmony_ci{
633af6ab5fSopenharmony_ci    if (UNLIKELY(IsClassDefinition())) {
643af6ab5fSopenharmony_ci        return parent_->HasExportAlias();
653af6ab5fSopenharmony_ci    }
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ci    return (astNodeFlags_ & AstNodeFlags::HAS_EXPORT_ALIAS) != 0;
683af6ab5fSopenharmony_ci}
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_cibool AstNode::IsScopeBearer() const noexcept
713af6ab5fSopenharmony_ci{
723af6ab5fSopenharmony_ci    return false;
733af6ab5fSopenharmony_ci}
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_civarbinder::Scope *AstNode::Scope() const noexcept
763af6ab5fSopenharmony_ci{
773af6ab5fSopenharmony_ci    UNREACHABLE();
783af6ab5fSopenharmony_ci}
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_civoid AstNode::ClearScope() noexcept
813af6ab5fSopenharmony_ci{
823af6ab5fSopenharmony_ci    UNREACHABLE();
833af6ab5fSopenharmony_ci}
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ciir::ClassElement *AstNode::AsClassElement()
863af6ab5fSopenharmony_ci{
873af6ab5fSopenharmony_ci    ASSERT(IsMethodDefinition() || IsClassProperty() || IsClassStaticBlock());
883af6ab5fSopenharmony_ci    return reinterpret_cast<ir::ClassElement *>(this);
893af6ab5fSopenharmony_ci}
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_ciconst ir::ClassElement *AstNode::AsClassElement() const
923af6ab5fSopenharmony_ci{
933af6ab5fSopenharmony_ci    ASSERT(IsMethodDefinition() || IsClassProperty() || IsClassStaticBlock());
943af6ab5fSopenharmony_ci    return reinterpret_cast<const ir::ClassElement *>(this);
953af6ab5fSopenharmony_ci}
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_citemplate <typename R, typename T>
983af6ab5fSopenharmony_cistatic R GetTopStatementImpl(T *self)
993af6ab5fSopenharmony_ci{
1003af6ab5fSopenharmony_ci    auto iter = self;
1013af6ab5fSopenharmony_ci
1023af6ab5fSopenharmony_ci    while (iter->Parent()) {
1033af6ab5fSopenharmony_ci        iter = iter->Parent();
1043af6ab5fSopenharmony_ci    }
1053af6ab5fSopenharmony_ci
1063af6ab5fSopenharmony_ci    return reinterpret_cast<R>(iter);
1073af6ab5fSopenharmony_ci}
1083af6ab5fSopenharmony_ci
1093af6ab5fSopenharmony_ciir::BlockStatement *AstNode::GetTopStatement()
1103af6ab5fSopenharmony_ci{
1113af6ab5fSopenharmony_ci    return GetTopStatementImpl<ir::BlockStatement *>(this);
1123af6ab5fSopenharmony_ci}
1133af6ab5fSopenharmony_ci
1143af6ab5fSopenharmony_ciconst ir::BlockStatement *AstNode::GetTopStatement() const
1153af6ab5fSopenharmony_ci{
1163af6ab5fSopenharmony_ci    return GetTopStatementImpl<const ir::BlockStatement *>(this);
1173af6ab5fSopenharmony_ci}
1183af6ab5fSopenharmony_ci
1193af6ab5fSopenharmony_ciAstNode *AstNode::Clone([[maybe_unused]] ArenaAllocator *const allocator, [[maybe_unused]] AstNode *const parent)
1203af6ab5fSopenharmony_ci{
1213af6ab5fSopenharmony_ci    UNREACHABLE();
1223af6ab5fSopenharmony_ci}
1233af6ab5fSopenharmony_ci
1243af6ab5fSopenharmony_civoid AstNode::TransformChildrenRecursively(const NodeTransformer &cb, std::string_view transformationName)
1253af6ab5fSopenharmony_ci{  // post-order, but use when you don't care about the order
1263af6ab5fSopenharmony_ci    TransformChildrenRecursivelyPostorder(cb, transformationName);
1273af6ab5fSopenharmony_ci}
1283af6ab5fSopenharmony_ci
1293af6ab5fSopenharmony_civoid AstNode::TransformChildrenRecursivelyPreorder(const NodeTransformer &cb, std::string_view transformationName)
1303af6ab5fSopenharmony_ci{
1313af6ab5fSopenharmony_ci    TransformChildren(
1323af6ab5fSopenharmony_ci        [=](AstNode *child) {
1333af6ab5fSopenharmony_ci            auto *res = cb(child);
1343af6ab5fSopenharmony_ci            res->TransformChildrenRecursivelyPreorder(cb, transformationName);
1353af6ab5fSopenharmony_ci            return res;
1363af6ab5fSopenharmony_ci        },
1373af6ab5fSopenharmony_ci        transformationName);
1383af6ab5fSopenharmony_ci}
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_civoid AstNode::TransformChildrenRecursivelyPostorder(const NodeTransformer &cb, std::string_view transformationName)
1413af6ab5fSopenharmony_ci{
1423af6ab5fSopenharmony_ci    TransformChildren(
1433af6ab5fSopenharmony_ci        [=](AstNode *child) {
1443af6ab5fSopenharmony_ci            child->TransformChildrenRecursivelyPostorder(cb, transformationName);
1453af6ab5fSopenharmony_ci            return cb(child);
1463af6ab5fSopenharmony_ci        },
1473af6ab5fSopenharmony_ci        transformationName);
1483af6ab5fSopenharmony_ci}
1493af6ab5fSopenharmony_ci
1503af6ab5fSopenharmony_civoid AstNode::IterateRecursively(const NodeTraverser &cb) const
1513af6ab5fSopenharmony_ci{  // pre-order, use when you don't care
1523af6ab5fSopenharmony_ci    IterateRecursivelyPreorder(cb);
1533af6ab5fSopenharmony_ci}
1543af6ab5fSopenharmony_ci
1553af6ab5fSopenharmony_civoid AstNode::IterateRecursivelyPreorder(const NodeTraverser &cb) const
1563af6ab5fSopenharmony_ci{
1573af6ab5fSopenharmony_ci    Iterate([=](AstNode *child) {
1583af6ab5fSopenharmony_ci        cb(child);
1593af6ab5fSopenharmony_ci        child->IterateRecursivelyPreorder(cb);
1603af6ab5fSopenharmony_ci    });
1613af6ab5fSopenharmony_ci}
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_civoid AstNode::IterateRecursivelyPostorder(const NodeTraverser &cb) const
1643af6ab5fSopenharmony_ci{
1653af6ab5fSopenharmony_ci    Iterate([=](AstNode *child) {
1663af6ab5fSopenharmony_ci        child->IterateRecursivelyPostorder(cb);
1673af6ab5fSopenharmony_ci        cb(child);
1683af6ab5fSopenharmony_ci    });
1693af6ab5fSopenharmony_ci}
1703af6ab5fSopenharmony_ci
1713af6ab5fSopenharmony_civoid AnyChildHelper(bool *found, const NodePredicate &cb, AstNode *ast)
1723af6ab5fSopenharmony_ci{
1733af6ab5fSopenharmony_ci    if (*found) {
1743af6ab5fSopenharmony_ci        return;
1753af6ab5fSopenharmony_ci    }
1763af6ab5fSopenharmony_ci
1773af6ab5fSopenharmony_ci    if (cb(ast)) {
1783af6ab5fSopenharmony_ci        *found = true;
1793af6ab5fSopenharmony_ci        return;
1803af6ab5fSopenharmony_ci    }
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci    ast->Iterate([=](AstNode *child) { AnyChildHelper(found, cb, child); });
1833af6ab5fSopenharmony_ci}
1843af6ab5fSopenharmony_ci
1853af6ab5fSopenharmony_cibool AstNode::IsAnyChild(const NodePredicate &cb) const
1863af6ab5fSopenharmony_ci{
1873af6ab5fSopenharmony_ci    bool found = false;
1883af6ab5fSopenharmony_ci    Iterate([&found, cb](AstNode *child) { AnyChildHelper(&found, cb, child); });
1893af6ab5fSopenharmony_ci    return found;
1903af6ab5fSopenharmony_ci}
1913af6ab5fSopenharmony_ci
1923af6ab5fSopenharmony_civoid FindChildHelper(AstNode *&found, const NodePredicate &cb, AstNode *ast)
1933af6ab5fSopenharmony_ci{
1943af6ab5fSopenharmony_ci    if (found != nullptr) {
1953af6ab5fSopenharmony_ci        return;
1963af6ab5fSopenharmony_ci    }
1973af6ab5fSopenharmony_ci
1983af6ab5fSopenharmony_ci    if (cb(ast)) {
1993af6ab5fSopenharmony_ci        found = ast;
2003af6ab5fSopenharmony_ci        return;
2013af6ab5fSopenharmony_ci    }
2023af6ab5fSopenharmony_ci
2033af6ab5fSopenharmony_ci    ast->Iterate([&found, cb](AstNode *child) { FindChildHelper(found, cb, child); });
2043af6ab5fSopenharmony_ci}
2053af6ab5fSopenharmony_ci
2063af6ab5fSopenharmony_ciAstNode *AstNode::FindChild(const NodePredicate &cb) const
2073af6ab5fSopenharmony_ci{
2083af6ab5fSopenharmony_ci    AstNode *found = nullptr;
2093af6ab5fSopenharmony_ci    Iterate([&found, cb](AstNode *child) { FindChildHelper(found, cb, child); });
2103af6ab5fSopenharmony_ci    return found;
2113af6ab5fSopenharmony_ci}
2123af6ab5fSopenharmony_ci
2133af6ab5fSopenharmony_civarbinder::Scope *AstNode::EnclosingScope(const ir::AstNode *expr)
2143af6ab5fSopenharmony_ci{
2153af6ab5fSopenharmony_ci    while (expr != nullptr && !expr->IsScopeBearer()) {
2163af6ab5fSopenharmony_ci        expr = expr->Parent();
2173af6ab5fSopenharmony_ci    }
2183af6ab5fSopenharmony_ci    return expr != nullptr ? expr->Scope() : nullptr;
2193af6ab5fSopenharmony_ci}
2203af6ab5fSopenharmony_ci
2213af6ab5fSopenharmony_cistd::string AstNode::DumpJSON() const
2223af6ab5fSopenharmony_ci{
2233af6ab5fSopenharmony_ci    ir::AstDumper dumper {this};
2243af6ab5fSopenharmony_ci    return dumper.Str();
2253af6ab5fSopenharmony_ci}
2263af6ab5fSopenharmony_ci
2273af6ab5fSopenharmony_cistd::string AstNode::DumpEtsSrc() const
2283af6ab5fSopenharmony_ci{
2293af6ab5fSopenharmony_ci    ir::SrcDumper dumper {this};
2303af6ab5fSopenharmony_ci    return dumper.Str();
2313af6ab5fSopenharmony_ci}
2323af6ab5fSopenharmony_ci
2333af6ab5fSopenharmony_civoid AstNode::SetOriginalNode(AstNode *originalNode)
2343af6ab5fSopenharmony_ci{
2353af6ab5fSopenharmony_ci    originalNode_ = originalNode;
2363af6ab5fSopenharmony_ci}
2373af6ab5fSopenharmony_ci
2383af6ab5fSopenharmony_civoid AstNode::SetTransformedNode(std::string_view const transformationName, AstNode *transformedNode)
2393af6ab5fSopenharmony_ci{
2403af6ab5fSopenharmony_ci    ASSERT(!transformedNode_.has_value());
2413af6ab5fSopenharmony_ci    transformedNode->SetOriginalNode(this);
2423af6ab5fSopenharmony_ci    transformedNode_ = std::make_optional(std::make_pair(transformationName, transformedNode));
2433af6ab5fSopenharmony_ci}
2443af6ab5fSopenharmony_ci}  // namespace ark::es2panda::ir
245