/* * Copyright (c) 2024 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_SCOPED_DEBUG_INFO_PLUGIN_H #define ES2PANDA_EVALUATE_SCOPED_DEBUG_INFO_PLUGIN_H #include "evaluate/debugInfoStorage.h" #include "evaluate/evaluateContext.h" #include "evaluate/helpers.h" #include "evaluate/irCheckHelper.h" #include "evaluate/proxyProgramsCache.h" #include "evaluate/pathResolver.h" #include "evaluate/entityDeclarator.h" #include "evaluate/debugInfoDeserialization/debugInfoDeserializer.h" namespace ark::es2panda::ir { class BlockStatement; class Statement; } // namespace ark::es2panda::ir namespace ark::es2panda::varbinder { class ETSBinder; class Variable; } // namespace ark::es2panda::varbinder namespace ark::es2panda::evaluate { /// @brief Context-dependent debug info plugin. Must be created before parsing phase. class ScopedDebugInfoPlugin final { public: explicit ScopedDebugInfoPlugin(parser::Program *globalProgram, checker::ETSChecker *checker, const CompilerOptions &options); NO_COPY_SEMANTIC(ScopedDebugInfoPlugin); NO_MOVE_SEMANTIC(ScopedDebugInfoPlugin); ~ScopedDebugInfoPlugin() = default; /** * @brief Searches debug-info for the given identifier * @param ident node with name of either a local or global variable or a class */ varbinder::Variable *FindIdentifier(ir::Identifier *ident); /** * @brief Searches debug-info for the given class * On success creates IR for this and all dependencies. */ varbinder::Variable *FindClass(ir::Identifier *ident); /** * @brief Adds collected prologue and epilogue statements in the block * In effect, previously collected prologue-epilogue statements are dropped. */ void AddPrologueEpilogue(ir::BlockStatement *block); /** * @brief Save \p stmt node to be pushed later at the beginning or end of the \p block depending on the IS_PROLOGUE * parameter */ template void RegisterPrologueEpilogue(ir::BlockStatement *block, ir::Statement *stmt); /** * @brief Initialization before ETSChecker starts checking AST * Since we can resolve references like `new A()`, that resolved before ETSChecker was started, * we need such a precheck call. */ void PreCheck(); /** * @brief Finalization after ETSChecker checks the main program */ void PostCheck(); PathResolver *GetPathResolver() { return &pathResolver_; } const PathResolver *GetPathResolver() const { return &pathResolver_; } IrCheckHelper *GetIrCheckHelper() { return &irCheckHelper_; } const IrCheckHelper *GetIrCheckHelper() const { return &irCheckHelper_; } DebugInfoStorage *GetDebugInfoStorage() { return &debugInfoStorage_; } const DebugInfoStorage *GetDebugInfoStorage() const { return &debugInfoStorage_; } ProxyProgramsCache *GetProxyProgramsCache() { return &proxyProgramsCache_; } const ProxyProgramsCache *GetProxyProgramsCache() const { return &proxyProgramsCache_; } EntityDeclarator *GetEntityDeclarator() { return &entityDeclarator_; } const EntityDeclarator *GetEntityDeclarator() const { return &entityDeclarator_; } DebugInfoDeserializer *GetDebugInfoDeserializer() { return &debugInfoDeserializer_; } const DebugInfoDeserializer *GetDebugInfoDeserializer() const { return &debugInfoDeserializer_; } varbinder::ETSBinder *GetETSBinder(); private: using PrologueEpiloguePair = std::pair, ArenaVector>; using PrologueEpilogueMap = ArenaUnorderedMap; private: /** * @brief Asserts correctness of input options. */ void ValidateEvaluationOptions(const CompilerOptions &options); /** * @brief Creates `Program` instances for each input context .abc file. */ void CreateContextPrograms(); /** * @brief Creates a program with the given package name and adds it as external for the given global program. * This method must be called once and before running any compiler phases. * @param sourceFilePath corresponding to source code of one of the provided .abc files. * @param moduleName of source file, extracted from .abc file encoding. * @returns pointer to initialized program. */ parser::Program *CreateEmptyProgram(std::string_view sourceFilePath, std::string_view moduleName); /** * @brief Returns non-null program for the given source file path. */ parser::Program *GetProgram(util::StringView fileName); parser::Program *GetEvaluatedExpressionProgram(); /// Search methods. varbinder::Variable *FindGlobalVariable(ir::Identifier *ident); varbinder::Variable *FindGlobalFunction(ir::Identifier *ident); varbinder::Variable *FindLocalVariable(ir::Identifier *ident); /** * @brief Pushes back return statement into the evaluation method * if its last statement potentially returns a primitive value. * @returns true if insertion took place, false otherwise. */ bool InsertReturnStatement(); ArenaAllocator *Allocator(); private: parser::Program *globalProgram_ {nullptr}; checker::ETSChecker *checker_ {nullptr}; EvaluateContext context_; IrCheckHelper irCheckHelper_; DebugInfoStorage debugInfoStorage_; DebugInfoDeserializer debugInfoDeserializer_; PathResolver pathResolver_; PrologueEpilogueMap prologueEpilogueMap_; ProxyProgramsCache proxyProgramsCache_; EntityDeclarator entityDeclarator_; }; } // namespace ark::es2panda::evaluate #endif // ES2PANDA_EVALUATE_SCOPED_DEBUG_INFO_PLUGIN_H