1 /** 2 * Copyright (c) 2024-2025 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_UTIL_IMPORT_PATH_MANAGER_H 17 #define ES2PANDA_UTIL_IMPORT_PATH_MANAGER_H 18 19 #if defined PANDA_TARGET_MOBILE 20 #define USE_UNIX_SYSCALL 21 #endif 22 23 #include "util/arktsconfig.h" 24 #include "util/ustring.h" 25 #include "util/enumbitops.h" 26 #include "util/path.h" 27 #include "util/options.h" 28 29 namespace ark::es2panda::util { 30 namespace gen::extension { 31 enum Enum : size_t; 32 } // namespace gen::extension 33 34 using ENUMBITOPS_OPERATORS; 35 36 enum class ImportFlags { 37 NONE = 0U, 38 DEFAULT_IMPORT = 1U << 1U, 39 IMPLICIT_PACKAGE_IMPORT = 1U << 2U, 40 }; 41 42 } // namespace ark::es2panda::util 43 44 namespace enumbitops { 45 template <> 46 struct IsAllowedType<ark::es2panda::util::ImportFlags> : std::true_type { 47 }; 48 } // namespace enumbitops 49 50 namespace ark::es2panda::ir { 51 class StringLiteral; 52 } // namespace ark::es2panda::ir 53 54 namespace ark::es2panda::parser { 55 class ParserContext; 56 } // namespace ark::es2panda::parser 57 58 namespace ark::es2panda::util { 59 60 enum class ModuleKind { MODULE, DECLARATION, PACKAGE }; 61 62 struct ModuleInfo { 63 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 64 StringView moduleName {}; 65 StringView modulePrefix {}; 66 ModuleKind kind {}; 67 // NOTE(dkofanov): Should be refactored and aligned with 'ModuleKind' and 68 // 'Program::MaybeTransformToDeclarationModule'. 69 bool isDeclForDynamicStaticInterop {}; 70 // NOLINTEND(misc-non-private-member-variables-in-classes) 71 }; 72 73 class ImportPathManager { 74 public: 75 static constexpr auto DUMMY_PATH = "dummy_path"; // CC-OFF(G.NAM.03-CPP) project code style 76 struct ImportMetadata { 77 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 78 ImportFlags importFlags {}; 79 Language::Id lang {Language::Id::COUNT}; 80 std::string_view resolvedSource {}; 81 std::string_view declPath {}; 82 std::string_view ohmUrl {}; 83 // NOLINTEND(misc-non-private-member-variables-in-classes) 84 85 bool HasSpecifiedDeclPath() const 86 { 87 return !declPath.empty() && (declPath != DUMMY_PATH); 88 } 89 90 bool IsImplicitPackageImported() const 91 { 92 return (importFlags & ImportFlags::IMPLICIT_PACKAGE_IMPORT) != 0; 93 } 94 95 bool IsValid() const; 96 }; 97 98 struct ParseInfo { 99 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 100 bool isParsed {}; 101 ImportMetadata importData; 102 // NOLINTEND(misc-non-private-member-variables-in-classes) 103 }; 104 105 ImportPathManager(ark::ArenaAllocator *allocator, const util::Options &options, parser::Program *globalProgram, 106 util::DiagnosticEngine &diagnosticEngine) 107 : allocator_(allocator), 108 arktsConfig_(options.ArkTSConfig()), 109 absoluteEtsPath_( 110 options.GetEtsPath().empty() ? "" : util::Path(options.GetEtsPath(), allocator_).GetAbsolutePath()), 111 stdLib_(options.GetStdlib()), 112 parseList_(allocator->Adapter()), 113 globalProgram_(globalProgram), 114 diagnosticEngine_ {diagnosticEngine} 115 { 116 } 117 118 NO_COPY_SEMANTIC(ImportPathManager); 119 NO_MOVE_SEMANTIC(ImportPathManager); 120 ImportPathManager() = delete; 121 ~ImportPathManager() = default; 122 123 [[nodiscard]] const ArenaVector<ParseInfo> &ParseList() const 124 { 125 return parseList_; 126 } 127 128 [[nodiscard]] ArenaVector<ParseInfo> &ParseList() 129 { 130 return parseList_; 131 } 132 133 util::StringView FormModuleName(const util::Path &path, const lexer::SourcePosition &srcPos); 134 ImportMetadata GatherImportMetadata(parser::Program *program, ImportFlags importFlags, 135 ir::StringLiteral *importPath); 136 void AddImplicitPackageImportToParseList(StringView packageDir, const lexer::SourcePosition &srcPos); 137 138 // API version for resolving paths. Kept only for API compatibility. Doesn't support 'dynamicPath'. 139 util::StringView ResolvePathAPI(StringView curModulePath, ir::StringLiteral *importPath) const; 140 141 void MarkAsParsed(StringView path); 142 util::StringView FormRelativePath(const util::Path &path); 143 std::shared_ptr<const ArkTsConfig> ArkTSConfig() const 144 { 145 return arktsConfig_; 146 } 147 148 void AddToParseList(const ImportMetadata importMetadata); 149 150 private: 151 util::StringView FormModuleNameSolelyByAbsolutePath(const util::Path &path); 152 util::StringView FormModuleName(const util::Path &path); 153 154 struct ResolvedPathRes { 155 // On successfull resolving, 2 variants are possible: 156 // `resolvedPath` is a module-path - if dynamic path was resolved; 157 // `resolvedPath` is a realpath - if static path was resolved. 158 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 159 std::string_view resolvedPath; 160 bool resolvedIsDynamic {false}; 161 // NOLINTEND(misc-non-private-member-variables-in-classes) 162 }; 163 ResolvedPathRes ResolvePath(std::string_view curModulePath, ir::StringLiteral *importPath) const; 164 ResolvedPathRes ResolveAbsolutePath(const ir::StringLiteral &importPathNode) const; 165 std::string_view DirOrDirWithIndexFile(StringView dir) const; 166 ResolvedPathRes AppendExtensionOrIndexFileIfOmitted(StringView basePath) const; 167 std::string TryMatchDynamicPath(std::string_view fixedPath) const; 168 StringView GetRealPath(StringView path) const; 169 170 #ifdef USE_UNIX_SYSCALL 171 void UnixWalkThroughDirectoryAndAddToParseList(ImportMetadata importMetadata); 172 #endif 173 174 private: 175 ark::ArenaAllocator *const allocator_; 176 std::shared_ptr<ArkTsConfig> const arktsConfig_; 177 std::string absoluteEtsPath_; 178 std::string stdLib_; 179 ArenaVector<ParseInfo> parseList_; 180 parser::Program *globalProgram_; 181 util::DiagnosticEngine &diagnosticEngine_; 182 std::string_view pathDelimiter_ {ark::os::file::File::GetPathDelim()}; 183 mutable const lexer::SourcePosition *srcPos_ {}; 184 bool isDynamic_ = false; 185 }; 186 187 } // namespace ark::es2panda::util 188 189 #endif // ES2PANDA_UTIL_IMPORT_PATH_MANAGER_H 190