• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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