blob: b32586ce13e62537cca0796dccb82a840d8091a5 [file] [log] [blame]
[email protected]60c9d172014-04-01 21:45:111// 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 "tools/gn/visibility.h"
6
dpranke05316e02016-07-19 00:45:187#include "base/memory/ptr_util.h"
[email protected]60c9d172014-04-01 21:45:118#include "base/strings/string_piece.h"
9#include "base/strings/string_util.h"
dpranke05316e02016-07-19 00:45:1810#include "base/values.h"
[email protected]60c9d172014-04-01 21:45:1111#include "tools/gn/err.h"
12#include "tools/gn/filesystem_utils.h"
13#include "tools/gn/item.h"
14#include "tools/gn/label.h"
15#include "tools/gn/scope.h"
16#include "tools/gn/value.h"
17#include "tools/gn/variables.h"
18
[email protected]60c9d172014-04-01 21:45:1119Visibility::Visibility() {
20}
21
22Visibility::~Visibility() {
23}
24
25bool Visibility::Set(const SourceDir& current_dir,
26 const Value& value,
27 Err* err) {
28 patterns_.clear();
29
Brett Wilson19b5fdb2014-09-11 17:19:1930 if (!value.VerifyTypeIs(Value::LIST, err)) {
31 CHECK(err->has_error());
[email protected]60c9d172014-04-01 21:45:1132 return false;
Brett Wilson19b5fdb2014-09-11 17:19:1933 }
[email protected]60c9d172014-04-01 21:45:1134
brettwd1033b62014-09-30 21:44:0535 for (const auto& item : value.list_value()) {
36 patterns_.push_back(LabelPattern::GetPattern(current_dir, item, err));
[email protected]60c9d172014-04-01 21:45:1137 if (err->has_error())
38 return false;
39 }
40 return true;
41}
42
43void Visibility::SetPublic() {
[email protected]fce5c3fe2014-04-10 21:13:0544 patterns_.clear();
[email protected]60c9d172014-04-01 21:45:1145 patterns_.push_back(
brettw3741b722014-08-29 17:07:2046 LabelPattern(LabelPattern::RECURSIVE_DIRECTORY, SourceDir(),
47 std::string(), Label()));
[email protected]60c9d172014-04-01 21:45:1148}
49
50void Visibility::SetPrivate(const SourceDir& current_dir) {
[email protected]fce5c3fe2014-04-10 21:13:0551 patterns_.clear();
[email protected]60c9d172014-04-01 21:45:1152 patterns_.push_back(
brettw3741b722014-08-29 17:07:2053 LabelPattern(LabelPattern::DIRECTORY, current_dir, std::string(),
54 Label()));
[email protected]60c9d172014-04-01 21:45:1155}
56
57bool Visibility::CanSeeMe(const Label& label) const {
brettwd1033b62014-09-30 21:44:0558 for (const auto& pattern : patterns_) {
59 if (pattern.Matches(label))
[email protected]60c9d172014-04-01 21:45:1160 return true;
61 }
62 return false;
63}
64
[email protected]c1e5ca82014-06-02 20:52:0065std::string Visibility::Describe(int indent, bool include_brackets) const {
66 std::string outer_indent_string(indent, ' ');
67
[email protected]60c9d172014-04-01 21:45:1168 if (patterns_.empty())
[email protected]c1e5ca82014-06-02 20:52:0069 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 }
[email protected]60c9d172014-04-01 21:45:1179
brettwd1033b62014-09-30 21:44:0580 for (const auto& pattern : patterns_)
81 result += inner_indent_string + pattern.Describe() + "\n";
[email protected]60c9d172014-04-01 21:45:1182
[email protected]c1e5ca82014-06-02 20:52:0083 if (include_brackets)
84 result += outer_indent_string + "]\n";
[email protected]60c9d172014-04-01 21:45:1185 return result;
86}
87
dpranke05316e02016-07-19 00:45:1888std::unique_ptr<base::Value> Visibility::AsValue() const {
89 auto* res = new base::ListValue();
90 for (const auto& pattern : patterns_)
91 res->AppendString(pattern.Describe());
92
93 return WrapUnique(res);
94}
95
[email protected]60c9d172014-04-01 21:45:1196// static
[email protected]60c9d172014-04-01 21:45:1197bool Visibility::CheckItemVisibility(const Item* from,
98 const Item* to,
99 Err* err) {
100 if (!to->visibility().CanSeeMe(from->label())) {
101 std::string to_label = to->label().GetUserVisibleName(false);
102 *err = Err(from->defined_from(), "Dependency not allowed.",
103 "The item " + from->label().GetUserVisibleName(false) + "\n"
104 "can not depend on " + to_label + "\n"
105 "because it is not in " + to_label + "'s visibility list: " +
dpranke05316e02016-07-19 00:45:18106 to->visibility().Describe(0, true));
[email protected]60c9d172014-04-01 21:45:11107 return false;
108 }
109 return true;
110}
111
112// static
113bool Visibility::FillItemVisibility(Item* item, Scope* scope, Err* err) {
114 const Value* vis_value = scope->GetValue(variables::kVisibility, true);
115 if (vis_value)
116 item->visibility().Set(scope->GetSourceDir(), *vis_value, err);
117 else // Default to public.
118 item->visibility().SetPublic();
119 return !err->has_error();
120}