1/*
2 * Copyright (c) 2021-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_COMPILER_CHECKER_ETS_BASE_ANALYZER_H
17#define ES2PANDA_COMPILER_CHECKER_ETS_BASE_ANALYZER_H
18
19#include "utils/arena_containers.h"
20#include "util/enumbitops.h"
21
22namespace ark::es2panda::ir {
23class AstNode;
24enum class AstNodeType;
25}  // namespace ark::es2panda::ir
26
27namespace ark::es2panda::checker {
28class ETSChecker;
29
30using ENUMBITOPS_OPERATORS;
31
32enum class LivenessStatus { DEAD, ALIVE };
33
34class PendingExit {
35public:
36    using JumpResolver = std::function<void()>;
37
38    explicit PendingExit(
39        const ir::AstNode *node, JumpResolver jumpResolver = [] {})
40        : node_(node), jumpResolver_(std::move(jumpResolver))
41    {
42    }
43    virtual ~PendingExit() = default;
44
45    DEFAULT_COPY_SEMANTIC(PendingExit);
46    DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PendingExit);
47
48    virtual void ResolveJump()
49    {
50        jumpResolver_();
51    }
52
53    const ir::AstNode *Node() const
54    {
55        return node_;
56    }
57
58private:
59    const ir::AstNode *node_;
60    JumpResolver jumpResolver_;
61};
62
63template <typename T>
64class BaseAnalyzer {
65public:
66    using PendingExitsVector = std::vector<T>;
67
68    explicit BaseAnalyzer() = default;
69
70    virtual void MarkDead() = 0;
71
72    void RecordExit(const T &pe)
73    {
74        pendingExits_.push_back(pe);
75        MarkDead();
76    }
77
78    LivenessStatus From(bool value)
79    {
80        return value ? LivenessStatus::ALIVE : LivenessStatus::DEAD;
81    }
82
83    LivenessStatus ResolveJump(const ir::AstNode *node, ir::AstNodeType jumpKind);
84    LivenessStatus ResolveContinues(const ir::AstNode *node);
85    LivenessStatus ResolveBreaks(const ir::AstNode *node);
86    const ir::AstNode *GetJumpTarget(const ir::AstNode *node) const;
87
88protected:
89    void ClearPendingExits();
90    PendingExitsVector &PendingExits();
91    void SetPendingExits(const PendingExitsVector &pendingExits);
92    PendingExitsVector &OldPendingExits();
93    void SetOldPendingExits(const PendingExitsVector &oldPendingExits);
94
95private:
96    PendingExitsVector pendingExits_;
97    PendingExitsVector oldPendingExits_;
98};
99}  // namespace ark::es2panda::checker
100
101template <>
102struct enumbitops::IsAllowedType<ark::es2panda::checker::LivenessStatus> : std::true_type {
103};
104
105#endif
106