• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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_AOT_ARKTSCONFIG_H
17 #define ES2PANDA_AOT_ARKTSCONFIG_H
18 
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "util/language.h"
27 #include "util/diagnostic.h"
28 #include "libpandabase/utils/json_builder.h"
29 #include "libpandabase/utils/json_parser.h"
30 
31 // NOTE(ivagin): If ARKTSCONFIG_USE_FILESYSTEM is not defined part of ArkTsConfig functionality is disabled.
32 //       Only build configuration which prevents us from usage of std::filesystem is "MOBILE" build
33 //       because of lack of std::filesystem in our current version of mobile nativ development kit.
34 //       nativ development kit version should be updated and ARKTSCONFIG_USE_FILESYSTEM removed
35 #if not defined PANDA_TARGET_MOBILE
36 #define ARKTSCONFIG_USE_FILESYSTEM
37 #endif
38 
39 #ifndef ARKTSCONFIG_USE_FILESYSTEM
40 #include <dirent.h>
41 #include <sys/types.h>
42 #else
43 #if __has_include(<filesystem>)
44 #include <filesystem>
45 namespace fs = std::filesystem;
46 #elif __has_include(<experimental/filesystem>)
47 #include <experimental/filesystem>
48 namespace fs = std::experimental::filesystem;
49 #endif
50 #endif
51 
52 namespace ark::es2panda::util {
53 class DiagnosticEngine;
54 }  // namespace ark::es2panda::util
55 
56 namespace ark::es2panda {
57 
58 struct CompareByLength {
operatorCompareByLength59     bool operator()(const std::string &x, const std::string &y) const
60     {
61         return x.size() == y.size() ? x > y : x.size() > y.size();
62     }
63 };
64 
65 class ArkTsConfig {
66     using PathsMap = std::map<std::string, std::vector<std::string>, CompareByLength>;
67 
68 public:
69 #ifdef ARKTSCONFIG_USE_FILESYSTEM
70     // Pattern describes arktsconfig path pattern for 'include' or 'exclude' properties
71     // e.g. src/**, src/**/*, src/util?.ts
72     class Pattern {
73     public:
74         Pattern() = default;
75         Pattern(std::string value, std::string base);
76 
77         bool IsPattern() const;
78 
79         // Get root from which sources file search should be started
80         // e.g. src/** -> src; src/index?.ts -> src; src/component/*/index.ts -> src/component; src/index* -> src/
81         std::string GetSearchRoot() const;
82 
83         // Test if absolute path is matched by pattern
84         bool Match(const std::string &path) const;
85 
86     private:
87         std::string value_ {};
88         std::string base_ {};
89     };
90 #endif  // ARKTSCONFIG_USE_FILESYSTEM
91 
92     class DynamicImportData {
93     public:
DynamicImportData(Language lang,std::string declPath,std::string ohmUrl)94         explicit DynamicImportData(Language lang, std::string declPath, std::string ohmUrl)
95             : lang_(lang), declPath_(std::move(declPath)), ohmUrl_(std::move(ohmUrl))
96         {
97         }
98 
GetLanguage()99         Language GetLanguage() const
100         {
101             return lang_;
102         }
103 
DeclPath()104         std::string_view DeclPath() const
105         {
106             return declPath_;
107         }
108 
OhmUrl()109         std::string_view OhmUrl() const
110         {
111             return ohmUrl_;
112         }
113 
114     private:
115         Language lang_;
116         std::string declPath_ {};
117         std::string ohmUrl_ {};
118     };
119 
ArkTsConfig(std::string_view configPath,util::DiagnosticEngine & de)120     explicit ArkTsConfig(std::string_view configPath, util::DiagnosticEngine &de)
121         : configPath_(configPath), diagnosticEngine_(de)
122     {
123     }
124     bool Parse(std::unordered_set<std::string> &parsedConfigPath);
125 
126     std::optional<std::string> ResolvePath(std::string_view path, bool isDynamic = false) const;
127 
128     void ResolveAllDependenciesInArkTsConfig();
129 
ConfigPath()130     const std::string &ConfigPath() const
131     {
132         return configPath_;
133     }
134 
Package()135     const std::string &Package() const
136     {
137         return package_;
138     }
BaseUrl()139     const std::string &BaseUrl() const
140     {
141         return baseUrl_;
142     }
RootDir()143     const std::string &RootDir() const
144     {
145         return rootDir_;
146     }
OutDir()147     const std::string &OutDir() const
148     {
149         return outDir_;
150     }
Dependencies()151     const std::unordered_map<std::string, std::shared_ptr<ArkTsConfig>> &Dependencies() const
152     {
153         return dependencies_;
154     }
ResetDependencies()155     void ResetDependencies()
156     {
157         return dependencies_.clear();
158     }
Entry()159     const std::string &Entry() const
160     {
161         return entry_;
162     }
Entries()163     const std::unordered_map<std::string, std::string> &Entries() const
164     {
165         return entries_;
166     }
Files()167     const std::vector<std::string> &Files() const
168     {
169         return files_;
170     }
UseUrl()171     const bool &UseUrl() const
172     {
173         return useUrl_;
174     }
Paths()175     const PathsMap &Paths() const
176     {
177         return paths_;
178     }
DynamicPaths()179     const std::map<std::string, DynamicImportData, CompareByLength> &DynamicPaths() const
180     {
181         return dynamicPaths_;
182     }
183 #ifdef ARKTSCONFIG_USE_FILESYSTEM
Include()184     const std::vector<Pattern> &Include() const
185     {
186         return include_;
187     }
Exclude()188     const std::vector<Pattern> &Exclude() const
189     {
190         return exclude_;
191     }
192     fs::path ComputeDestination(const fs::path &src, const fs::path &rootDir, const fs::path &outDir);
193 #endif  // ARKTSCONFIG_USE_FILESYSTEM
194     bool Check(bool cond, const diagnostic::DiagnosticKind &diag, const util::DiagnosticMessageParams &params);
195 
196 private:
197     bool ParseCompilerOptions(std::string &arktsConfigDir, std::unordered_set<std::string> &parsedConfigPath,
198                               const JsonObject *arktsConfig);
199     std::optional<ArkTsConfig> ParseExtends(const std::string &configPath, const std::string &extends,
200                                             const std::string &configDir,
201                                             std::unordered_set<std::string> &parsedConfigPath);
202     bool ParsePaths(const JsonObject::JsonObjPointer *options, PathsMap &pathsMap, const std::string &baseUrl);
203     bool ParseDynamicPaths(const JsonObject::JsonObjPointer *options,
204                            std::map<std::string, DynamicImportData, CompareByLength> &dynamicPathsMap,
205                            const std::string &baseUrl);
206     bool ParseSingleDynamicPath(const std::string &key, const JsonObject::JsonObjPointer *data,
207                                 std::map<std::string, DynamicImportData, CompareByLength> &dynamicPathsMap,
208                                 const std::string &baseUrl);
209     template <class Collection, class Function>
210     bool ParseCollection(const JsonObject *config, Collection &out, const std::string &target, Function &&constructor);
211     void ResolveConfigDependencies(std::unordered_map<std::string, std::shared_ptr<ArkTsConfig>> &dependencies,
212                                    std::vector<std::string> &dependencyPaths,
213                                    std::unordered_set<std::string> &parsedConfigPath);
214     std::optional<std::string> ReadConfig(const std::string &path);
215 
216 private:
217     static constexpr const char *PACKAGE = "package";  // CC-OFF(G.NAM.03,G.NAM.03-CPP) project code style
218     static constexpr const char *BASE_URL = "baseUrl";
219     static constexpr const char *COMPILER_OPTIONS = "compilerOptions";
220     static constexpr const char *EXCLUDE = "exclude";
221     static constexpr const char *EXTENDS = "extends";
222     static constexpr const char *FILES = "files";
223     static constexpr const char *USE_EMPTY_PACKAGE = "useEmptyPackage";  // CC-OFF(G.NAM.03-CPP) project code style
224     static constexpr const char *INCLUDE = "include";
225     static constexpr const char *OUT_DIR = "outDir";
226     static constexpr const char *ROOT_DIR = "rootDir";
227     static constexpr const char *DEPENDENCIES = "dependencies";  // CC-OFF(G.NAM.03,G.NAM.03-CPP) project code style
228     static constexpr const char *ENTRY = "entry";                // CC-OFF(G.NAM.03,G.NAM.03-CPP) project code style
229 
230     void Inherit(const ArkTsConfig &base);
231 
232     bool isParsed_ = false;
233     std::string configPath_;
234 
235     std::string package_ {};
236     std::string baseUrl_ {};
237     bool useUrl_ = false;
238     std::string outDir_ {};
239     std::string rootDir_ {};
240     std::string entry_ {};
241     PathsMap paths_ {};
242     std::map<std::string, DynamicImportData, CompareByLength> dynamicPaths_ {};
243     std::vector<std::string> files_ {};
244     std::unordered_map<std::string, std::shared_ptr<ArkTsConfig>> dependencies_ {};
245     // key: package name; value: entry's absolute path
246     std::unordered_map<std::string, std::string> entries_;
247 #ifdef ARKTSCONFIG_USE_FILESYSTEM
248     std::vector<Pattern> include_ {};
249     std::vector<Pattern> exclude_ {};
250 #endif  // ARKTSCONFIG_USE_FILESYSTEM
251     util::DiagnosticEngine &diagnosticEngine_;
252 };
253 
254 // Find source files and compute destination locations
255 // Return: vector of path pairs <source file, destination abc file>
256 std::vector<std::pair<std::string, std::string>> FindProjectSources(const std::shared_ptr<ArkTsConfig> &arktsConfig);
257 
258 std::string JoinPaths(const std::string &a, const std::string &b);
259 std::string ParentPath(const std::string &path);
260 
261 }  // namespace ark::es2panda
262 
263 #endif  // ES2PANDA_AOT_TSCONFIG_H
264