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 7 #include "base/strings/string_piece.h" 8 #include "base/strings/string_util.h" 9 #include "tools/gn/err.h" 10 #include "tools/gn/filesystem_utils.h" 11 #include "tools/gn/item.h" 12 #include "tools/gn/label.h" 13 #include "tools/gn/scope.h" 14 #include "tools/gn/value.h" 15 #include "tools/gn/variables.h" 16 17 Visibility::Visibility() { 18 } 19 20 Visibility::~Visibility() { 21 } 22 23 bool Visibility::Set(const SourceDir& current_dir, 24 const Value& value, 25 Err* err) { 26 patterns_.clear(); 27 28 if (!value.VerifyTypeIs(Value::LIST, err)) { 29 CHECK(err->has_error()); 30 return false; 31 } 32 33 const std::vector<Value>& list = value.list_value(); 34 for (size_t i = 0; i < list.size(); i++) { 35 patterns_.push_back(LabelPattern::GetPattern(current_dir, list[i], err)); 36 if (err->has_error()) 37 return false; 38 } 39 return true; 40 } 41 42 void Visibility::SetPublic() { 43 patterns_.clear(); 44 patterns_.push_back( 45 LabelPattern(LabelPattern::RECURSIVE_DIRECTORY, SourceDir(), 46 std::string(), Label())); 47 } 48 49 void Visibility::SetPrivate(const SourceDir& current_dir) { 50 patterns_.clear(); 51 patterns_.push_back( 52 LabelPattern(LabelPattern::DIRECTORY, current_dir, std::string(), 53 Label())); 54 } 55 56 bool Visibility::CanSeeMe(const Label& label) const { 57 for (size_t i = 0; i < patterns_.size(); i++) { 58 if (patterns_[i].Matches(label)) 59 return true; 60 } 61 return false; 62 } 63 64 std::string Visibility::Describe(int indent, bool include_brackets) const { 65 std::string outer_indent_string(indent, ' '); 66 67 if (patterns_.empty()) 68 return outer_indent_string + "[] (no visibility)\n"; 69 70 std::string result; 71 72 std::string inner_indent_string = outer_indent_string; 73 if (include_brackets) { 74 result += outer_indent_string + "[\n"; 75 // Indent the insides more if brackets are requested. 76 inner_indent_string += " "; 77 } 78 79 for (size_t i = 0; i < patterns_.size(); i++) 80 result += inner_indent_string + patterns_[i].Describe() + "\n"; 81 82 if (include_brackets) 83 result += outer_indent_string + "]\n"; 84 return result; 85 } 86 87 // static 88 bool Visibility::CheckItemVisibility(const Item* from, 89 const Item* to, 90 Err* err) { 91 if (!to->visibility().CanSeeMe(from->label())) { 92 std::string to_label = to->label().GetUserVisibleName(false); 93 *err = Err(from->defined_from(), "Dependency not allowed.", 94 "The item " + from->label().GetUserVisibleName(false) + "\n" 95 "can not depend on " + to_label + "\n" 96 "because it is not in " + to_label + "'s visibility list: " + 97 to->visibility().Describe(0, true)); 98 return false; 99 } 100 return true; 101 } 102 103 // static 104 bool Visibility::FillItemVisibility(Item* item, Scope* scope, Err* err) { 105 const Value* vis_value = scope->GetValue(variables::kVisibility, true); 106 if (vis_value) 107 item->visibility().Set(scope->GetSourceDir(), *vis_value, err); 108 else // Default to public. 109 item->visibility().SetPublic(); 110 return !err->has_error(); 111 } 112