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_NON_RECURSIVE_IR_CHECKER_H 17#define ES2PANDA_EVALUATE_NON_RECURSIVE_IR_CHECKER_H 18 19#include "libpandabase/mem/arena_allocator.h" 20#include "libpandabase/utils/arena_containers.h" 21 22namespace ark::es2panda::checker { 23class ETSChecker; 24} // namespace ark::es2panda::checker 25 26namespace ark::es2panda::ir { 27class AstNode; 28} // namespace ark::es2panda::ir 29 30namespace ark::es2panda::parser { 31class Program; 32} // namespace ark::es2panda::parser 33 34namespace ark::es2panda::varbinder { 35class ETSBinder; 36class Scope; 37} // namespace ark::es2panda::varbinder 38 39namespace ark::es2panda::evaluate { 40 41/** 42 * @brief Helper class for running type checks 43 * All newly created IR nodes from debug-info must be checked through this class, 44 * otherwise recursive class creations can lead to varbinder scopes errors. 45 */ 46class IrCheckHelper final { 47public: 48 struct ScopedAstNode final { 49 ScopedAstNode(parser::Program *p, varbinder::Scope *s, ir::AstNode *parent, ir::AstNode *n) 50 : program(p), scope(s), parentClass(parent), node(n) 51 { 52 } 53 54 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 55 parser::Program *program {nullptr}; 56 varbinder::Scope *scope {nullptr}; 57 ir::AstNode *parentClass {nullptr}; 58 ir::AstNode *node {nullptr}; 59 // NOLINTEND(misc-non-private-member-variables-in-classes) 60 }; 61 62public: 63 explicit IrCheckHelper(checker::ETSChecker *checker, varbinder::ETSBinder *varBinder); 64 NO_COPY_SEMANTIC(IrCheckHelper); 65 NO_MOVE_SEMANTIC(IrCheckHelper); 66 ~IrCheckHelper() noexcept = default; 67 68 /** 69 * @brief Runs scope and type checks on the given IR node 70 * @param node to check, must not be null. 71 * @param scope to which node is relative to - if null, current checker scope is taken. 72 * @param parentClass class to use record table from, might be null. 73 * @param program relative to node - if null, current varbinder program is taken; 74 * either it or `scope` must be non-null. 75 * @returns false if check was delayed until recursion end, true if check was done immediately. 76 */ 77 bool CheckNewNode(ir::AstNode *node, varbinder::Scope *scope, ir::AstNode *parentClass, parser::Program *program); 78 79 void PreCheck(); 80 81 void CheckGlobalEntity(parser::Program *program, ir::AstNode *node, bool mustCheck = true); 82 void CheckLocalEntity(ir::AstNode *node); 83 84 checker::ETSChecker *GetChecker() const 85 { 86 return checker_; 87 } 88 89private: 90 void HandleCustomNodes(); 91 void CheckDecls(); 92 93private: 94 checker::ETSChecker *checker_ {nullptr}; 95 varbinder::ETSBinder *varBinder_ {nullptr}; 96 97 bool isRecursive_ {false}; 98 // List is required due to possible push-backs during iteration. 99 ArenaList<ScopedAstNode> recursiveDecls_; 100 // Indicates that PreCheck was called from ETSChecker::StartChecker() 101 bool isPrecheckPassed_ {false}; 102}; 103 104} // namespace ark::es2panda::evaluate 105 106#endif // ES2PANDA_EVALUATE_NON_RECURSIVE_IR_CHECKER_H 107