• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_ANALYZER_H_
6 #define TOOLS_GN_ANALYZER_H_
7 
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include "gn/builder.h"
13 #include "gn/item.h"
14 #include "gn/label.h"
15 #include "gn/source_file.h"
16 
17 // An Analyzer can answer questions about a build graph. It is used
18 // to answer queries for the `refs` and `analyze` commands, where we
19 // need to look at the graph in ways that can't easily be determined
20 // from just a single Target.
21 class Analyzer {
22  public:
23   Analyzer(const Builder& builder,
24            const SourceFile& build_config_file,
25            const SourceFile& dot_file,
26            const SourceFileSet& build_args_dependency_files);
27   ~Analyzer();
28 
29   // Figures out from a Buider and a JSON-formatted string containing lists
30   // of files and targets, which targets would be affected by modifications
31   // to the files . See the help text for the analyze command (kAnalyze_Help)
32   // for the specification of the input and output string formats and the
33   // expected behavior of the method.
34   std::string Analyze(const std::string& input, Err* err) const;
35 
36  private:
37   // Returns the set of all items that might be affected, directly or
38   // indirectly, by modifications to the given source files.
39   std::set<const Item*> GetAllAffectedItems(
40       const std::set<const SourceFile*>& source_files) const;
41 
42   // Returns the set of labels that do not refer to objects in the graph.
43   std::set<Label> InvalidLabels(const std::set<Label>& labels) const;
44 
45   // Returns the set of all targets that have a label in the given set.
46   // Invalid (or missing) labels will be ignored.
47   std::set<const Target*> TargetsFor(const std::set<Label>& labels) const;
48 
49   // Returns a filtered set of the given targets, meaning that for each of the
50   // given targets,
51   // - if the target is not a group, add it to the set
52   // - if the target is a group, recursively filter each dependency and add
53   //   its filtered results to the set.
54   //
55   // For example, if we had:
56   //
57   //   group("foobar") { deps = [ ":foo", ":bar" ] }
58   //   group("bar") { deps = [ ":baz", ":quux" ] }
59   //   executable("foo") { ... }
60   //   executable("baz") { ... }
61   //   executable("quux") { ... }
62   //
63   // Then the filtered version of {"foobar"} would be {":foo", ":baz",
64   // ":quux"}. This is used by the analyze command in order to only build
65   // the affected dependencies of a group (and not also build the unaffected
66   // ones).
67   //
68   // This filtering behavior is also known as "pruning" the list of targets.
69   std::set<const Target*> Filter(const std::set<const Target*>& targets) const;
70 
71   // Filter an individual target and adds the results to filtered
72   // (see Filter(), above).
73   void FilterTarget(const Target*,
74                     std::set<const Target*>* seen,
75                     std::set<const Target*>* filtered) const;
76 
77   bool ItemRefersToFile(const Item* item, const SourceFile* file) const;
78 
79   void AddItemsDirectlyReferringToFile(
80       const SourceFile* file,
81       std::set<const Item*>* affected_items) const;
82 
83   void AddAllItemsReferringToItem(const Item* item,
84                                   std::set<const Item*>* affected_items) const;
85 
86   // Main GN files stand for files whose context are used globally to execute
87   // every other build files, this list includes dot file, build config file,
88   // build args files etc.
89   bool WereMainGNFilesModified(
90       const std::set<const SourceFile*>& modified_files) const;
91 
92   std::vector<const Item*> all_items_;
93   std::map<Label, const Item*> labels_to_items_;
94   Label default_toolchain_;
95 
96   // Maps items to the list of items that depend on them.
97   std::multimap<const Item*, const Item*> dep_map_;
98 
99   const SourceFile build_config_file_;
100   const SourceFile dot_file_;
101   const SourceFileSet build_args_dependency_files_;
102 };
103 
104 #endif  // TOOLS_GN_ANALYZER_H_
105