• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2024 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gn/ohos_components_checker.h"
6 
7 #include <fstream>
8 #include <functional>
9 #include <iostream>
10 #include <sys/stat.h>
11 
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/values.h"
16 #include "gn/build_settings.h"
17 #include "gn/config.h"
18 #include "gn/filesystem_utils.h"
19 #include "gn/functions.h"
20 #include "gn/ohos_components.h"
21 #include "gn/parse_tree.h"
22 #include "gn/settings.h"
23 #include "gn/substitution_writer.h"
24 #include "gn/target.h"
25 #include "gn/value.h"
26 
27 static const std::string SCAN_RESULT_PATH = "scan_out";
28 static const std::string WHITELIST_PATH = "component_compilation_whitelist.json";
29 static const int BASE_BINARY = 1;
30 static std::vector<std::string> all_deps_config_;
31 static std::map<std::string, std::vector<std::string>> public_deps_;
32 static std::map<std::string, std::vector<std::string>> lib_dirs_;
33 static std::vector<std::string> includes_over_range_;
34 static std::map<std::string, std::vector<std::string>> innerapi_public_deps_inner_;
35 static std::vector<std::string> innerapi_not_lib_;
36 static std::vector<std::string> innerapi_not_declare_;
37 static std::map<std::string, std::vector<std::string>> includes_absolute_deps_other_;
38 static std::map<std::string, std::vector<std::string>> target_absolute_deps_other_;
39 static std::map<std::string, std::vector<std::string>> import_other_;
40 static std::map<std::string, std::vector<std::string>> deps_not_lib_;
41 static std::map<std::string, std::vector<std::string>> fuzzy_match_;
42 
43 OhosComponentChecker *OhosComponentChecker::instance_ = nullptr;
44 
Trim(std::string & str)45 static std::string& Trim(std::string &str)
46 {
47     if (str.empty()) {
48         return str;
49     }
50     str.erase(0, str.find_first_not_of(" \t\r\n"));
51     str.erase(str.find_last_not_of(" \t\r\n") + 1);
52     return str;
53 }
54 
StartWith(const std::string & str,const std::string & prefix)55 static bool StartWith(const std::string &str, const std::string &prefix)
56 {
57     return (str.rfind(prefix, 0) == 0);
58 }
59 
CreateScanOutDir(const std::string & dir)60 static void CreateScanOutDir(const std::string &dir)
61 {
62     base::FilePath path(dir);
63     base::CreateDirectory(path);
64     return;
65 }
66 
RemoveScanOutDir(const std::string & dir)67 static void RemoveScanOutDir(const std::string& dir)
68 {
69     if (access(dir.c_str(), F_OK) == -1) {
70         return;
71     }
72     base::FilePath path(dir);
73     base::DeleteFile(path, true);
74     return;
75 }
76 
ReadBuildConfigFile(base::FilePath path,std::string & content)77 static bool ReadBuildConfigFile(base::FilePath path, std::string &content)
78 {
79     if (!base::ReadFileToString(path, &content)) {
80         return false;
81     }
82     return true;
83 }
84 
LoadAllDepsConfigWhitelist(const base::Value & list)85 static void LoadAllDepsConfigWhitelist(const base::Value &list)
86 {
87     for (const base::Value &value : list.GetList()) {
88         all_deps_config_.push_back(value.GetString());
89     }
90 }
91 
LoadIncludesOverRangeWhitelist(const base::Value & list)92 static void LoadIncludesOverRangeWhitelist(const base::Value &list)
93 {
94     for (const base::Value &value : list.GetList()) {
95         includes_over_range_.push_back(value.GetString());
96     }
97 }
98 
LoadInnerApiPublicDepsInnerWhitelist(const base::Value & value)99 static void LoadInnerApiPublicDepsInnerWhitelist(const base::Value &value)
100 {
101     for (auto info : value.DictItems()) {
102         for (const base::Value &value_tmp : info.second.GetList()) {
103             innerapi_public_deps_inner_[info.first].push_back(value_tmp.GetString());
104         }
105     }
106 }
107 
LoadPublicDepsWhitelist(const base::Value & value)108 static void LoadPublicDepsWhitelist(const base::Value &value)
109 {
110     for (auto info : value.DictItems()) {
111         for (const base::Value &value_tmp : info.second.GetList()) {
112             public_deps_[info.first].push_back(value_tmp.GetString());
113         }
114     }
115 }
116 
LoadLibDirsWhitelist(const base::Value & value)117 static void LoadLibDirsWhitelist(const base::Value &value)
118 {
119     for (auto info : value.DictItems()) {
120         for (const base::Value &value_tmp : info.second.GetList()) {
121             lib_dirs_[info.first].push_back(value_tmp.GetString());
122         }
123     }
124 }
125 
LoadInnerApiNotLibWhitelist(const base::Value & list)126 static void LoadInnerApiNotLibWhitelist(const base::Value &list)
127 {
128     for (const base::Value &value : list.GetList()) {
129         innerapi_not_lib_.push_back(value.GetString());
130     }
131 }
132 
LoadInnerApiNotDeclareWhitelist(const base::Value & list)133 static void LoadInnerApiNotDeclareWhitelist(const base::Value &list)
134 {
135     for (const base::Value &value : list.GetList()) {
136         innerapi_not_declare_.push_back(value.GetString());
137     }
138 }
139 
LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value & value)140 static void LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value &value)
141 {
142     for (auto info : value.DictItems()) {
143         for (const base::Value &value_tmp : info.second.GetList()) {
144             includes_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
145         }
146     }
147 }
148 
LoadAbsoluteDepsOtherWhitelist(const base::Value & value)149 static void LoadAbsoluteDepsOtherWhitelist(const base::Value &value)
150 {
151     for (auto info : value.DictItems()) {
152         for (const base::Value &value_tmp : info.second.GetList()) {
153             target_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
154         }
155     }
156 }
157 
LoadImportOtherWhitelist(const base::Value & value)158 static void LoadImportOtherWhitelist(const base::Value &value)
159 {
160     for (auto info : value.DictItems()) {
161         for (const base::Value &value_tmp : info.second.GetList()) {
162             import_other_[info.first].push_back(value_tmp.GetString());
163         }
164     }
165 }
166 
LoadDepsNotLibWhitelist(const base::Value & value)167 static void LoadDepsNotLibWhitelist(const base::Value &value)
168 {
169     for (auto info : value.DictItems()) {
170         for (const base::Value &value_tmp : info.second.GetList()) {
171             deps_not_lib_[info.first].push_back(value_tmp.GetString());
172         }
173     }
174 }
175 
LoadFuzzyMatchWhitelist(const base::Value & value)176 static void LoadFuzzyMatchWhitelist(const base::Value &value)
177 {
178     for (auto info : value.DictItems()) {
179         for (const base::Value &value_tmp : info.second.GetList()) {
180             fuzzy_match_[info.first].push_back(value_tmp.GetString());
181         }
182     }
183 }
184 
185 static std::map<std::string, std::function<void(const base::Value &value)>> whitelist_map_ = {
186     { "all_dependent_configs", LoadAllDepsConfigWhitelist },
187     { "includes_over_range", LoadIncludesOverRangeWhitelist },
188     { "innerapi_not_lib", LoadInnerApiNotLibWhitelist },
189     { "innerapi_not_declare", LoadInnerApiNotDeclareWhitelist },
190     { "innerapi_public_deps_inner", LoadInnerApiPublicDepsInnerWhitelist },
191     { "public_deps", LoadPublicDepsWhitelist },
192     { "lib_dirs", LoadLibDirsWhitelist },
193     { "includes_absolute_deps_other", LoadIncludesAbsoluteDepsOtherWhitelist },
194     { "target_absolute_deps_other", LoadAbsoluteDepsOtherWhitelist },
195     { "import_other", LoadImportOtherWhitelist },
196     { "deps_not_lib", LoadDepsNotLibWhitelist },
197     { "fuzzy_match", LoadFuzzyMatchWhitelist }
198 };
199 
LoadWhitelist(const std::string & build_dir)200 static void LoadWhitelist(const std::string &build_dir)
201 {
202     std::string whitelistContent;
203     if (!ReadBuildConfigFile(base::FilePath(build_dir + "/" + WHITELIST_PATH), whitelistContent)) {
204         if (!ReadBuildConfigFile(base::FilePath("out/products_ext/" + WHITELIST_PATH), whitelistContent)) {
205             if (!ReadBuildConfigFile(base::FilePath("build/" + WHITELIST_PATH), whitelistContent)) {
206                 return;
207             }
208         }
209     }
210     const base::DictionaryValue *whitelist_dict;
211     std::unique_ptr<base::Value> whitelist = base::JSONReader::ReadAndReturnError(whitelistContent,
212         base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
213     if (!whitelist) {
214         return;
215     }
216     if (!whitelist->GetAsDictionary(&whitelist_dict)) {
217         return;
218     }
219 
220     for (const auto kv : whitelist_dict->DictItems()) {
221         auto iter = whitelist_map_.find(kv.first);
222         if (iter != whitelist_map_.end()) {
223             iter->second(kv.second);
224         }
225     }
226     return;
227 }
228 
IsIntercept(unsigned int switchValue,int shiftLeftNum)229 static bool IsIntercept(unsigned int switchValue, int shiftLeftNum)
230 {
231     if ((switchValue & (BASE_BINARY << (shiftLeftNum - 1))) != 0) {
232         return true;
233     }
234     return false;
235 }
236 
InterceptAllDepsConfig(const Target * target,const std::string & label,Err * err) const237 bool OhosComponentChecker::InterceptAllDepsConfig(const Target *target, const std::string &label, Err *err) const
238 {
239     if (!IsIntercept(ruleSwitch_, ALL_DEPS_CONFIG_BINARY)) {
240         return true;
241     }
242 
243     auto result = std::find(all_deps_config_.begin(), all_deps_config_.end(), label);
244     if (result != all_deps_config_.end()) {
245         return true;
246     }
247 
248     *err = Err(target->defined_from(), "all_dependent_configs not allowed.",
249         "The item " + label + " does not allow all_dependent_configs.");
250     return false;
251 }
252 
InterceptIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const253 bool OhosComponentChecker::InterceptIncludesOverRange(const Target *target, const std::string &label,
254     const std::string &dir, Err *err) const
255 {
256     if (!IsIntercept(ruleSwitch_, INCLUDE_OVER_RANGE_BINARY)) {
257         return true;
258     }
259 
260     auto result = std::find(includes_over_range_.begin(), includes_over_range_.end(), label);
261     if (result != includes_over_range_.end()) {
262         return true;
263     }
264     *err = Err(target->defined_from(), "Header file range is too large.",
265         "The item " + label + " header : " + dir + " range is too large.");
266     return false;
267 }
268 
InterceptInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const269 bool OhosComponentChecker::InterceptInnerApiPublicDepsInner(const Target *target, const std::string &label,
270     const std::string &deps, Err *err) const
271 {
272     if (!IsIntercept(ruleSwitch_, INNERAPI_PUBLIC_DEPS_INNER_BINARY)) {
273         return true;
274     }
275 
276     if (auto res = innerapi_public_deps_inner_.find(label); res != innerapi_public_deps_inner_.end()) {
277         std::string deps_str(deps);
278         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
279         if (res_second != res->second.end()) {
280             return true;
281         }
282     }
283     *err = Err(target->defined_from(), "InnerApi not allow the use of public_deps dependent internal modules.",
284         "The item " + label + " not allow the use of public_deps dependent internal module : " + deps);
285     return false;
286 }
287 
InterceptPublicDeps(const Target * target,const std::string & label,const std::string & deps,Err * err) const288 bool OhosComponentChecker::InterceptPublicDeps(const Target *target, const std::string &label,
289         const std::string &deps, Err *err) const
290     {
291         if (!IsIntercept(ruleSwitch_, PUBLIC_DEPS_BINARY)) {
292             return true;
293         }
294 
295         if (auto res = public_deps_.find(label); res != public_deps_.end()) {
296             std::string deps_str(deps);
297             auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
298             if (res_second != res->second.end()) {
299                 return true;
300             }
301         }
302         *err = Err(target->defined_from(), "public_deps/public_external_deps not allowed.",
303             "The item " + label + " not allow the use of public_deps/public_external_deps dependent module : " + deps);
304          return false;
305     }
306 
InterceptLibDir(const Target * target,const std::string & label,const std::string & dir,Err * err) const307 bool OhosComponentChecker::InterceptLibDir(const Target *target, const std::string &label,
308     const std::string &dir, Err *err) const
309 {
310     if (!IsIntercept(ruleSwitch_, LIB_DIRS_BINARY)) {
311         return true;
312     }
313 
314     if (auto res = fuzzy_match_.find("lib_dirs"); res != fuzzy_match_.end()) {
315         std::string lib_dirs(dir);
316         for (auto res_second : res->second) {
317             if (StartWith(Trim(lib_dirs), res_second)) {
318                 return true;
319             }
320         }
321     }
322 
323     if (auto res = lib_dirs_.find(label); res != lib_dirs_.end()) {
324         std::string lib_dirs(dir);
325         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(lib_dirs));
326         if (res_second != res->second.end()) {
327             return true;
328         }
329     }
330 
331     *err = Err(target->defined_from(), "lib_dirs not allowed.",
332         "The item" + label + " do not use lib_dirs : " + dir);
333     return false;
334 }
335 
InterceptInnerApiNotLib(const Item * item,const std::string & label,Err * err) const336 bool OhosComponentChecker::InterceptInnerApiNotLib(const Item *item, const std::string &label, Err *err) const
337 {
338     if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_LIB_BINARY)) {
339         return true;
340     }
341 
342     auto result = std::find(innerapi_not_lib_.begin(), innerapi_not_lib_.end(), label);
343     if (result != innerapi_not_lib_.end()) {
344         return true;
345     }
346     *err =
347         Err(item->defined_from(), "InnerApi is not a library type.", "The item " + label + " is not a library type.");
348     return false;
349 }
350 
InterceptDepsNotLib(const Item * item,const std::string & label,const std::string & deps,Err * err) const351 bool OhosComponentChecker::InterceptDepsNotLib(const Item *item, const std::string &label,
352     const std::string &deps, Err *err) const
353 {
354     if (!IsIntercept(ruleSwitch_, DEPS_NOT_LIB_BINARY)) {
355         return true;
356     }
357 
358     if (auto res = fuzzy_match_.find("deps_not_lib"); res != fuzzy_match_.end()) {
359         std::string deps_str(deps);
360         for (auto res_second : res->second) {
361             if (StartWith(Trim(deps_str), res_second)) {
362                 return true;
363             }
364         }
365     }
366 
367     if (auto res = deps_not_lib_.find(label); res != deps_not_lib_.end()) {
368         std::string deps_str(deps);
369         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
370         if (res_second != res->second.end()) {
371             return true;
372         }
373     }
374     *err = Err(item->defined_from(), "Depend a non-lib target.",
375         "The item " + label + " cannot depend on a non-lib target " + deps);
376     return false;
377 }
378 
InterceptInnerApiNotDeclare(const Item * item,const std::string & label,Err * err) const379 bool OhosComponentChecker::InterceptInnerApiNotDeclare(const Item *item, const std::string &label, Err *err) const
380 {
381     if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_DECLARE_BINARY)) {
382         return true;
383     }
384 
385     auto result = std::find(innerapi_not_declare_.begin(), innerapi_not_declare_.end(), label);
386     if (result != innerapi_not_declare_.end()) {
387         return true;
388     }
389     *err = Err(item->defined_from(), "InnerApi is not defined in bundle.json.",
390         "The item " + label + " is not defined in bundle.json.");
391     return false;
392 }
393 
InterceptIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const394 bool OhosComponentChecker::InterceptIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
395     const std::string &includes, Err *err) const
396 {
397     if (!IsIntercept(ruleSwitch_, INCLUDES_ABSOLUTE_DEPS_OTHER_BINARY)) {
398         return true;
399     }
400 
401     if (auto res = fuzzy_match_.find("deps_includes_absolute"); res != fuzzy_match_.end()) {
402         std::string includes_str(includes);
403         for (auto res_second : res->second) {
404             if (StartWith(Trim(includes_str), res_second)) {
405                 return true;
406             }
407         }
408     }
409 
410     if (auto res = includes_absolute_deps_other_.find(label); res != includes_absolute_deps_other_.end()) {
411         std::string includes_str(includes);
412         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(includes_str));
413         if (res_second != res->second.end()) {
414             return true;
415         }
416     }
417     *err = Err(target->defined_from(), "Do not directly use header files of other components.",
418         "The item " + label + " do not directly use header files : " + includes + " of other components." +
419         "\n"
420         "Please use 'external_deps' dependent module.");
421     return false;
422 }
423 
424 
InterceptTargetAbsoluteDepsOther(const Item * item,const std::string & label,const std::string & deps,Err * err) const425 bool OhosComponentChecker::InterceptTargetAbsoluteDepsOther(const Item *item, const std::string &label,
426     const std::string &deps, Err *err) const
427 {
428     if (!IsIntercept(ruleSwitch_, TARGET_ABSOLUTE_DEPS_OTHER_BINARY)) {
429         return true;
430     }
431 
432     if (auto res = fuzzy_match_.find("deps_component_absolute"); res != fuzzy_match_.end()) {
433         std::string deps_str(deps);
434         for (auto res_second : res->second) {
435             if (StartWith(Trim(deps_str), res_second)) {
436                 return true;
437             }
438         }
439     }
440 
441     if (auto res = target_absolute_deps_other_.find(label); res != target_absolute_deps_other_.end()) {
442         std::string deps_str(deps);
443         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
444         if (res_second != res->second.end()) {
445             return true;
446         }
447     }
448     *err = Err(item->defined_from(), "Not allow use absolute dependent other component.",
449         "The item " + label + " not allow use absolute dependent other component : " + deps +
450         "\n"
451         "Please use 'external_deps'.");
452     return false;
453 }
454 
InterceptInnerApiVisibilityDenied(const Item * item,const std::string & from_label,const std::string & to_label,Err * err) const455 bool OhosComponentChecker::InterceptInnerApiVisibilityDenied(const Item *item, const std::string &from_label,
456     const std::string &to_label, Err *err) const
457 {
458     if (!IsIntercept(ruleSwitch_, INNERAPI_VISIBILITY_DENIED)) {
459         return true;
460     }
461 
462     *err = Err(item->defined_from(), "InnerApi visibility denied.",
463         "The item " + from_label + " cannot dependent  " + to_label +
464         "\n"
465         "Please check 'visibility' field in 'bundle.json' of " +
466         to_label);
467     return false;
468 }
469 
InterceptImportOther(const FunctionCallNode * function,const std::string & label,const std::string & deps,Err * err) const470 bool OhosComponentChecker::InterceptImportOther(const FunctionCallNode *function, const std::string &label,
471     const std::string &deps, Err *err) const
472 {
473     if (!IsIntercept(ruleSwitch_, IMPORT_OTHER_BINARY)) {
474         return true;
475     }
476 
477     if (auto res = fuzzy_match_.find("deps_gni"); res != fuzzy_match_.end()) {
478         std::string deps_str(deps);
479         for (auto res_second : res->second) {
480             if (StartWith(Trim(deps_str), res_second)) {
481                 return true;
482             }
483         }
484     }
485 
486     if (auto res = import_other_.find(label); res != import_other_.end()) {
487         std::string deps_str(deps);
488         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
489         if (res_second != res->second.end()) {
490             return true;
491         }
492     }
493     *err = Err(function->function(), "Not allow import other gni.",
494         label + " not allow import other gni : " + deps);
495     return false;
496 }
497 
OhosComponentChecker(const std::string & build_dir,int checkType,unsigned int ruleSwitch)498 OhosComponentChecker::OhosComponentChecker(const std::string &build_dir, int checkType, unsigned int ruleSwitch)
499 {
500     checkType_ = checkType;
501     build_dir_ = build_dir;
502     ruleSwitch_ = ruleSwitch;
503     if (checkType_ == CheckType::INTERCEPT_IGNORE_TEST || checkType_ == CheckType::INTERCEPT_ALL) {
504         LoadWhitelist(build_dir_);
505     }
506     if (checkType_ == CheckType::SCAN_ALL || checkType_ == CheckType::INTERCEPT_ALL) {
507         ignoreTest_ = false;
508     }
509     RemoveScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
510 }
511 
GenerateScanList(const std::string & path,const std::string & subsystem,const std::string & component,const std::string & label,const std::string & deps) const512 void OhosComponentChecker::GenerateScanList(const std::string &path, const std::string &subsystem,
513     const std::string &component, const std::string &label, const std::string &deps) const
514 {
515     CreateScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
516     std::ofstream file;
517     file.open(build_dir_ + "/" + SCAN_RESULT_PATH + "/" + path, std::ios::app);
518     file << subsystem << " " << component << " " << label << " " << deps << "\n";
519     file.close();
520     return;
521 }
522 
CheckAllDepsConfigs(const Target * target,const std::string & label,Err * err) const523 bool OhosComponentChecker::CheckAllDepsConfigs(const Target *target, const std::string &label, Err *err) const
524 {
525     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
526         return true;
527     }
528 
529     const OhosComponent *component = target->ohos_component();
530     if (component == nullptr) {
531         return true;
532     }
533     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
534         return InterceptAllDepsConfig(target, label, err);
535     }
536     GenerateScanList("all_dependent_configs.list", component->subsystem(), component->name(), label, "");
537     return true;
538 }
539 
CheckInnerApiIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const540 bool OhosComponentChecker::CheckInnerApiIncludesOverRange(const Target *target, const std::string &label,
541     const std::string &dir, Err *err) const
542 {
543     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
544         return true;
545     }
546 
547     const OhosComponent *component = target->ohos_component();
548     if (component == nullptr || !component->isInnerApi(label) || StartWith(label, "//third_party")) {
549         return true;
550     }
551 
552     bool is_part_path = false;
553     for (const auto &path : component->modulePath()) {
554         if (dir == path || dir == path + "/") {
555             is_part_path = true;
556             break;
557         }
558     }
559     if (dir != "." && dir != "./" && dir != "../" && !is_part_path) {
560         return true;
561     }
562 
563     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
564         return InterceptIncludesOverRange(target, label, dir, err);
565     }
566     GenerateScanList("includes_over_range.list", component->subsystem(), component->name(), label, dir);
567     return true;
568 }
569 
CheckInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const570 bool OhosComponentChecker::CheckInnerApiPublicDepsInner(const Target *target, const std::string &label,
571     const std::string &deps, Err *err) const
572 {
573     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
574         return true;
575     }
576 
577     const OhosComponent *component = target->ohos_component();
578     if (component == nullptr || !component->isInnerApi(label)) {
579         return true;
580     }
581 
582     bool is_same_part = false;
583     for (const auto &path : component->modulePath()) {
584         if (StartWith(deps, path)) {
585             is_same_part = true;
586             break;
587         }
588     }
589 
590     if (!is_same_part && StartWith(deps, "//")) {
591         return true;
592     }
593 
594     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
595         return InterceptInnerApiPublicDepsInner(target, label, deps, err);
596     }
597     GenerateScanList("innerapi_public_deps_inner.list", component->subsystem(), component->name(), label, deps);
598     return true;
599 }
600 
CheckPublicDeps(const Target * target,const std::string & label,const std::string & deps,Err * err) const601 bool OhosComponentChecker::CheckPublicDeps(const Target *target, const std::string &label,
602         const std::string &deps, Err *err) const
603     {
604         if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
605             return true;
606         }
607 
608         if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
609             return InterceptPublicDeps(target, label, deps, err);
610         }
611         const OhosComponent *component = target->ohos_component();
612         GenerateScanList("public_deps.list", component == nullptr ? "" : component->subsystem(),
613             component == nullptr ? "" : component->name(), label, deps);
614         return true;
615     }
616 
CheckLibDir(const Target * target,const std::string & label,const std::string & dir,Err * err) const617 bool OhosComponentChecker::CheckLibDir(const Target *target, const std::string &label,
618     const std::string &dir, Err *err) const
619 {
620     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
621         return true;
622     }
623 
624     const OhosComponent *component = target->ohos_component();
625     if (component == nullptr) {
626         return true;
627     }
628 
629     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
630         return InterceptLibDir(target, label, dir, err);
631     }
632     GenerateScanList("lib_dirs.list", component->subsystem(), component->name(), label, dir);
633     return true;
634 }
635 
CheckInnerApiNotLib(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const636 bool OhosComponentChecker::CheckInnerApiNotLib(const Item *item, const OhosComponent *component,
637     const std::string &label, const std::string &deps, Err *err) const
638 {
639     if (checkType_ <= CheckType::NONE || item == nullptr || item->AsTarget() == nullptr ||
640         (ignoreTest_ && item->testonly()) || component == nullptr) {
641         return true;
642     }
643 
644     Target::OutputType type = item->AsTarget()->output_type();
645     if (type == Target::SHARED_LIBRARY || type == Target::STATIC_LIBRARY || type == Target::RUST_LIBRARY ||
646         type == Target::EXECUTABLE || type == Target::COPY_FILES) {
647         return true;
648     }
649 
650     if (type == Target::GROUP && item->checkflag() == false) {
651         return true;
652     }
653 
654     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
655         return InterceptDepsNotLib(item, label, deps, err) && InterceptInnerApiNotLib(item, deps, err);
656     }
657 
658     std::string type_str(Target::GetStringForOutputType(type));
659     GenerateScanList("innerapi_not_lib.list", component->subsystem(), component->name(), deps, type_str);
660     GenerateScanList("deps_not_lib.list", component->subsystem(), component->name(), label, deps);
661     return true;
662 }
663 
CheckInnerApiNotDeclare(const Item * item,const OhosComponent * component,const std::string & label,Err * err) const664 bool OhosComponentChecker::CheckInnerApiNotDeclare(const Item *item, const OhosComponent *component,
665     const std::string &label, Err *err) const
666 {
667     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
668         return true;
669     }
670 
671     if (component->isInnerApi(label)) {
672         return true;
673     }
674     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
675         return InterceptInnerApiNotDeclare(item, label, err);
676     }
677     GenerateScanList("innerapi_not_declare.list", component->subsystem(), component->name(), label, "");
678     return true;
679 }
680 
CheckIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const681 bool OhosComponentChecker::CheckIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
682     const std::string &includes, Err *err) const
683 {
684     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
685         return true;
686     }
687 
688     if (includes == "//" || !StartWith(includes, "//") || StartWith(includes, "//out/")
689         || StartWith(includes, "////out/") || StartWith(includes, "//prebuilts/")) {
690         return true;
691     }
692 
693     const OhosComponent *component = target->ohos_component();
694     if (component == nullptr) {
695         return true;
696     }
697 
698     for(const auto &path : component->modulePath()) {
699         if (StartWith(includes, path)) {
700             return true;
701         }
702     }
703 
704     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
705         return InterceptIncludesAbsoluteDepsOther(target, label, includes, err);
706     }
707     GenerateScanList("includes_absolute_deps_other.list", component->subsystem(), component->name(), label, includes);
708     return true;
709 }
710 
CheckInnerApiVisibilityDenied(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const711 bool OhosComponentChecker::CheckInnerApiVisibilityDenied(const Item *item, const OhosComponent *component,
712     const std::string &label, const std::string &deps, Err *err) const
713 {
714     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
715         return true;
716     }
717 
718     if (!component->isInnerApi(deps)) {
719         return true;
720     }
721     std::vector<std::string> visibility = component->getInnerApiVisibility(deps);
722     if (visibility.empty()) {
723         return true;
724     }
725 
726     const OhosComponent *from_component = item->ohos_component();
727     if (from_component == nullptr) {
728         return true;
729     }
730     auto result = std::find(visibility.begin(), visibility.end(), from_component->name());
731     if (result != visibility.end()) {
732         return true;
733     }
734 
735     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
736         return InterceptInnerApiVisibilityDenied(item, label, deps, err);
737     }
738     GenerateScanList("innerkit_visibility_denied.list", from_component->subsystem(), from_component->name(), label,
739         deps);
740     return true;
741 }
742 
CheckTargetAbsoluteDepsOther(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,bool is_external_deps,Err * err) const743 bool OhosComponentChecker::CheckTargetAbsoluteDepsOther(const Item *item, const OhosComponent *component,
744     const std::string &label, const std::string &deps, bool is_external_deps, Err *err) const
745 {
746     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
747         return true;
748     }
749 
750     if (is_external_deps) {
751         return true;
752     }
753 
754     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
755         return InterceptTargetAbsoluteDepsOther(item, label, deps, err);
756     }
757 
758     const OhosComponent *from_component = item->ohos_component();
759     if (from_component == nullptr) {
760         return true;
761     }
762     GenerateScanList("target_absolute_deps_other.list",
763         from_component->subsystem(), from_component->name(), label, deps);
764     return true;
765 }
766 
CheckImportOther(const FunctionCallNode * function,const BuildSettings * build_settings,const std::string & label,const std::string & deps,Err * err) const767 bool OhosComponentChecker::CheckImportOther(const FunctionCallNode *function, const BuildSettings *build_settings,
768     const std::string &label, const std::string &deps, Err *err) const
769 {
770     if (checkType_ <= CheckType::NONE || function == nullptr || build_settings == nullptr) {
771         return true;
772     }
773     const OhosComponent *component = build_settings->GetOhosComponent(label);
774     if (component == nullptr) {
775         return true;
776     }
777     if (StartWith(deps, "//build/") || StartWith(deps, "//out/")
778         || StartWith(deps, "//prebuilts/")) {
779         return true;
780     }
781 
782     for (const auto &path : component->modulePath()) {
783         if (StartWith(deps, path)) {
784             return true;
785         }
786     }
787 
788     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
789         return InterceptImportOther(function, label, deps, err);
790     }
791     GenerateScanList("import_other.list", component->subsystem(), component->name(), label, deps);
792     return true;
793 }
794