* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ES2PANDA_IR_ETS_MODULE_H
#define ES2PANDA_IR_ETS_MODULE_H
#include "ir/statements/blockStatement.h"
#include "ir/annotationAllowed.h"
#include "ir/expressions/identifier.h"
#include "ir/srcDump.h"
namespace ark::es2panda::parser {
class Program;
}
namespace ark::es2panda::ir {
using ENUMBITOPS_OPERATORS;
enum class ModuleFlag : uint32_t {
NONE = 0,
ETSSCRIPT = 1U << 0U,
NAMESPACE = 1U << 1U,
NAMESPACE_CHAIN_LAST_NODE = 1U << 2U
};
}
template <>
struct enumbitops::IsAllowedType<ark::es2panda::ir::ModuleFlag> : std::true_type {
};
namespace ark::es2panda::ir {
class ETSModule : public AnnotationAllowed<BlockStatement> {
public:
explicit ETSModule(ArenaAllocator *allocator, ArenaVector<Statement *> &&statementList, Identifier *ident,
ModuleFlag flag, Language lang, parser::Program *program)
: AnnotationAllowed<BlockStatement>(allocator, std::move(statementList)),
ident_(ident),
flag_(flag),
lang_(lang),
program_(program)
{
SetType(AstNodeType::ETS_MODULE);
InitHistory();
}
explicit ETSModule(ArenaAllocator *allocator, ArenaVector<Statement *> &&statementList, Identifier *ident,
ModuleFlag flag, Language lang, parser::Program *program, AstNodeHistory *history)
: AnnotationAllowed<BlockStatement>(allocator, std::move(statementList)),
ident_(ident),
flag_(flag),
lang_(lang),
program_(program)
{
SetType(AstNodeType::ETS_MODULE);
if (history != nullptr) {
SetHistoryInternal(history);
} else {
InitHistory();
}
}
ir::Identifier *Ident()
{
return GetHistoryNodeAs<ETSModule>()->ident_;
}
const ir::Identifier *Ident() const
{
return GetHistoryNodeAs<ETSModule>()->ident_;
}
void SetIdent(ir::Identifier *ident)
{
auto newNode = GetOrCreateHistoryNodeAs<ETSModule>();
newNode->ident_ = ident;
if (ident != nullptr) {
ident->SetParent(newNode);
}
}
parser::Program *Program()
{
return GetHistoryNodeAs<ETSModule>()->program_;
}
const ir::ClassDefinition *GlobalClass() const
{
return GetHistoryNodeAs<ETSModule>()->globalClass_;
}
[[nodiscard]] es2panda::Language Language() const noexcept
{
return GetHistoryNodeAs<ETSModule>()->lang_;
}
ir::ClassDefinition *GlobalClass()
{
return GetHistoryNodeAs<ETSModule>()->globalClass_;
}
void SetGlobalClass(ir::ClassDefinition *globalClass)
{
if (globalClass != GlobalClass()) {
GetOrCreateHistoryNode()->AsETSModule()->globalClass_ = globalClass;
}
}
[[nodiscard]] bool IsETSScript() const noexcept
{
return (ModuleFlags() & ModuleFlag::ETSSCRIPT) != 0;
}
[[nodiscard]] bool IsNamespace() const noexcept
{
return (ModuleFlags() & ModuleFlag::NAMESPACE) != 0;
}
[[nodiscard]] bool IsNamespaceChainLastNode() const noexcept
{
return (ModuleFlags() & ModuleFlag::NAMESPACE_CHAIN_LAST_NODE) != 0;
}
void SetNamespaceChainLastNode() noexcept
{
ES2PANDA_ASSERT(IsNamespace());
AddModuleFlag(ModuleFlag::NAMESPACE_CHAIN_LAST_NODE);
}
const parser::Program *Program() const
{
return GetHistoryNodeAs<ETSModule>()->program_;
}
void Dump(ir::SrcDumper *dumper) const override;
void Accept(ASTVisitorT *v) override
{
v->Accept(this);
}
ETSModule *Construct(ArenaAllocator *allocator) override;
void CopyTo(AstNode *other) const override;
private:
friend class SizeOfNodeTest;
ModuleFlag ModuleFlags() const
{
return GetHistoryNodeAs<ETSModule>()->flag_;
}
void AddModuleFlag(ModuleFlag flag) noexcept
{
if (!All(ModuleFlags(), flag)) {
GetOrCreateHistoryNode()->AsETSModule()->flag_ |= flag;
}
}
void ClearModuleFlag(ModuleFlag flag) noexcept
{
if (Any(ModuleFlags(), flag)) {
GetOrCreateHistoryNode()->AsETSModule()->flag_ &= ~flag;
}
}
Identifier *ident_;
ModuleFlag flag_;
es2panda::Language lang_;
parser::Program *program_;
ir::ClassDefinition *globalClass_ {};
};
}
#endif