1 // Copyright 2014 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/visibility.h"
6
7 #include <memory>
8 #include <string_view>
9
10 #include "base/strings/string_util.h"
11 #include "base/values.h"
12 #include "gn/err.h"
13 #include "gn/filesystem_utils.h"
14 #include "gn/graph/include/module.h"
15 #include "gn/graph/include/node.h"
16 #include "gn/item.h"
17 #include "gn/label.h"
18 #include "gn/ohos_components.h"
19 #include "gn/ohos_components_checker.h"
20 #include "gn/precise/precise.h"
21 #include "gn/scope.h"
22 #include "gn/value.h"
23 #include "gn/variables.h"
24
25 Visibility::Visibility() = default;
26
27 Visibility::~Visibility() = default;
28
Set(const SourceDir & current_dir,std::string_view source_root,const Value & value,Err * err)29 bool Visibility::Set(const SourceDir& current_dir,
30 std::string_view source_root,
31 const Value& value,
32 Err* err) {
33 patterns_.clear();
34
35 if (!value.VerifyTypeIs(Value::LIST, err)) {
36 CHECK(err->has_error());
37 return false;
38 }
39
40 for (const auto& item : value.list_value()) {
41 patterns_.push_back(
42 LabelPattern::GetPattern(current_dir, source_root, item, err));
43 if (err->has_error())
44 return false;
45 }
46 return true;
47 }
48
SetPublic()49 void Visibility::SetPublic() {
50 patterns_.clear();
51 patterns_.push_back(LabelPattern(LabelPattern::RECURSIVE_DIRECTORY,
52 SourceDir(), std::string(), Label()));
53 }
54
SetPrivate(const SourceDir & current_dir)55 void Visibility::SetPrivate(const SourceDir& current_dir) {
56 patterns_.clear();
57 patterns_.push_back(LabelPattern(LabelPattern::DIRECTORY, current_dir,
58 std::string(), Label()));
59 }
60
CanSeeMe(const Label & label) const61 bool Visibility::CanSeeMe(const Label& label) const {
62 return LabelPattern::VectorMatches(patterns_, label);
63 }
64
Describe(int indent,bool include_brackets) const65 std::string Visibility::Describe(int indent, bool include_brackets) const {
66 std::string outer_indent_string(indent, ' ');
67
68 if (patterns_.empty())
69 return outer_indent_string + "[] (no visibility)\n";
70
71 std::string result;
72
73 std::string inner_indent_string = outer_indent_string;
74 if (include_brackets) {
75 result += outer_indent_string + "[\n";
76 // Indent the insides more if brackets are requested.
77 inner_indent_string += " ";
78 }
79
80 for (const auto& pattern : patterns_)
81 result += inner_indent_string + pattern.Describe() + "\n";
82
83 if (include_brackets)
84 result += outer_indent_string + "]\n";
85 return result;
86 }
87
AsValue() const88 std::unique_ptr<base::Value> Visibility::AsValue() const {
89 auto res = std::make_unique<base::ListValue>();
90 for (const auto& pattern : patterns_)
91 res->AppendString(pattern.Describe());
92 return res;
93 }
94
95 // static
CheckItemVisibility(const Item * from,const Item * to,bool is_external_deps,Err * err)96 bool Visibility::CheckItemVisibility(const Item *from, const Item *to, bool is_external_deps, Err *err) {
97 std::string to_label = to->label().GetUserVisibleName(false);
98 std::string from_label = from->label().GetUserVisibleName(false);
99 if (!to->visibility().CanSeeMe(from->label())) {
100 *err = Err(from->defined_from(), "Dependency not allowed.",
101 "The item " + from->label().GetUserVisibleName(false) +
102 "\n"
103 "can not depend on " +
104 to_label +
105 "\n"
106 "because it is not in " +
107 to_label + "'s visibility list: " + to->visibility().Describe(0, true));
108 return false;
109 }
110 const OhosComponent *from_component = from->ohos_component();
111 const OhosComponent *to_component = to->ohos_component();
112
113 PreciseManager* precisehManager = PreciseManager::GetInstance();
114 if (precisehManager != nullptr) {
115 Node *fromNode = precisehManager->GetModule(from_label);
116 if (!fromNode) {
117 fromNode = new Module(from_label, from_label, from);
118 }
119 Node *toNode = precisehManager->GetModule(to_label);
120 if (!toNode) {
121 toNode = new Module(to_label, to_label, to);
122 }
123 fromNode->AddTo(toNode);
124 toNode->AddFrom(fromNode);
125 precisehManager->AddModule(from_label, fromNode);
126 precisehManager->AddModule(to_label, toNode);
127 }
128
129 if ((from_component == nullptr) || (to_component == nullptr)) {
130 return true;
131 }
132 if (to_component->name() == "build_framework") {
133 return true;
134 }
135 if (from_component->name() == "build_framework") {
136 return true;
137 }
138 if (from_component == to_component) {
139 return true;
140 }
141
142 OhosComponentChecker *checker = OhosComponentChecker::getInstance();
143 if (checker != nullptr) {
144 if (!checker->CheckInnerApiNotLib(to, to_component, from_label, to_label, err) ||
145 !checker->CheckInnerApiNotDeclare(to, to_component, to_label, err) ||
146 !checker->CheckTargetAbsoluteDepsOther(from, to_component, from_label, to_label, is_external_deps, err) ||
147 !checker->CheckInnerApiVisibilityDenied(from, to_component, from_label, to_label, err)) {
148 return false;
149 }
150 }
151 return true;
152 }
153
154 // static
FillItemVisibility(Item * item,Scope * scope,Err * err)155 bool Visibility::FillItemVisibility(Item* item, Scope* scope, Err* err) {
156 const Value* vis_value = scope->GetValue(variables::kVisibility, true);
157 if (vis_value)
158 item->visibility().Set(
159 scope->GetSourceDir(),
160 scope->settings()->build_settings()->root_path_utf8(), *vis_value, err);
161 else // Default to public.
162 item->visibility().SetPublic();
163 return !err->has_error();
164 }
165