Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: tools/gn/command_desc.cc

Issue 48523006: GN: Separately track labels and origins for lists of stuff (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/command_gyp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <set> 6 #include <set>
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "tools/gn/commands.h" 10 #include "tools/gn/commands.h"
11 #include "tools/gn/config.h" 11 #include "tools/gn/config.h"
12 #include "tools/gn/config_values_extractors.h" 12 #include "tools/gn/config_values_extractors.h"
13 #include "tools/gn/item.h" 13 #include "tools/gn/item.h"
14 #include "tools/gn/item_node.h" 14 #include "tools/gn/item_node.h"
15 #include "tools/gn/label.h" 15 #include "tools/gn/label.h"
16 #include "tools/gn/setup.h" 16 #include "tools/gn/setup.h"
17 #include "tools/gn/standard_out.h" 17 #include "tools/gn/standard_out.h"
18 #include "tools/gn/target.h" 18 #include "tools/gn/target.h"
19 19
20 namespace commands { 20 namespace commands {
21 21
22 namespace { 22 namespace {
23 23
24 struct CompareTargetLabel {
25 bool operator()(const Target* a, const Target* b) const {
26 return a->label() < b->label();
27 }
28 };
29
30 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result); 24 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result);
31 25
32 void RecursiveCollectDeps(const Target* target, std::set<Label>* result) { 26 void RecursiveCollectDeps(const Target* target, std::set<Label>* result) {
33 if (result->find(target->label()) != result->end()) 27 if (result->find(target->label()) != result->end())
34 return; // Already did this target. 28 return; // Already did this target.
35 result->insert(target->label()); 29 result->insert(target->label());
36 30
37 RecursiveCollectChildDeps(target, result); 31 RecursiveCollectChildDeps(target, result);
38 } 32 }
39 33
40 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) { 34 void RecursiveCollectChildDeps(const Target* target, std::set<Label>* result) {
41 const std::vector<const Target*>& deps = target->deps(); 35 const LabelTargetVector& deps = target->deps();
42 for (size_t i = 0; i < deps.size(); i++) 36 for (size_t i = 0; i < deps.size(); i++)
43 RecursiveCollectDeps(deps[i], result); 37 RecursiveCollectDeps(deps[i].ptr, result);
44 38
45 const std::vector<const Target*>& datadeps = target->datadeps(); 39 const LabelTargetVector& datadeps = target->datadeps();
46 for (size_t i = 0; i < datadeps.size(); i++) 40 for (size_t i = 0; i < datadeps.size(); i++)
47 RecursiveCollectDeps(datadeps[i], result); 41 RecursiveCollectDeps(datadeps[i].ptr, result);
48 } 42 }
49 43
50 // Prints dependencies of the given target (not the target itself). 44 // Prints dependencies of the given target (not the target itself).
51 void RecursivePrintDeps(const Target* target, 45 void RecursivePrintDeps(const Target* target,
52 const Label& default_toolchain, 46 const Label& default_toolchain,
53 int indent_level) { 47 int indent_level) {
54 std::vector<const Target*> sorted_deps = target->deps(); 48 LabelTargetVector sorted_deps = target->deps();
55 const std::vector<const Target*> datadeps = target->datadeps(); 49 const LabelTargetVector& datadeps = target->datadeps();
56 for (size_t i = 0; i < datadeps.size(); i++) 50 sorted_deps.insert(sorted_deps.end(), datadeps.begin(), datadeps.end());
57 sorted_deps.push_back(datadeps[i]); 51 std::sort(sorted_deps.begin(), sorted_deps.end(),
58 std::sort(sorted_deps.begin(), sorted_deps.end(), CompareTargetLabel()); 52 LabelPtrLabelLess<Target>());
59 53
60 std::string indent(indent_level * 2, ' '); 54 std::string indent(indent_level * 2, ' ');
61 for (size_t i = 0; i < sorted_deps.size(); i++) { 55 for (size_t i = 0; i < sorted_deps.size(); i++) {
62 OutputString(indent + 56 OutputString(indent +
63 sorted_deps[i]->label().GetUserVisibleName(default_toolchain) + "\n"); 57 sorted_deps[i].label.GetUserVisibleName(default_toolchain) + "\n");
64 RecursivePrintDeps(sorted_deps[i], default_toolchain, indent_level + 1); 58 RecursivePrintDeps(sorted_deps[i].ptr, default_toolchain, indent_level + 1);
65 } 59 }
66 } 60 }
67 61
68 void PrintDeps(const Target* target, bool display_header) { 62 void PrintDeps(const Target* target, bool display_header) {
69 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); 63 const CommandLine* cmdline = CommandLine::ForCurrentProcess();
70 Label toolchain_label = target->label().GetToolchainLabel(); 64 Label toolchain_label = target->label().GetToolchainLabel();
71 65
72 // Tree mode is separate. 66 // Tree mode is separate.
73 if (cmdline->HasSwitch("tree")) { 67 if (cmdline->HasSwitch("tree")) {
74 if (display_header) 68 if (display_header)
(...skipping 12 matching lines...) Expand all
87 RecursiveCollectChildDeps(target, &all_deps); 81 RecursiveCollectChildDeps(target, &all_deps);
88 for (std::set<Label>::iterator i = all_deps.begin(); 82 for (std::set<Label>::iterator i = all_deps.begin();
89 i != all_deps.end(); ++i) 83 i != all_deps.end(); ++i)
90 deps.push_back(*i); 84 deps.push_back(*i);
91 } else { 85 } else {
92 if (display_header) { 86 if (display_header) {
93 OutputString("\nDirect dependencies " 87 OutputString("\nDirect dependencies "
94 "(try also \"--all\" and \"--tree\"):\n"); 88 "(try also \"--all\" and \"--tree\"):\n");
95 } 89 }
96 90
97 const std::vector<const Target*>& target_deps = target->deps(); 91 const LabelTargetVector& target_deps = target->deps();
98 for (size_t i = 0; i < target_deps.size(); i++) 92 for (size_t i = 0; i < target_deps.size(); i++)
99 deps.push_back(target_deps[i]->label()); 93 deps.push_back(target_deps[i].label);
100 94
101 const std::vector<const Target*>& target_datadeps = target->datadeps(); 95 const LabelTargetVector& target_datadeps = target->datadeps();
102 for (size_t i = 0; i < target_datadeps.size(); i++) 96 for (size_t i = 0; i < target_datadeps.size(); i++)
103 deps.push_back(target_datadeps[i]->label()); 97 deps.push_back(target_datadeps[i].label);
104 } 98 }
105 99
106 std::sort(deps.begin(), deps.end()); 100 std::sort(deps.begin(), deps.end());
107 for (size_t i = 0; i < deps.size(); i++) 101 for (size_t i = 0; i < deps.size(); i++)
108 OutputString(" " + deps[i].GetUserVisibleName(toolchain_label) + "\n"); 102 OutputString(" " + deps[i].GetUserVisibleName(toolchain_label) + "\n");
109 } 103 }
110 104
111 // libs and lib_dirs are special in that they're inherited. We don't currently 105 // libs and lib_dirs are special in that they're inherited. We don't currently
112 // implement a blame feature for this since the bottom-up inheritance makes 106 // implement a blame feature for this since the bottom-up inheritance makes
113 // this difficult. 107 // this difficult.
(...skipping 20 matching lines...) Expand all
134 for (size_t i = 0; i < libs.size(); i++) 128 for (size_t i = 0; i < libs.size(); i++)
135 OutputString(" " + libs[i] + "\n"); 129 OutputString(" " + libs[i] + "\n");
136 } 130 }
137 131
138 void PrintConfigs(const Target* target, bool display_header) { 132 void PrintConfigs(const Target* target, bool display_header) {
139 // Configs (don't sort since the order determines how things are processed). 133 // Configs (don't sort since the order determines how things are processed).
140 if (display_header) 134 if (display_header)
141 OutputString("\nConfigs (in order applying):\n"); 135 OutputString("\nConfigs (in order applying):\n");
142 136
143 Label toolchain_label = target->label().GetToolchainLabel(); 137 Label toolchain_label = target->label().GetToolchainLabel();
144 const std::vector<const Config*>& configs = target->configs(); 138 const LabelConfigVector& configs = target->configs();
145 for (size_t i = 0; i < configs.size(); i++) { 139 for (size_t i = 0; i < configs.size(); i++) {
146 OutputString(" " + 140 OutputString(" " +
147 configs[i]->label().GetUserVisibleName(toolchain_label) + "\n"); 141 configs[i].label.GetUserVisibleName(toolchain_label) + "\n");
148 } 142 }
149 } 143 }
150 144
151 void PrintSources(const Target* target, bool display_header) { 145 void PrintSources(const Target* target, bool display_header) {
152 if (display_header) 146 if (display_header)
153 OutputString("\nSources:\n"); 147 OutputString("\nSources:\n");
154 148
155 Target::FileList sources = target->sources(); 149 Target::FileList sources = target->sources();
156 std::sort(sources.begin(), sources.end()); 150 std::sort(sources.begin(), sources.end());
157 for (size_t i = 0; i < sources.size(); i++) 151 for (size_t i = 0; i < sources.size(); i++)
158 OutputString(" " + sources[i].value() + "\n"); 152 OutputString(" " + sources[i].value() + "\n");
159 } 153 }
160 154
161 // Attempts to attribute the gen dependency of the given target to some source 155 // Attribute the origin for attributing from where a target came from. Does
162 // code and outputs the string to the output stream. 156 // nothing if the input is null or it does not have a location.
163 // 157 void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) {
164 // The attribution of the source of the dependencies is stored in the ItemNode 158 if (!origin)
165 // which is the parallel structure to the target dependency map, so we have
166 // to jump through a few loops to find everything.
167 void OutputSourceOfDep(const Target* target,
168 const Label& dep_label,
169 std::ostream& out) {
170 ItemTree& item_tree = target->settings()->build_settings()->item_tree();
171 base::AutoLock lock(item_tree.lock());
172
173 const ItemNode* target_node = target->item_node();
174 CHECK(target_node);
175 ItemNode* dep_node = item_tree.GetExistingNodeLocked(dep_label);
176 CHECK(dep_node);
177
178 const ItemNode::ItemNodeMap& direct_deps = target_node->direct_dependencies();
179 ItemNode::ItemNodeMap::const_iterator found = direct_deps.find(dep_node);
180 if (found == direct_deps.end())
181 return; 159 return;
182 160 Location location = origin->GetRange().begin();
183 const Location& location = found->second.begin();
184 out << " (Added by " + location.file()->name().value() << ":" 161 out << " (Added by " + location.file()->name().value() << ":"
185 << location.line_number() << ")\n"; 162 << location.line_number() << ")\n";
186 } 163 }
187 164
188 // Templatized writer for writing out different config value types. 165 // Templatized writer for writing out different config value types.
189 template<typename T> struct DescValueWriter {}; 166 template<typename T> struct DescValueWriter {};
190 template<> struct DescValueWriter<std::string> { 167 template<> struct DescValueWriter<std::string> {
191 void operator()(const std::string& str, std::ostream& out) const { 168 void operator()(const std::string& str, std::ostream& out) const {
192 out << " " << str << "\n"; 169 out << " " << str << "\n";
193 } 170 }
(...skipping 23 matching lines...) Expand all
217 for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) { 194 for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
218 if ((iter.cur().*getter)().empty()) 195 if ((iter.cur().*getter)().empty())
219 continue; 196 continue;
220 197
221 // Optional blame sub-head. 198 // Optional blame sub-head.
222 if (display_blame) { 199 if (display_blame) {
223 const Config* config = iter.GetCurrentConfig(); 200 const Config* config = iter.GetCurrentConfig();
224 if (config) { 201 if (config) {
225 // Source of this value is a config. 202 // Source of this value is a config.
226 out << " From " << config->label().GetUserVisibleName(false) << "\n"; 203 out << " From " << config->label().GetUserVisibleName(false) << "\n";
227 OutputSourceOfDep(target, config->label(), out); 204 OutputSourceOfDep(iter.origin(), out);
228 } else { 205 } else {
229 // Source of this value is the target itself. 206 // Source of this value is the target itself.
230 out << " From " << target->label().GetUserVisibleName(false) << "\n"; 207 out << " From " << target->label().GetUserVisibleName(false) << "\n";
231 } 208 }
232 } 209 }
233 210
234 // Actual values. 211 // Actual values.
235 ConfigValuesToStream(iter.cur(), getter, writer, out); 212 ConfigValuesToStream(iter.cur(), getter, writer, out);
236 } 213 }
237 214
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 OUTPUT_CONFIG_VALUE(ldflags, std::string) 363 OUTPUT_CONFIG_VALUE(ldflags, std::string)
387 PrintLibs(target, true); 364 PrintLibs(target, true);
388 PrintLibDirs(target, true); 365 PrintLibDirs(target, true);
389 366
390 PrintDeps(target, true); 367 PrintDeps(target, true);
391 368
392 return 0; 369 return 0;
393 } 370 }
394 371
395 } // namespace commands 372 } // namespace commands
OLDNEW
« no previous file with comments | « tools/gn/BUILD.gn ('k') | tools/gn/command_gyp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698