1/*
2 * Copyright (c) 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 ES2PANDA_EVALUATE_ENTITY_DECLARATOR_H
17#define ES2PANDA_EVALUATE_ENTITY_DECLARATOR_H
18
19#include "checker/ETSchecker.h"
20#include "evaluate/proxyProgramsCache.h"
21#include "evaluate/helpers.h"
22#include "libpandabase/utils/arena_containers.h"
23
24namespace ark::es2panda::parser {
25class Program;
26}  // namespace ark::es2panda::parser
27
28namespace ark::es2panda::varbinder {
29class Variable;
30}  // namespace ark::es2panda::varbinder
31
32namespace ark::es2panda::ir {
33class Statement;
34}  // namespace ark::es2panda::ir
35
36namespace ark::es2panda::evaluate {
37
38using UMapStringViewVariable = ArenaUnorderedMap<util::StringView, varbinder::Variable *>;
39
40/// @brief Helps to declare entities created by debug-info plugin in AST.
41class EntityDeclarator final {
42public:
43    NO_COPY_SEMANTIC(EntityDeclarator);
44    NO_MOVE_SEMANTIC(EntityDeclarator);
45
46    explicit EntityDeclarator(ScopedDebugInfoPlugin &debugInfoPlugin);
47    ~EntityDeclarator() = default;
48
49    /**
50     * @brief Invoke \p irCreator if entity was not already created and then create import declaration if it is needed
51     *
52     * If a variable of an entity that comes as a result of invoking irCreator is used in a program that does not match
53     * the program where the entity was declared, then ImportGlobalEntity inserts an import declaration into the AST.
54     */
55    template <typename F>
56    varbinder::Variable *ImportGlobalEntity(util::StringView pathToDeclSource, util::StringView declName,
57                                            parser::Program *importerProgram, util::StringView importedName,
58                                            F &&irCreator);
59
60    /**
61     * @brief Returns true if the entity has already been declared, or false otherwise
62     */
63    bool IsEntityDeclared(parser::Program *program, util::StringView name);
64
65private:
66    static varbinder::Variable *FindEntityVariable(UMapStringViewVariable &entitiesMap, util::StringView entityName);
67
68    UMapStringViewVariable &GetOrCreateEntitiesMap(parser::Program *program);
69
70    void CreateAndInsertImportStatement(util::StringView pathToDeclSource, util::StringView declName,
71                                        parser::Program *importerProgram, util::StringView importedName,
72                                        varbinder::Variable *var);
73
74    ir::ETSImportDeclaration *CreateIrImport(util::StringView pathToDeclSourceFile, util::StringView classDeclName,
75                                             util::StringView classImportedName);
76
77    void InsertImportStatement(ir::Statement *importStatement, parser::Program *importerProgram);
78
79private:
80    ScopedDebugInfoPlugin &debugInfoPlugin_;
81
82    ArenaUnorderedMap<parser::Program *, UMapStringViewVariable> createdEntities_;
83};
84
85}  // namespace ark::es2panda::evaluate
86
87#endif  // ES2PANDA_EVALUATE_ENTITY_DECLARATOR_H
88