[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 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 "tools/gn/visibility.h" |
| 6 | |
dpranke | 05316e0 | 2016-07-19 00:45:18 | [diff] [blame] | 7 | #include "base/memory/ptr_util.h" |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 8 | #include "base/strings/string_piece.h" |
| 9 | #include "base/strings/string_util.h" |
dpranke | 05316e0 | 2016-07-19 00:45:18 | [diff] [blame] | 10 | #include "base/values.h" |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 11 | #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] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 19 | Visibility::Visibility() { |
| 20 | } |
| 21 | |
| 22 | Visibility::~Visibility() { |
| 23 | } |
| 24 | |
| 25 | bool Visibility::Set(const SourceDir& current_dir, |
| 26 | const Value& value, |
| 27 | Err* err) { |
| 28 | patterns_.clear(); |
| 29 | |
Brett Wilson | 19b5fdb | 2014-09-11 17:19:19 | [diff] [blame] | 30 | if (!value.VerifyTypeIs(Value::LIST, err)) { |
| 31 | CHECK(err->has_error()); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 32 | return false; |
Brett Wilson | 19b5fdb | 2014-09-11 17:19:19 | [diff] [blame] | 33 | } |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 34 | |
brettw | d1033b6 | 2014-09-30 21:44:05 | [diff] [blame] | 35 | for (const auto& item : value.list_value()) { |
| 36 | patterns_.push_back(LabelPattern::GetPattern(current_dir, item, err)); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 37 | if (err->has_error()) |
| 38 | return false; |
| 39 | } |
| 40 | return true; |
| 41 | } |
| 42 | |
| 43 | void Visibility::SetPublic() { |
[email protected] | fce5c3fe | 2014-04-10 21:13:05 | [diff] [blame] | 44 | patterns_.clear(); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 45 | patterns_.push_back( |
brettw | 3741b72 | 2014-08-29 17:07:20 | [diff] [blame] | 46 | LabelPattern(LabelPattern::RECURSIVE_DIRECTORY, SourceDir(), |
| 47 | std::string(), Label())); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | void Visibility::SetPrivate(const SourceDir& current_dir) { |
[email protected] | fce5c3fe | 2014-04-10 21:13:05 | [diff] [blame] | 51 | patterns_.clear(); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 52 | patterns_.push_back( |
brettw | 3741b72 | 2014-08-29 17:07:20 | [diff] [blame] | 53 | LabelPattern(LabelPattern::DIRECTORY, current_dir, std::string(), |
| 54 | Label())); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | bool Visibility::CanSeeMe(const Label& label) const { |
brettw | d1033b6 | 2014-09-30 21:44:05 | [diff] [blame] | 58 | for (const auto& pattern : patterns_) { |
| 59 | if (pattern.Matches(label)) |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 60 | return true; |
| 61 | } |
| 62 | return false; |
| 63 | } |
| 64 | |
[email protected] | c1e5ca8 | 2014-06-02 20:52:00 | [diff] [blame] | 65 | std::string Visibility::Describe(int indent, bool include_brackets) const { |
| 66 | std::string outer_indent_string(indent, ' '); |
| 67 | |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 68 | if (patterns_.empty()) |
[email protected] | c1e5ca8 | 2014-06-02 20:52:00 | [diff] [blame] | 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 | } |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 79 | |
brettw | d1033b6 | 2014-09-30 21:44:05 | [diff] [blame] | 80 | for (const auto& pattern : patterns_) |
| 81 | result += inner_indent_string + pattern.Describe() + "\n"; |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 82 | |
[email protected] | c1e5ca8 | 2014-06-02 20:52:00 | [diff] [blame] | 83 | if (include_brackets) |
| 84 | result += outer_indent_string + "]\n"; |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 85 | return result; |
| 86 | } |
| 87 | |
dpranke | 05316e0 | 2016-07-19 00:45:18 | [diff] [blame] | 88 | std::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] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 96 | // static |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 97 | bool 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: " + |
dpranke | 05316e0 | 2016-07-19 00:45:18 | [diff] [blame] | 106 | to->visibility().Describe(0, true)); |
[email protected] | 60c9d17 | 2014-04-01 21:45:11 | [diff] [blame] | 107 | return false; |
| 108 | } |
| 109 | return true; |
| 110 | } |
| 111 | |
| 112 | // static |
| 113 | bool 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 | } |