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 #include "baseAnalyzer.h"
17 #include "assignAnalyzer.h"
18 #include "ir/astNode.h"
19 #include "ir/statements/breakStatement.h"
20 #include "ir/statements/continueStatement.h"
21 
22 namespace ark::es2panda::checker {
23 
24 template <typename T>
ClearPendingExits()25 void BaseAnalyzer<T>::ClearPendingExits()
26 {
27     pendingExits_.clear();
28     oldPendingExits_.clear();
29 }
30 
31 template <typename T>
PendingExits()32 typename BaseAnalyzer<T>::PendingExitsVector &BaseAnalyzer<T>::PendingExits()
33 {
34     return pendingExits_;
35 }
36 
37 template <typename T>
SetPendingExits(const PendingExitsVector &pendingExits)38 void BaseAnalyzer<T>::SetPendingExits(const PendingExitsVector &pendingExits)
39 {
40     pendingExits_ = pendingExits;
41 }
42 
43 template <typename T>
OldPendingExits()44 typename BaseAnalyzer<T>::PendingExitsVector &BaseAnalyzer<T>::OldPendingExits()
45 {
46     return oldPendingExits_;
47 }
48 
49 template <typename T>
SetOldPendingExits(const PendingExitsVector &oldPendingExits)50 void BaseAnalyzer<T>::SetOldPendingExits(const PendingExitsVector &oldPendingExits)
51 {
52     oldPendingExits_ = oldPendingExits;
53 }
54 
55 template <typename T>
GetJumpTarget(const ir::AstNode *node) const56 const ir::AstNode *BaseAnalyzer<T>::GetJumpTarget(const ir::AstNode *node) const
57 {
58     if (node->IsBreakStatement()) {
59         return node->AsBreakStatement()->Target();
60     }
61 
62     ASSERT(node->IsContinueStatement());
63     return node->AsContinueStatement()->Target();
64 }
65 
66 template <typename T>
ResolveJump(const ir::AstNode *node, ir::AstNodeType jumpKind)67 LivenessStatus BaseAnalyzer<T>::ResolveJump(const ir::AstNode *node, ir::AstNodeType jumpKind)
68 {
69     bool resolved = false;
70     PendingExitsVector exits = pendingExits_;
71     pendingExits_ = oldPendingExits_;
72 
73     for (auto &it : exits) {
74         if (it.Node()->Type() == jumpKind && node == GetJumpTarget(it.Node())) {
75             it.ResolveJump();
76             resolved = true;
77         } else {
78             pendingExits_.push_back(it);
79         }
80     }
81 
82     return From(resolved);
83 }
84 
85 template <typename T>
ResolveContinues(const ir::AstNode *node)86 LivenessStatus BaseAnalyzer<T>::ResolveContinues(const ir::AstNode *node)
87 {
88     oldPendingExits_.clear();
89     return ResolveJump(node, ir::AstNodeType::CONTINUE_STATEMENT);
90 }
91 
92 template <typename T>
ResolveBreaks(const ir::AstNode *node)93 LivenessStatus BaseAnalyzer<T>::ResolveBreaks(const ir::AstNode *node)
94 {
95     return ResolveJump(node, ir::AstNodeType::BREAK_STATEMENT);
96 }
97 
98 template class BaseAnalyzer<PendingExit>;
99 template class BaseAnalyzer<AssignPendingExit>;
100 
101 }  // namespace ark::es2panda::checker
102