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