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_EXPRESSION_IDENTIFIER_H
173af6ab5fSopenharmony_ci#define ES2PANDA_IR_EXPRESSION_IDENTIFIER_H
183af6ab5fSopenharmony_ci
193af6ab5fSopenharmony_ci#include "checker/checkerContext.h"
203af6ab5fSopenharmony_ci#include "ir/expression.h"
213af6ab5fSopenharmony_ci#include "ir/validationInfo.h"
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_cinamespace ark::es2panda::varbinder {
243af6ab5fSopenharmony_ciclass Variable;
253af6ab5fSopenharmony_ci}  // namespace ark::es2panda::varbinder
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_cinamespace ark::es2panda::ir {
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_ciusing ENUMBITOPS_OPERATORS;
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_cienum class IdentifierFlags : uint32_t {
323af6ab5fSopenharmony_ci    NONE = 0U,
333af6ab5fSopenharmony_ci    OPTIONAL = 1U << 0U,
343af6ab5fSopenharmony_ci    REFERENCE = 1U << 1U,
353af6ab5fSopenharmony_ci    TDZ = 1U << 2U,
363af6ab5fSopenharmony_ci    PRIVATE = 1U << 3U,
373af6ab5fSopenharmony_ci    GET = 1U << 4U,
383af6ab5fSopenharmony_ci    SET = 1U << 5U,
393af6ab5fSopenharmony_ci    IGNORE_BOX = 1U << 6U,
403af6ab5fSopenharmony_ci};
413af6ab5fSopenharmony_ci
423af6ab5fSopenharmony_ci}  // namespace ark::es2panda::ir
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_citemplate <>
453af6ab5fSopenharmony_cistruct enumbitops::IsAllowedType<ark::es2panda::ir::IdentifierFlags> : std::true_type {
463af6ab5fSopenharmony_ci};
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_cinamespace ark::es2panda::ir {
493af6ab5fSopenharmony_ci
503af6ab5fSopenharmony_ciclass Identifier : public AnnotatedExpression {
513af6ab5fSopenharmony_ciprivate:
523af6ab5fSopenharmony_ci    struct Tag {};
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_cipublic:
553af6ab5fSopenharmony_ci    Identifier() = delete;
563af6ab5fSopenharmony_ci    ~Identifier() override = default;
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_ci    NO_COPY_SEMANTIC(Identifier);
593af6ab5fSopenharmony_ci    NO_MOVE_SEMANTIC(Identifier);
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_cipublic:
623af6ab5fSopenharmony_ci    explicit Identifier(ArenaAllocator *const allocator) : Identifier("", allocator) {}
633af6ab5fSopenharmony_ci    explicit Identifier(util::StringView const name, ArenaAllocator *const allocator)
643af6ab5fSopenharmony_ci        : AnnotatedExpression(AstNodeType::IDENTIFIER), name_(name), decorators_(allocator->Adapter())
653af6ab5fSopenharmony_ci    {
663af6ab5fSopenharmony_ci    }
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ci    explicit Identifier(util::StringView const name, TypeNode *const typeAnnotation, ArenaAllocator *const allocator)
693af6ab5fSopenharmony_ci        : AnnotatedExpression(AstNodeType::IDENTIFIER, typeAnnotation), name_(name), decorators_(allocator->Adapter())
703af6ab5fSopenharmony_ci    {
713af6ab5fSopenharmony_ci    }
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci    explicit Identifier(Tag tag, Identifier const &other, ArenaAllocator *allocator);
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci    [[nodiscard]] const util::StringView &Name() const noexcept
763af6ab5fSopenharmony_ci    {
773af6ab5fSopenharmony_ci        return name_;
783af6ab5fSopenharmony_ci    }
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci    [[nodiscard]] util::StringView &Name() noexcept
813af6ab5fSopenharmony_ci    {
823af6ab5fSopenharmony_ci        return name_;
833af6ab5fSopenharmony_ci    }
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    void SetName(const util::StringView &newName) noexcept
863af6ab5fSopenharmony_ci    {
873af6ab5fSopenharmony_ci        name_ = newName;
883af6ab5fSopenharmony_ci    }
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_ci    [[nodiscard]] const ArenaVector<Decorator *> &Decorators() const noexcept
913af6ab5fSopenharmony_ci    {
923af6ab5fSopenharmony_ci        return decorators_;
933af6ab5fSopenharmony_ci    }
943af6ab5fSopenharmony_ci
953af6ab5fSopenharmony_ci    const ArenaVector<Decorator *> *DecoratorsPtr() const override
963af6ab5fSopenharmony_ci    {
973af6ab5fSopenharmony_ci        return &Decorators();
983af6ab5fSopenharmony_ci    }
993af6ab5fSopenharmony_ci
1003af6ab5fSopenharmony_ci    [[nodiscard]] bool IsOptional() const noexcept
1013af6ab5fSopenharmony_ci    {
1023af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::OPTIONAL) != 0;
1033af6ab5fSopenharmony_ci    }
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    void SetOptional(bool const optional) noexcept
1063af6ab5fSopenharmony_ci    {
1073af6ab5fSopenharmony_ci        if (optional) {
1083af6ab5fSopenharmony_ci            flags_ |= IdentifierFlags::OPTIONAL;
1093af6ab5fSopenharmony_ci        } else {
1103af6ab5fSopenharmony_ci            flags_ &= ~IdentifierFlags::OPTIONAL;
1113af6ab5fSopenharmony_ci        }
1123af6ab5fSopenharmony_ci    }
1133af6ab5fSopenharmony_ci
1143af6ab5fSopenharmony_ci    [[nodiscard]] bool IsReference() const noexcept
1153af6ab5fSopenharmony_ci    {
1163af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::REFERENCE) != 0;
1173af6ab5fSopenharmony_ci    }
1183af6ab5fSopenharmony_ci
1193af6ab5fSopenharmony_ci    void SetReference(bool const isReference = true) noexcept
1203af6ab5fSopenharmony_ci    {
1213af6ab5fSopenharmony_ci        if (isReference) {
1223af6ab5fSopenharmony_ci            flags_ |= IdentifierFlags::REFERENCE;
1233af6ab5fSopenharmony_ci        } else {
1243af6ab5fSopenharmony_ci            flags_ &= ~IdentifierFlags::REFERENCE;
1253af6ab5fSopenharmony_ci        }
1263af6ab5fSopenharmony_ci    }
1273af6ab5fSopenharmony_ci
1283af6ab5fSopenharmony_ci    [[nodiscard]] bool IsTdz() const noexcept
1293af6ab5fSopenharmony_ci    {
1303af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::TDZ) != 0;
1313af6ab5fSopenharmony_ci    }
1323af6ab5fSopenharmony_ci
1333af6ab5fSopenharmony_ci    void SetTdz() noexcept
1343af6ab5fSopenharmony_ci    {
1353af6ab5fSopenharmony_ci        flags_ |= IdentifierFlags::TDZ;
1363af6ab5fSopenharmony_ci    }
1373af6ab5fSopenharmony_ci
1383af6ab5fSopenharmony_ci    void SetAccessor() noexcept
1393af6ab5fSopenharmony_ci    {
1403af6ab5fSopenharmony_ci        flags_ |= IdentifierFlags::GET;
1413af6ab5fSopenharmony_ci    }
1423af6ab5fSopenharmony_ci
1433af6ab5fSopenharmony_ci    [[nodiscard]] bool IsAccessor() const noexcept
1443af6ab5fSopenharmony_ci    {
1453af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::GET) != 0;
1463af6ab5fSopenharmony_ci    }
1473af6ab5fSopenharmony_ci
1483af6ab5fSopenharmony_ci    void SetMutator() noexcept
1493af6ab5fSopenharmony_ci    {
1503af6ab5fSopenharmony_ci        flags_ |= IdentifierFlags::SET;
1513af6ab5fSopenharmony_ci    }
1523af6ab5fSopenharmony_ci
1533af6ab5fSopenharmony_ci    [[nodiscard]] bool IsMutator() const noexcept
1543af6ab5fSopenharmony_ci    {
1553af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::SET) != 0;
1563af6ab5fSopenharmony_ci    }
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci    [[nodiscard]] bool IsPrivateIdent() const noexcept
1593af6ab5fSopenharmony_ci    {
1603af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::PRIVATE) != 0;
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci
1633af6ab5fSopenharmony_ci    void SetPrivate(bool const isPrivate) noexcept
1643af6ab5fSopenharmony_ci    {
1653af6ab5fSopenharmony_ci        if (isPrivate) {
1663af6ab5fSopenharmony_ci            flags_ |= IdentifierFlags::PRIVATE;
1673af6ab5fSopenharmony_ci        } else {
1683af6ab5fSopenharmony_ci            flags_ &= ~IdentifierFlags::PRIVATE;
1693af6ab5fSopenharmony_ci        }
1703af6ab5fSopenharmony_ci    }
1713af6ab5fSopenharmony_ci
1723af6ab5fSopenharmony_ci    [[nodiscard]] bool IsIgnoreBox() const noexcept
1733af6ab5fSopenharmony_ci    {
1743af6ab5fSopenharmony_ci        return (flags_ & IdentifierFlags::IGNORE_BOX) != 0;
1753af6ab5fSopenharmony_ci    }
1763af6ab5fSopenharmony_ci
1773af6ab5fSopenharmony_ci    void SetIgnoreBox() noexcept
1783af6ab5fSopenharmony_ci    {
1793af6ab5fSopenharmony_ci        flags_ |= IdentifierFlags::IGNORE_BOX;
1803af6ab5fSopenharmony_ci    }
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci    void AddDecorators([[maybe_unused]] ArenaVector<ir::Decorator *> &&decorators) override
1833af6ab5fSopenharmony_ci    {
1843af6ab5fSopenharmony_ci        decorators_ = std::move(decorators);
1853af6ab5fSopenharmony_ci    }
1863af6ab5fSopenharmony_ci
1873af6ab5fSopenharmony_ci    [[nodiscard]] Identifier *Clone(ArenaAllocator *allocator, AstNode *parent) override;
1883af6ab5fSopenharmony_ci
1893af6ab5fSopenharmony_ci    bool CanHaveDecorator([[maybe_unused]] bool inTs) const override
1903af6ab5fSopenharmony_ci    {
1913af6ab5fSopenharmony_ci        return true;
1923af6ab5fSopenharmony_ci    }
1933af6ab5fSopenharmony_ci
1943af6ab5fSopenharmony_ci    [[nodiscard]] ValidationInfo ValidateExpression();
1953af6ab5fSopenharmony_ci
1963af6ab5fSopenharmony_ci    void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override;
1973af6ab5fSopenharmony_ci    void Iterate(const NodeTraverser &cb) const override;
1983af6ab5fSopenharmony_ci    void Dump(ir::AstDumper *dumper) const override;
1993af6ab5fSopenharmony_ci    void Dump(ir::SrcDumper *dumper) const override;
2003af6ab5fSopenharmony_ci    void Compile(compiler::PandaGen *pg) const override;
2013af6ab5fSopenharmony_ci    void Compile(compiler::ETSGen *etsg) const override;
2023af6ab5fSopenharmony_ci    checker::Type *Check(checker::TSChecker *checker) override;
2033af6ab5fSopenharmony_ci    checker::Type *Check(checker::ETSChecker *checker) override;
2043af6ab5fSopenharmony_ci
2053af6ab5fSopenharmony_ci    void Accept(ASTVisitorT *v) override
2063af6ab5fSopenharmony_ci    {
2073af6ab5fSopenharmony_ci        v->Accept(this);
2083af6ab5fSopenharmony_ci    }
2093af6ab5fSopenharmony_ci
2103af6ab5fSopenharmony_ciprivate:
2113af6ab5fSopenharmony_ci    util::StringView name_;
2123af6ab5fSopenharmony_ci    IdentifierFlags flags_ {IdentifierFlags::NONE};
2133af6ab5fSopenharmony_ci    ArenaVector<Decorator *> decorators_;
2143af6ab5fSopenharmony_ci};
2153af6ab5fSopenharmony_ci}  // namespace ark::es2panda::ir
2163af6ab5fSopenharmony_ci
2173af6ab5fSopenharmony_ci#endif
218