* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ES2PANDA_EVALUATE_NON_RECURSIVE_IR_CHECKER_H
#define ES2PANDA_EVALUATE_NON_RECURSIVE_IR_CHECKER_H
#include "libarkbase/mem/arena_allocator.h"
namespace ark::es2panda::checker {
class ETSChecker;
}
namespace ark::es2panda::ir {
class AstNode;
}
namespace ark::es2panda::parser {
class Program;
}
namespace ark::es2panda::varbinder {
class ETSBinder;
class Scope;
}
namespace ark::es2panda::evaluate {
* @brief Helper class for running type checks
* All newly created IR nodes from debug-info must be checked through this class,
* otherwise recursive class creations can lead to varbinder scopes errors.
*/
class IrCheckHelper final {
public:
struct ScopedAstNode final {
ScopedAstNode(parser::Program *p, varbinder::Scope *s, ir::AstNode *parent, ir::AstNode *n)
: program(p), scope(s), parentClass(parent), node(n)
{
}
parser::Program *program {nullptr};
varbinder::Scope *scope {nullptr};
ir::AstNode *parentClass {nullptr};
ir::AstNode *node {nullptr};
};
public:
explicit IrCheckHelper(checker::ETSChecker *checker, varbinder::ETSBinder *varBinder);
NO_COPY_SEMANTIC(IrCheckHelper);
NO_MOVE_SEMANTIC(IrCheckHelper);
~IrCheckHelper() noexcept = default;
* @brief Runs scope and type checks on the given IR node
* @param node to check, must not be null.
* @param scope to which node is relative to - if null, current checker scope is taken.
* @param parentClass class to use record table from, might be null.
* @param program relative to node - if null, current varbinder program is taken;
* either it or `scope` must be non-null.
* @returns false if check was delayed until recursion end, true if check was done immediately.
*/
bool CheckNewNode(ir::AstNode *node, varbinder::Scope *scope, ir::AstNode *parentClass, parser::Program *program);
void PreCheck();
void CheckGlobalEntity(parser::Program *program, ir::AstNode *node, bool mustCheck = true);
void CheckLocalEntity(ir::AstNode *node);
checker::ETSChecker *GetChecker() const
{
return checker_;
}
private:
void HandleCustomNodes();
void CheckDecls();
private:
checker::ETSChecker *checker_ {nullptr};
varbinder::ETSBinder *varBinder_ {nullptr};
bool isRecursive_ {false};
ArenaList<ScopedAstNode> recursiveDecls_;
bool isPrecheckPassed_ {false};
};
}
#endif