1/*
2 * Copyright (c) 2023 - 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef PANDA_GLOBALDECLTRANSFORMER_H
17#define PANDA_GLOBALDECLTRANSFORMER_H
18
19#include "util/helpers.h"
20#include "compiler/lowering/phase.h"
21#include "ir/visitor/IterateAstVisitor.h"
22
23namespace ark::es2panda::compiler {
24
25class GlobalDeclTransformer : public ir::visitor::CustomAstVisitor {
26    const std::unordered_set<ir::AstNodeType> typeDecl_ = {
27        ir::AstNodeType::CLASS_DECLARATION,         ir::AstNodeType::STRUCT_DECLARATION,
28        ir::AstNodeType::TS_ENUM_DECLARATION,       ir::AstNodeType::TS_INTERFACE_DECLARATION,
29        ir::AstNodeType::ETS_PACKAGE_DECLARATION,   ir::AstNodeType::ETS_IMPORT_DECLARATION,
30        ir::AstNodeType::TS_TYPE_ALIAS_DECLARATION, ir::AstNodeType::EXPORT_ALL_DECLARATION,
31        ir::AstNodeType::EXPORT_NAMED_DECLARATION,  ir::AstNodeType::REEXPORT_STATEMENT,
32        ir::AstNodeType::NAMESPACE_DECLARATION,
33    };
34
35    const std::unordered_set<ir::AstNodeType> propertiesDecl_ = {
36        ir::AstNodeType::FUNCTION_DECLARATION,
37        ir::AstNodeType::VARIABLE_DECLARATION,
38    };
39
40public:
41    struct ResultT {
42        explicit ResultT(ArenaAllocator *alloc) : classProperties(alloc->Adapter()), initStatements(alloc->Adapter()) {}
43
44        // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
45        ArenaVector<ir::Statement *> classProperties;
46        // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
47        ArenaVector<ir::Statement *> initStatements;
48    };
49
50    explicit GlobalDeclTransformer(ArenaAllocator *allocator) : allocator_(allocator), result_(allocator) {}
51
52    /**
53     * Removes top level statements, global variable declarations, global function declarations
54     * @param stmts
55     */
56    void FilterDeclarations(ArenaVector<ir::Statement *> &stmts);
57
58    /**
59     * Creates ClassProperty for global variables and MethodFunction for global functions.
60     * Copy top level statements to vector.
61     * @param stmts top level statements
62     * @param addInitializer $init$ should contain global variable initializers
63     * @return pair (class properties, init statements)
64     */
65    ResultT TransformStatements(const ArenaVector<ir::Statement *> &stmts, bool addInitializer);
66
67    void VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) override;
68    void VisitVariableDeclaration(ir::VariableDeclaration *varDecl) override;
69    void HandleNode(ir::AstNode *node) override;
70
71    ir::Identifier *RefIdent(const util::StringView &name);
72
73    ir::ExpressionStatement *InitTopLevelProperty(ir::ClassProperty *classProperty);
74
75private:
76    ArenaAllocator *allocator_;
77    ResultT result_;
78    bool addInitializer_ = true;
79};
80
81}  // namespace ark::es2panda::compiler
82#endif  // PANDA_GLOBALDECLTRANSFORMER_H
83