1/*
2 * Copyright (c) 2021-2022 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_COMPILER_CORE_ENV_SCOPE_H
17#define ES2PANDA_COMPILER_CORE_ENV_SCOPE_H
18
19#include <binder/scope.h>
20#include <ir/irnode.h>
21#include <compiler/core/dynamicContext.h>
22#include <compiler/core/regScope.h>
23#include <compiler/core/labelTarget.h>
24
25namespace panda::es2panda::ir {
26class AstNode;
27class Statement;
28}  // namespace panda::es2panda::ir
29
30namespace panda::es2panda::compiler {
31
32class PandaGen;
33
34class ScopeContext {
35public:
36    explicit ScopeContext(PandaGen *pg, binder::Scope *newScope);
37    ~ScopeContext();
38
39    NO_COPY_SEMANTIC(ScopeContext);
40    NO_MOVE_SEMANTIC(ScopeContext);
41
42private:
43    PandaGen *pg_;
44    binder::Scope *prevScope_;
45};
46
47class EnvScope {
48public:
49    explicit EnvScope() = default;
50
51    NO_COPY_SEMANTIC(EnvScope);
52    NO_MOVE_SEMANTIC(EnvScope);
53    ~EnvScope();
54
55    void Initialize(PandaGen *pg);
56
57    EnvScope *Prev() const
58    {
59        return prev_;
60    }
61
62protected:
63    friend class PandaGen;
64
65    PandaGen *pg_ {};
66    EnvScope *prev_ {};
67};
68
69class VariableEnvScope : public EnvScope {
70public:
71    explicit VariableEnvScope(PandaGen *pg, binder::VariableScope *scope, LabelTarget target)
72        : scope_(InitVariableContext(pg, scope) ? scope : nullptr), regScope_(pg, scope), lexEnvCtx_(this, pg, target)
73    {
74    }
75
76    bool HasEnv() const
77    {
78        return scope_ != nullptr;
79    }
80
81    binder::VariableScope *Scope() const
82    {
83        ASSERT(HasEnv());
84        return scope_;
85    }
86
87protected:
88    binder::VariableScope *scope_ {};
89
90private:
91    bool InitVariableContext(PandaGen *pg, binder::VariableScope *scope);
92
93    LocalRegScope regScope_;
94    LexEnvContext lexEnvCtx_;
95};
96
97class LoopEnvScope : public VariableEnvScope {
98public:
99    explicit LoopEnvScope(PandaGen *pg, binder::LoopScope *scope, LabelTarget target)
100        : VariableEnvScope(pg, scope, target)
101    {
102    }
103
104    explicit LoopEnvScope(PandaGen *pg, LabelTarget target, binder::LoopScope *scope)
105        : VariableEnvScope(pg, scope, target)
106    {
107    }
108
109    void CopyPerIterationCtx();
110};
111
112}  // namespace panda::es2panda::compiler
113
114#endif
115