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

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

Issue 2940873002: Implement tracking of BUILD.gn files used to define target, toolchain or (Closed)
Patch Set: Fix compilation after rebase. Created 3 years, 5 months 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
« no previous file with comments | « tools/gn/analyzer.h ('k') | tools/gn/analyzer_unittest.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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "tools/gn/analyzer.h" 5 #include "tools/gn/analyzer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/json/json_reader.h" 12 #include "base/json/json_reader.h"
13 #include "base/json/json_writer.h" 13 #include "base/json/json_writer.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/string_util.h"
17 #include "base/values.h" 16 #include "base/values.h"
18 #include "tools/gn/builder.h" 17 #include "tools/gn/builder.h"
19 #include "tools/gn/deps_iterator.h" 18 #include "tools/gn/deps_iterator.h"
20 #include "tools/gn/err.h" 19 #include "tools/gn/err.h"
21 #include "tools/gn/filesystem_utils.h" 20 #include "tools/gn/filesystem_utils.h"
21 #include "tools/gn/input_file.h"
22 #include "tools/gn/loader.h" 22 #include "tools/gn/loader.h"
23 #include "tools/gn/location.h" 23 #include "tools/gn/location.h"
24 #include "tools/gn/source_file.h" 24 #include "tools/gn/source_file.h"
25 #include "tools/gn/target.h" 25 #include "tools/gn/target.h"
26 26
27 using LabelSet = Analyzer::LabelSet; 27 using LabelSet = Analyzer::LabelSet;
28 using SourceFileSet = Analyzer::SourceFileSet; 28 using SourceFileSet = Analyzer::SourceFileSet;
29 using TargetSet = Analyzer::TargetSet; 29 using TargetSet = Analyzer::TargetSet;
30 30
31 namespace { 31 namespace {
(...skipping 17 matching lines...) Expand all
49 LabelSet invalid_labels; 49 LabelSet invalid_labels;
50 }; 50 };
51 51
52 LabelSet LabelsFor(const TargetSet& targets) { 52 LabelSet LabelsFor(const TargetSet& targets) {
53 LabelSet labels; 53 LabelSet labels;
54 for (auto* target : targets) 54 for (auto* target : targets)
55 labels.insert(target->label()); 55 labels.insert(target->label());
56 return labels; 56 return labels;
57 } 57 }
58 58
59 bool AnyBuildFilesWereModified(const SourceFileSet& source_files) {
60 for (auto* file : source_files) {
61 if (base::EndsWith(file->value(), ".gn", base::CompareCase::SENSITIVE) ||
62 base::EndsWith(file->value(), ".gni", base::CompareCase::SENSITIVE) ||
63 base::EndsWith(file->value(), "build/vs_toolchain.py",
64 base::CompareCase::SENSITIVE))
65 return true;
66 }
67 return false;
68 }
69
70 TargetSet Intersect(const TargetSet& l, const TargetSet& r) { 59 TargetSet Intersect(const TargetSet& l, const TargetSet& r) {
71 TargetSet result; 60 TargetSet result;
72 std::set_intersection(l.begin(), l.end(), r.begin(), r.end(), 61 std::set_intersection(l.begin(), l.end(), r.begin(), r.end(),
73 std::inserter(result, result.begin())); 62 std::inserter(result, result.begin()));
74 return result; 63 return result;
75 } 64 }
76 65
77 std::vector<std::string> GetStringVector(const base::DictionaryValue& dict, 66 std::vector<std::string> GetStringVector(const base::DictionaryValue& dict,
78 const std::string& key, 67 const std::string& key,
79 Err* err) { 68 Err* err) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 WriteLabels(default_toolchain, *value, "test_targets", outputs.test_labels); 207 WriteLabels(default_toolchain, *value, "test_targets", outputs.test_labels);
219 } 208 }
220 209
221 if (!base::JSONWriter::Write(*value.get(), &output)) 210 if (!base::JSONWriter::Write(*value.get(), &output))
222 *err = Err(Location(), "Failed to marshal JSON value for output"); 211 *err = Err(Location(), "Failed to marshal JSON value for output");
223 return output; 212 return output;
224 } 213 }
225 214
226 } // namespace 215 } // namespace
227 216
228 Analyzer::Analyzer(const Builder& builder) 217 Analyzer::Analyzer(const Builder& builder,
218 const SourceFile& build_config_file,
219 const SourceFile& dotgn_file)
229 : all_targets_(builder.GetAllResolvedTargets()), 220 : all_targets_(builder.GetAllResolvedTargets()),
230 default_toolchain_(builder.loader()->GetDefaultToolchain()) { 221 default_toolchain_(builder.loader()->GetDefaultToolchain()),
222 build_config_file_(build_config_file),
223 dotgn_file_(dotgn_file) {
231 for (const auto* target : all_targets_) { 224 for (const auto* target : all_targets_) {
232 labels_to_targets_[target->label()] = target; 225 labels_to_targets_[target->label()] = target;
233 for (const auto& dep_pair : target->GetDeps(Target::DEPS_ALL)) 226 for (const auto& dep_pair : target->GetDeps(Target::DEPS_ALL))
234 dep_map_.insert(std::make_pair(dep_pair.ptr, target)); 227 dep_map_.insert(std::make_pair(dep_pair.ptr, target));
235 } 228 }
236 for (const auto* target : all_targets_) { 229 for (const auto* target : all_targets_) {
237 if (dep_map_.find(target) == dep_map_.end()) 230 if (dep_map_.find(target) == dep_map_.end())
238 roots_.insert(target); 231 roots_.insert(target);
239 } 232 }
240 } 233 }
(...skipping 14 matching lines...) Expand all
255 for (const auto& label : InvalidLabels(inputs.compile_labels)) 248 for (const auto& label : InvalidLabels(inputs.compile_labels))
256 invalid_labels.insert(label); 249 invalid_labels.insert(label);
257 for (const auto& label : InvalidLabels(inputs.test_labels)) 250 for (const auto& label : InvalidLabels(inputs.test_labels))
258 invalid_labels.insert(label); 251 invalid_labels.insert(label);
259 if (!invalid_labels.empty()) { 252 if (!invalid_labels.empty()) {
260 outputs.error = "Invalid targets"; 253 outputs.error = "Invalid targets";
261 outputs.invalid_labels = invalid_labels; 254 outputs.invalid_labels = invalid_labels;
262 return OutputsToJSON(outputs, default_toolchain_, err); 255 return OutputsToJSON(outputs, default_toolchain_, err);
263 } 256 }
264 257
265 // TODO(crbug.com/555273): We can do smarter things when we detect changes 258 if (WereMainGNFilesModified(inputs.source_files)) {
266 // to build files. For example, if all of the ninja files are unchanged,
267 // we know that we can ignore changes to .gn* files. Also, for most .gn
268 // files, we can treat a change as simply affecting every target, config,
269 // or toolchain defined in that file.
270 if (AnyBuildFilesWereModified(inputs.source_files)) {
271 outputs.status = "Found dependency (all)"; 259 outputs.status = "Found dependency (all)";
272 if (inputs.compile_included_all) { 260 if (inputs.compile_included_all) {
273 outputs.compile_includes_all = true; 261 outputs.compile_includes_all = true;
274 } else { 262 } else {
275 outputs.compile_labels.insert(inputs.compile_labels.begin(), 263 outputs.compile_labels.insert(inputs.compile_labels.begin(),
276 inputs.compile_labels.end()); 264 inputs.compile_labels.end());
277 outputs.compile_labels.insert(inputs.test_labels.begin(), 265 outputs.compile_labels.insert(inputs.test_labels.begin(),
278 inputs.test_labels.end()); 266 inputs.test_labels.end());
279 } 267 }
280 outputs.test_labels = inputs.test_labels; 268 outputs.test_labels = inputs.test_labels;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 filtered->insert(target); 341 filtered->insert(target);
354 } else { 342 } else {
355 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) 343 for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
356 FilterTarget(pair.ptr, seen, filtered); 344 FilterTarget(pair.ptr, seen, filtered);
357 } 345 }
358 } 346 }
359 } 347 }
360 348
361 bool Analyzer::TargetRefersToFile(const Target* target, 349 bool Analyzer::TargetRefersToFile(const Target* target,
362 const SourceFile* file) const { 350 const SourceFile* file) const {
351 for (const auto* cur_file : target->input_files()) {
352 if (cur_file->name() == *file)
353 return true;
354 }
363 for (const auto& cur_file : target->sources()) { 355 for (const auto& cur_file : target->sources()) {
364 if (cur_file == *file) 356 if (cur_file == *file)
365 return true; 357 return true;
366 } 358 }
367 for (const auto& cur_file : target->public_headers()) { 359 for (const auto& cur_file : target->public_headers()) {
368 if (cur_file == *file) 360 if (cur_file == *file)
369 return true; 361 return true;
370 } 362 }
371 for (const auto& cur_file : target->inputs()) { 363 for (const auto& cur_file : target->inputs()) {
372 if (cur_file == *file) 364 if (cur_file == *file)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 void Analyzer::AddAllRefsTo(const Target* target, TargetSet* results) const { 397 void Analyzer::AddAllRefsTo(const Target* target, TargetSet* results) const {
406 if (results->find(target) != results->end()) 398 if (results->find(target) != results->end())
407 return; // Already found this target. 399 return; // Already found this target.
408 results->insert(target); 400 results->insert(target);
409 401
410 auto dep_begin = dep_map_.lower_bound(target); 402 auto dep_begin = dep_map_.lower_bound(target);
411 auto dep_end = dep_map_.upper_bound(target); 403 auto dep_end = dep_map_.upper_bound(target);
412 for (auto cur_dep = dep_begin; cur_dep != dep_end; cur_dep++) 404 for (auto cur_dep = dep_begin; cur_dep != dep_end; cur_dep++)
413 AddAllRefsTo(cur_dep->second, results); 405 AddAllRefsTo(cur_dep->second, results);
414 } 406 }
407
408 bool Analyzer::WereMainGNFilesModified(
409 const SourceFileSet& source_files) const {
410 for (auto* file : source_files) {
411 if (*file == dotgn_file_ || *file == build_config_file_)
412 return true;
413 }
414 return false;
415 }
OLDNEW
« no previous file with comments | « tools/gn/analyzer.h ('k') | tools/gn/analyzer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698