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