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_DEBUG_INFO_STORAGE_H
17#define ES2PANDA_EVALUATE_DEBUG_INFO_STORAGE_H
18
19#include "evaluate/evaluateContext.h"
20#include "evaluate/importExportTable.h"
21#include "util/ustring.h"
22
23#include "libpandafile/debug_info_extractor.h"
24#include "libpandafile/file.h"
25#include "libpandafile/class_data_accessor.h"
26
27#include <memory>
28#include <optional>
29#include <string_view>
30#include <unordered_map>
31#include <utility>
32
33namespace ark::es2panda::evaluate {
34
35struct FileDebugInfo final {
36    using RecordsMap = ArenaUnorderedMap<util::StringView, panda_file::File::EntityId>;
37
38    FileDebugInfo() = delete;
39    explicit FileDebugInfo(std::unique_ptr<const panda_file::File> &&pandaFile, panda_file::File::EntityId classId,
40                           std::string_view module)
41        : pf(std::move(pandaFile)), globalClassAcc(*pf, classId), moduleName(module)
42    {
43        ASSERT(pf);
44    }
45
46    // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
47    std::unique_ptr<const panda_file::File> pf {nullptr};
48    panda_file::ClassDataAccessor globalClassAcc;
49    std::string_view moduleName;
50    std::string_view sourceFilePath;
51    std::optional<ImportExportTable> importExportTable;
52    std::optional<RecordsMap> records;
53    // NOLINTEND(misc-non-private-member-variables-in-classes)
54};
55
56// Context-independent debug info lazy-loading storage.
57// All "find" methods must accept paths to source files.
58class DebugInfoStorage final {
59public:
60    explicit DebugInfoStorage(const CompilerOptions &options, ArenaAllocator *allocator);
61
62    NO_COPY_SEMANTIC(DebugInfoStorage);
63    NO_MOVE_SEMANTIC(DebugInfoStorage);
64
65    ~DebugInfoStorage() = default;
66
67    ArenaAllocator *Allocator()
68    {
69        return allocator_;
70    }
71
72    [[nodiscard]] bool FillEvaluateContext(EvaluateContext &context);
73
74    const panda_file::File *GetPandaFile(std::string_view filePath);
75    const ImportExportTable *GetImportExportTable(std::string_view filePath);
76    panda_file::ClassDataAccessor *GetGlobalClassAccessor(std::string_view filePath);
77    std::string_view GetModuleName(std::string_view filePath);
78
79    FileDebugInfo *GetDebugInfoByModuleName(std::string_view moduleName) const;
80
81    /**
82     * @brief Returns class'es panda file Id on success, invalid EntityId otherwise
83     */
84    panda_file::File::EntityId FindClass(std::string_view filePath, std::string_view className);
85
86    template <typename Callback>
87    void EnumerateContextFiles(const Callback &cb)
88    {
89        for (const auto &[sourceFilePath, debugInfo] : sourceFileToDebugInfo_) {
90            if (!cb(sourceFilePath, debugInfo->pf.get(), debugInfo->globalClassAcc, debugInfo->moduleName)) {
91                return;
92            }
93        }
94    }
95
96private:
97    using DebugInfoMap = ArenaUnorderedMap<std::string_view, FileDebugInfo *>;
98
99private:
100    void LoadFileDebugInfo(std::string_view pfPath);
101
102    const ImportExportTable &LazyLoadImportExportTable(FileDebugInfo *info);
103    const FileDebugInfo::RecordsMap &LazyLoadRecords(FileDebugInfo *info);
104
105private:
106    ArenaAllocator *allocator_ {nullptr};
107
108    // Mapping from sources' files names into the corresponding debug information struct.
109    // Used for fast lookups basing on imports/exports tables.
110    DebugInfoMap sourceFileToDebugInfo_;
111    // Mapping from module names into the corresponding debug information struct.
112    // Used for fast lookups during inheritance chain resolution.
113    DebugInfoMap moduleNameToDebugInfo_;
114};
115
116}  // namespace ark::es2panda::evaluate
117
118#endif  // ES2PANDA_EVALUATE_DEBUG_INFO_STORAGE_H
119