• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Visibility()17 Visibility::Visibility() {
18 }
19 
~Visibility()20 Visibility::~Visibility() {
21 }
22 
Set(const SourceDir & current_dir,const Value & value,Err * err)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 
SetPublic()42 void Visibility::SetPublic() {
43   patterns_.clear();
44   patterns_.push_back(
45       LabelPattern(LabelPattern::RECURSIVE_DIRECTORY, SourceDir(),
46       std::string(), Label()));
47 }
48 
SetPrivate(const SourceDir & current_dir)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 
CanSeeMe(const Label & label) const56 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 
Describe(int indent,bool include_brackets) const64 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
CheckItemVisibility(const Item * from,const Item * to,Err * err)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
FillItemVisibility(Item * item,Scope * scope,Err * err)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