• 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::vector<std::string> includes_over_range_;
32 static std::map<std::string, std::vector<std::string>> innerapi_public_deps_inner_;
33 static std::vector<std::string> innerapi_not_lib_;
34 static std::vector<std::string> innerapi_not_declare_;
35 static std::map<std::string, std::vector<std::string>> includes_absolute_deps_other_;
36 static std::map<std::string, std::vector<std::string>> target_absolute_deps_other_;
37 static std::map<std::string, std::vector<std::string>> import_other_;
38 static std::map<std::string, std::vector<std::string>> deps_not_lib_;
39 static std::map<std::string, std::vector<std::string>> fuzzy_match_;
40 
41 OhosComponentChecker *OhosComponentChecker::instance_ = nullptr;
42 
Trim(std::string & str)43 static std::string& Trim(std::string &str)
44 {
45     if (str.empty()) {
46         return str;
47     }
48     str.erase(0, str.find_first_not_of(" \t\r\n"));
49     str.erase(str.find_last_not_of(" \t\r\n") + 1);
50     return str;
51 }
52 
StartWith(const std::string & str,const std::string & prefix)53 static bool StartWith(const std::string &str, const std::string &prefix)
54 {
55     return (str.rfind(prefix, 0) == 0);
56 }
57 
CreateScanOutDir(const std::string & dir)58 static void CreateScanOutDir(const std::string &dir)
59 {
60     base::FilePath path(dir);
61     base::CreateDirectory(path);
62     return;
63 }
64 
RemoveScanOutDir(const std::string & dir)65 static void RemoveScanOutDir(const std::string& dir)
66 {
67     if (access(dir.c_str(), F_OK) == -1) {
68         return;
69     }
70     base::FilePath path(dir);
71     base::DeleteFile(path, true);
72     return;
73 }
74 
ReadBuildConfigFile(base::FilePath path,std::string & content)75 static bool ReadBuildConfigFile(base::FilePath path, std::string &content)
76 {
77     if (!base::ReadFileToString(path, &content)) {
78         return false;
79     }
80     return true;
81 }
82 
LoadAllDepsConfigWhitelist(const base::Value & list)83 static void LoadAllDepsConfigWhitelist(const base::Value &list)
84 {
85     for (const base::Value &value : list.GetList()) {
86         all_deps_config_.push_back(value.GetString());
87     }
88 }
89 
LoadIncludesOverRangeWhitelist(const base::Value & list)90 static void LoadIncludesOverRangeWhitelist(const base::Value &list)
91 {
92     for (const base::Value &value : list.GetList()) {
93         includes_over_range_.push_back(value.GetString());
94     }
95 }
96 
LoadInnerApiPublicDepsInnerWhitelist(const base::Value & value)97 static void LoadInnerApiPublicDepsInnerWhitelist(const base::Value &value)
98 {
99     for (auto info : value.DictItems()) {
100         for (const base::Value &value_tmp : info.second.GetList()) {
101             innerapi_public_deps_inner_[info.first].push_back(value_tmp.GetString());
102         }
103     }
104 }
105 
LoadInnerApiNotLibWhitelist(const base::Value & list)106 static void LoadInnerApiNotLibWhitelist(const base::Value &list)
107 {
108     for (const base::Value &value : list.GetList()) {
109         innerapi_not_lib_.push_back(value.GetString());
110     }
111 }
112 
LoadInnerApiNotDeclareWhitelist(const base::Value & list)113 static void LoadInnerApiNotDeclareWhitelist(const base::Value &list)
114 {
115     for (const base::Value &value : list.GetList()) {
116         innerapi_not_declare_.push_back(value.GetString());
117     }
118 }
119 
LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value & value)120 static void LoadIncludesAbsoluteDepsOtherWhitelist(const base::Value &value)
121 {
122     for (auto info : value.DictItems()) {
123         for (const base::Value &value_tmp : info.second.GetList()) {
124             includes_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
125         }
126     }
127 }
128 
LoadAbsoluteDepsOtherWhitelist(const base::Value & value)129 static void LoadAbsoluteDepsOtherWhitelist(const base::Value &value)
130 {
131     for (auto info : value.DictItems()) {
132         for (const base::Value &value_tmp : info.second.GetList()) {
133             target_absolute_deps_other_[info.first].push_back(value_tmp.GetString());
134         }
135     }
136 }
137 
LoadImportOtherWhitelist(const base::Value & value)138 static void LoadImportOtherWhitelist(const base::Value &value)
139 {
140     for (auto info : value.DictItems()) {
141         for (const base::Value &value_tmp : info.second.GetList()) {
142             import_other_[info.first].push_back(value_tmp.GetString());
143         }
144     }
145 }
146 
LoadDepsNotLibWhitelist(const base::Value & value)147 static void LoadDepsNotLibWhitelist(const base::Value &value)
148 {
149     for (auto info : value.DictItems()) {
150         for (const base::Value &value_tmp : info.second.GetList()) {
151             deps_not_lib_[info.first].push_back(value_tmp.GetString());
152         }
153     }
154 }
155 
LoadFuzzyMatchWhitelist(const base::Value & value)156 static void LoadFuzzyMatchWhitelist(const base::Value &value)
157 {
158     for (auto info : value.DictItems()) {
159         for (const base::Value &value_tmp : info.second.GetList()) {
160             fuzzy_match_[info.first].push_back(value_tmp.GetString());
161         }
162     }
163 }
164 
165 static std::map<std::string, std::function<void(const base::Value &value)>> whitelist_map_ = {
166     { "all_dependent_configs", LoadAllDepsConfigWhitelist },
167     { "includes_over_range", LoadIncludesOverRangeWhitelist },
168     { "innerapi_not_lib", LoadInnerApiNotLibWhitelist },
169     { "innerapi_not_declare", LoadInnerApiNotDeclareWhitelist },
170     { "innerapi_public_deps_inner", LoadInnerApiPublicDepsInnerWhitelist },
171     { "includes_absolute_deps_other", LoadIncludesAbsoluteDepsOtherWhitelist },
172     { "target_absolute_deps_other", LoadAbsoluteDepsOtherWhitelist },
173     { "import_other", LoadImportOtherWhitelist },
174     { "deps_not_lib", LoadDepsNotLibWhitelist },
175     { "fuzzy_match", LoadFuzzyMatchWhitelist }
176 };
177 
LoadWhitelist(const std::string & build_dir)178 static void LoadWhitelist(const std::string &build_dir)
179 {
180     std::string whitelistContent;
181     if (!ReadBuildConfigFile(base::FilePath(build_dir + "/" + WHITELIST_PATH), whitelistContent)) {
182         if (!ReadBuildConfigFile(base::FilePath("out/products_ext/" + WHITELIST_PATH), whitelistContent)) {
183             if (!ReadBuildConfigFile(base::FilePath("build/" + WHITELIST_PATH), whitelistContent)) {
184                 return;
185             }
186         }
187     }
188     const base::DictionaryValue *whitelist_dict;
189     std::unique_ptr<base::Value> whitelist = base::JSONReader::ReadAndReturnError(whitelistContent,
190         base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
191     if (!whitelist) {
192         return;
193     }
194     if (!whitelist->GetAsDictionary(&whitelist_dict)) {
195         return;
196     }
197 
198     for (const auto kv : whitelist_dict->DictItems()) {
199         auto iter = whitelist_map_.find(kv.first);
200         if (iter != whitelist_map_.end()) {
201             iter->second(kv.second);
202         }
203     }
204     return;
205 }
206 
IsIntercept(unsigned int switchValue,int shiftLeftNum)207 static bool IsIntercept(unsigned int switchValue, int shiftLeftNum)
208 {
209     if ((switchValue & (BASE_BINARY << (shiftLeftNum - 1))) != 0) {
210         return true;
211     }
212     return false;
213 }
214 
InterceptAllDepsConfig(const Target * target,const std::string & label,Err * err) const215 bool OhosComponentChecker::InterceptAllDepsConfig(const Target *target, const std::string &label, Err *err) const
216 {
217     if (!IsIntercept(ruleSwitch_, ALL_DEPS_CONFIG_BINARY)) {
218         return true;
219     }
220 
221     auto result = std::find(all_deps_config_.begin(), all_deps_config_.end(), label);
222     if (result != all_deps_config_.end()) {
223         return true;
224     }
225 
226     *err = Err(target->defined_from(), "all_dependent_configs not allowed.",
227         "The item " + label + " does not allow all_dependent_configs.");
228     return false;
229 }
230 
InterceptIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const231 bool OhosComponentChecker::InterceptIncludesOverRange(const Target *target, const std::string &label,
232     const std::string &dir, Err *err) const
233 {
234     if (!IsIntercept(ruleSwitch_, INCLUDE_OVER_RANGE_BINARY)) {
235         return true;
236     }
237 
238     auto result = std::find(includes_over_range_.begin(), includes_over_range_.end(), label);
239     if (result != includes_over_range_.end()) {
240         return true;
241     }
242     *err = Err(target->defined_from(), "Header file range is too large.",
243         "The item " + label + " header : " + dir + " range is too large.");
244     return false;
245 }
246 
InterceptInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const247 bool OhosComponentChecker::InterceptInnerApiPublicDepsInner(const Target *target, const std::string &label,
248     const std::string &deps, Err *err) const
249 {
250     if (!IsIntercept(ruleSwitch_, INNERAPI_PUBLIC_DEPS_INNER_BINARY)) {
251         return true;
252     }
253 
254     if (auto res = innerapi_public_deps_inner_.find(label); res != innerapi_public_deps_inner_.end()) {
255         std::string deps_str(deps);
256         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
257         if (res_second != res->second.end()) {
258             return true;
259         }
260     }
261     *err = Err(target->defined_from(), "InnerApi not allow the use of public_deps dependent internal modules.",
262         "The item " + label + " not allow the use of public_deps dependent internal modules : " + deps);
263     return false;
264 }
265 
InterceptInnerApiNotLib(const Item * item,const std::string & label,Err * err) const266 bool OhosComponentChecker::InterceptInnerApiNotLib(const Item *item, const std::string &label, Err *err) const
267 {
268     if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_LIB_BINARY)) {
269         return true;
270     }
271 
272     auto result = std::find(innerapi_not_lib_.begin(), innerapi_not_lib_.end(), label);
273     if (result != innerapi_not_lib_.end()) {
274         return true;
275     }
276     *err =
277         Err(item->defined_from(), "InnerApi is not a library type.", "The item " + label + " is not a library type.");
278     return false;
279 }
280 
InterceptDepsNotLib(const Item * item,const std::string & label,const std::string & deps,Err * err) const281 bool OhosComponentChecker::InterceptDepsNotLib(const Item *item, const std::string &label,
282     const std::string &deps, Err *err) const
283 {
284     if (!IsIntercept(ruleSwitch_, DEPS_NOT_LIB_BINARY)) {
285         return true;
286     }
287 
288     if (auto res = fuzzy_match_.find("deps_not_lib"); res != fuzzy_match_.end()) {
289         std::string deps_str(deps);
290         for (auto res_second : res->second) {
291             if (StartWith(Trim(deps_str), res_second)) {
292                 return true;
293             }
294         }
295     }
296 
297     if (auto res = deps_not_lib_.find(label); res != deps_not_lib_.end()) {
298         std::string deps_str(deps);
299         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
300         if (res_second != res->second.end()) {
301             return true;
302         }
303     }
304     *err = Err(item->defined_from(), "Depend a non-lib target.",
305         "The item " + label + " cannot depend on a non-lib target " + deps);
306     return false;
307 }
308 
InterceptInnerApiNotDeclare(const Item * item,const std::string & label,Err * err) const309 bool OhosComponentChecker::InterceptInnerApiNotDeclare(const Item *item, const std::string &label, Err *err) const
310 {
311     if (!IsIntercept(ruleSwitch_, INNERAPI_NOT_DECLARE_BINARY)) {
312         return true;
313     }
314 
315     auto result = std::find(innerapi_not_declare_.begin(), innerapi_not_declare_.end(), label);
316     if (result != innerapi_not_declare_.end()) {
317         return true;
318     }
319     *err = Err(item->defined_from(), "InnerApi is not defined in bundle.json.",
320         "The item " + label + " is not defined in bundle.json.");
321     return false;
322 }
323 
InterceptIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const324 bool OhosComponentChecker::InterceptIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
325     const std::string &includes, Err *err) const
326 {
327     if (!IsIntercept(ruleSwitch_, INCLUDES_ABSOLUTE_DEPS_OTHER_BINARY)) {
328         return true;
329     }
330 
331     if (auto res = fuzzy_match_.find("deps_includes_absolute"); res != fuzzy_match_.end()) {
332         std::string includes_str(includes);
333         for (auto res_second : res->second) {
334             if (StartWith(Trim(includes_str), res_second)) {
335                 return true;
336             }
337         }
338     }
339 
340     if (auto res = includes_absolute_deps_other_.find(label); res != includes_absolute_deps_other_.end()) {
341         std::string includes_str(includes);
342         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(includes_str));
343         if (res_second != res->second.end()) {
344             return true;
345         }
346     }
347     *err = Err(target->defined_from(), "Do not directly use header files of other components.",
348         "The item " + label + " do not directly use header files : " + includes + " of other components." +
349         "\n"
350         "Please use 'external_deps/public_external_deps' dependent module.");
351     return false;
352 }
353 
354 
InterceptTargetAbsoluteDepsOther(const Item * item,const std::string & label,const std::string & deps,Err * err) const355 bool OhosComponentChecker::InterceptTargetAbsoluteDepsOther(const Item *item, const std::string &label,
356     const std::string &deps, Err *err) const
357 {
358     if (!IsIntercept(ruleSwitch_, TARGET_ABSOLUTE_DEPS_OTHER_BINARY)) {
359         return true;
360     }
361 
362     if (auto res = fuzzy_match_.find("deps_component_absolute"); res != fuzzy_match_.end()) {
363         std::string deps_str(deps);
364         for (auto res_second : res->second) {
365             if (StartWith(Trim(deps_str), res_second)) {
366                 return true;
367             }
368         }
369     }
370 
371     if (auto res = target_absolute_deps_other_.find(label); res != target_absolute_deps_other_.end()) {
372         std::string deps_str(deps);
373         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
374         if (res_second != res->second.end()) {
375             return true;
376         }
377     }
378     *err = Err(item->defined_from(), "Not allow use absolute dependent other component.",
379         "The item " + label + " not allow use absolute dependent other component : " + deps +
380         "\n"
381         "Please use 'external_deps/public_external_deps'.");
382     return false;
383 }
384 
InterceptInnerApiVisibilityDenied(const Item * item,const std::string & from_label,const std::string & to_label,Err * err) const385 bool OhosComponentChecker::InterceptInnerApiVisibilityDenied(const Item *item, const std::string &from_label,
386     const std::string &to_label, Err *err) const
387 {
388     if (!IsIntercept(ruleSwitch_, INNERAPI_VISIBILITY_DENIED)) {
389         return true;
390     }
391 
392     *err = Err(item->defined_from(), "InnerApi visibility denied.",
393         "The item " + from_label + " cannot dependent  " + to_label +
394         "\n"
395         "Please check 'visibility' field in 'bundle.json' of " +
396         to_label);
397     return false;
398 }
399 
InterceptImportOther(const FunctionCallNode * function,const std::string & label,const std::string & deps,Err * err) const400 bool OhosComponentChecker::InterceptImportOther(const FunctionCallNode *function, const std::string &label,
401     const std::string &deps, Err *err) const
402 {
403     if (!IsIntercept(ruleSwitch_, IMPORT_OTHER_BINARY)) {
404         return true;
405     }
406 
407     if (auto res = fuzzy_match_.find("deps_gni"); res != fuzzy_match_.end()) {
408         std::string deps_str(deps);
409         for (auto res_second : res->second) {
410             if (StartWith(Trim(deps_str), res_second)) {
411                 return true;
412             }
413         }
414     }
415 
416     if (auto res = import_other_.find(label); res != import_other_.end()) {
417         std::string deps_str(deps);
418         auto res_second = std::find(res->second.begin(), res->second.end(), Trim(deps_str));
419         if (res_second != res->second.end()) {
420             return true;
421         }
422     }
423     *err = Err(function->function(), "Not allow import other gni.",
424         label + " not allow import other gni : " + deps);
425     return false;
426 }
427 
OhosComponentChecker(const std::string & build_dir,int checkType,unsigned int ruleSwitch)428 OhosComponentChecker::OhosComponentChecker(const std::string &build_dir, int checkType, unsigned int ruleSwitch)
429 {
430     checkType_ = checkType;
431     build_dir_ = build_dir;
432     ruleSwitch_ = ruleSwitch;
433     if (checkType_ == CheckType::INTERCEPT_IGNORE_TEST || checkType_ == CheckType::INTERCEPT_ALL) {
434         LoadWhitelist(build_dir_);
435     }
436     if (checkType_ == CheckType::SCAN_ALL || checkType_ == CheckType::INTERCEPT_ALL) {
437         ignoreTest_ = false;
438     }
439     RemoveScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
440 }
441 
GenerateScanList(const std::string & path,const std::string & subsystem,const std::string & component,const std::string & label,const std::string & deps) const442 void OhosComponentChecker::GenerateScanList(const std::string &path, const std::string &subsystem,
443     const std::string &component, const std::string &label, const std::string &deps) const
444 {
445     CreateScanOutDir(build_dir_ + "/" + SCAN_RESULT_PATH);
446     std::ofstream file;
447     file.open(build_dir_ + "/" + SCAN_RESULT_PATH + "/" + path, std::ios::app);
448     file << subsystem << " " << component << " " << label << " " << deps << "\n";
449     file.close();
450     return;
451 }
452 
CheckAllDepsConfigs(const Target * target,const std::string & label,Err * err) const453 bool OhosComponentChecker::CheckAllDepsConfigs(const Target *target, const std::string &label, Err *err) const
454 {
455     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
456         return true;
457     }
458 
459     const OhosComponent *component = target->ohos_component();
460     if (component == nullptr) {
461         return true;
462     }
463     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
464         return InterceptAllDepsConfig(target, label, err);
465     }
466     GenerateScanList("all_dependent_configs.list", component->subsystem(), component->name(), label, "");
467     return true;
468 }
469 
CheckInnerApiIncludesOverRange(const Target * target,const std::string & label,const std::string & dir,Err * err) const470 bool OhosComponentChecker::CheckInnerApiIncludesOverRange(const Target *target, const std::string &label,
471     const std::string &dir, Err *err) const
472 {
473     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
474         return true;
475     }
476 
477     const OhosComponent *component = target->ohos_component();
478     if (component == nullptr || (!component->isInnerApi(label) && !StartWith(label, "//third_party"))) {
479         return true;
480     }
481 
482     if (dir != "." && dir != "./" && dir != "../" && dir != component->path() && dir != component->path() + "/") {
483         return true;
484     }
485 
486     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
487         return InterceptIncludesOverRange(target, label, dir, err);
488     }
489     GenerateScanList("includes_over_range.list", component->subsystem(), component->name(), label, dir);
490     return true;
491 }
492 
CheckInnerApiPublicDepsInner(const Target * target,const std::string & label,const std::string & deps,Err * err) const493 bool OhosComponentChecker::CheckInnerApiPublicDepsInner(const Target *target, const std::string &label,
494     const std::string &deps, Err *err) const
495 {
496     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
497         return true;
498     }
499 
500     const OhosComponent *component = target->ohos_component();
501     if (component == nullptr || !component->isInnerApi(label)) {
502         return true;
503     }
504 
505     if (!StartWith(deps, component->path()) && StartWith(deps, "//")) {
506         return true;
507     }
508 
509     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
510         return InterceptInnerApiPublicDepsInner(target, label, deps, err);
511     }
512     GenerateScanList("innerapi_public_deps_inner.list", component->subsystem(), component->name(), label, deps);
513     return true;
514 }
515 
CheckInnerApiNotLib(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const516 bool OhosComponentChecker::CheckInnerApiNotLib(const Item *item, const OhosComponent *component,
517     const std::string &label, const std::string &deps, Err *err) const
518 {
519     if (checkType_ <= CheckType::NONE || item == nullptr || item->AsTarget() == nullptr ||
520         (ignoreTest_ && item->testonly()) || component == nullptr) {
521         return true;
522     }
523 
524     Target::OutputType type = item->AsTarget()->output_type();
525     if (type == Target::SHARED_LIBRARY || type == Target::STATIC_LIBRARY || type == Target::RUST_LIBRARY ||
526         type == Target::EXECUTABLE || type == Target::COPY_FILES) {
527         return true;
528     }
529 
530     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
531         return InterceptDepsNotLib(item, label, deps, err) && InterceptInnerApiNotLib(item, deps, err);
532     }
533 
534     std::string type_str(Target::GetStringForOutputType(type));
535     GenerateScanList("innerapi_not_lib.list", component->subsystem(), component->name(), deps, type_str);
536     GenerateScanList("deps_not_lib.list", component->subsystem(), component->name(), label, deps);
537     return true;
538 }
539 
CheckInnerApiNotDeclare(const Item * item,const OhosComponent * component,const std::string & label,Err * err) const540 bool OhosComponentChecker::CheckInnerApiNotDeclare(const Item *item, const OhosComponent *component,
541     const std::string &label, Err *err) const
542 {
543     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
544         return true;
545     }
546 
547     if (component->isInnerApi(label)) {
548         return true;
549     }
550     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
551         return InterceptInnerApiNotDeclare(item, label, err);
552     }
553     GenerateScanList("innerapi_not_declare.list", component->subsystem(), component->name(), label, "");
554     return true;
555 }
556 
CheckIncludesAbsoluteDepsOther(const Target * target,const std::string & label,const std::string & includes,Err * err) const557 bool OhosComponentChecker::CheckIncludesAbsoluteDepsOther(const Target *target, const std::string &label,
558     const std::string &includes, Err *err) const
559 {
560     if (checkType_ <= CheckType::NONE || target == nullptr || (ignoreTest_ && target->testonly())) {
561         return true;
562     }
563 
564     if (includes == "//" || !StartWith(includes, "//") || StartWith(includes, "//out/")
565         || StartWith(includes, "////out/") || StartWith(includes, "//prebuilts/")) {
566         return true;
567     }
568 
569     const OhosComponent *component = target->ohos_component();
570     if (component == nullptr) {
571         return true;
572     }
573 
574     if (StartWith(includes, component->path())) {
575         return true;
576     }
577 
578     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
579         return InterceptIncludesAbsoluteDepsOther(target, label, includes, err);
580     }
581     GenerateScanList("includes_absolute_deps_other.list", component->subsystem(), component->name(), label, includes);
582     return true;
583 }
584 
CheckInnerApiVisibilityDenied(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,Err * err) const585 bool OhosComponentChecker::CheckInnerApiVisibilityDenied(const Item *item, const OhosComponent *component,
586     const std::string &label, const std::string &deps, Err *err) const
587 {
588     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
589         return true;
590     }
591 
592     if (!component->isInnerApi(deps)) {
593         return true;
594     }
595     std::vector<std::string> visibility = component->getInnerApiVisibility(deps);
596     if (visibility.empty()) {
597         return true;
598     }
599 
600     const OhosComponent *from_component = item->ohos_component();
601     if (from_component == nullptr) {
602         return true;
603     }
604     auto result = std::find(visibility.begin(), visibility.end(), from_component->name());
605     if (result != visibility.end()) {
606         return true;
607     }
608 
609     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
610         return InterceptInnerApiVisibilityDenied(item, label, deps, err);
611     }
612     GenerateScanList("innerkit_visibility_denied.list", from_component->subsystem(), from_component->name(), label,
613         deps);
614     return true;
615 }
616 
CheckTargetAbsoluteDepsOther(const Item * item,const OhosComponent * component,const std::string & label,const std::string & deps,bool is_external_deps,Err * err) const617 bool OhosComponentChecker::CheckTargetAbsoluteDepsOther(const Item *item, const OhosComponent *component,
618     const std::string &label, const std::string &deps, bool is_external_deps, Err *err) const
619 {
620     if (checkType_ <= CheckType::NONE || component == nullptr || item == nullptr || (ignoreTest_ && item->testonly())) {
621         return true;
622     }
623 
624     if (is_external_deps) {
625         return true;
626     }
627 
628     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
629         return InterceptTargetAbsoluteDepsOther(item, label, deps, err);
630     }
631 
632     const OhosComponent *from_component = item->ohos_component();
633     if (from_component == nullptr) {
634         return true;
635     }
636     GenerateScanList("target_absolute_deps_other.list",
637         from_component->subsystem(), from_component->name(), label, deps);
638     return true;
639 }
640 
CheckImportOther(const FunctionCallNode * function,const BuildSettings * build_settings,const std::string & label,const std::string & deps,Err * err) const641 bool OhosComponentChecker::CheckImportOther(const FunctionCallNode *function, const BuildSettings *build_settings,
642     const std::string &label, const std::string &deps, Err *err) const
643 {
644     if (checkType_ <= CheckType::NONE || function == nullptr || build_settings == nullptr) {
645         return true;
646     }
647     const OhosComponent *component = build_settings->GetOhosComponent(label);
648     if (component == nullptr) {
649         return true;
650     }
651     if (StartWith(deps, component->path()) || StartWith(deps, "//build/") || StartWith(deps, "//out/")
652         || StartWith(deps, "//prebuilts/")) {
653         return true;
654     }
655 
656     if (checkType_ >= CheckType::INTERCEPT_IGNORE_TEST) {
657         return InterceptImportOther(function, label, deps, err);
658     }
659     GenerateScanList("import_other.list", component->subsystem(), component->name(), label, deps);
660     return true;
661 }
662