1 // Copyright 2019 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef NINJA_MISSING_DEPS_H_
16 #define NINJA_MISSING_DEPS_H_
17 
18 #include <map>
19 #include <set>
20 #include <string>
21 
22 #include <unordered_map>
23 
24 struct DepsLog;
25 struct DiskInterface;
26 struct Edge;
27 struct Node;
28 struct Rule;
29 struct State;
30 
31 class MissingDependencyScannerDelegate {
32  public:
33   virtual ~MissingDependencyScannerDelegate();
34   virtual void OnMissingDep(Node* node, const std::string& path,
35                             const Rule& generator) = 0;
36 };
37 
38 class MissingDependencyPrinter : public MissingDependencyScannerDelegate {
39   void OnMissingDep(Node* node, const std::string& path, const Rule& generator);
40   void OnStats(int nodes_processed, int nodes_missing_deps,
41                int missing_dep_path_count, int generated_nodes,
42                int generator_rules);
43 };
44 
45 struct MissingDependencyScanner {
46  public:
47   MissingDependencyScanner(MissingDependencyScannerDelegate* delegate,
48                            DepsLog* deps_log, State* state,
49                            DiskInterface* disk_interface);
50   void ProcessNode(Node* node);
51   void PrintStats();
HadMissingDepsMissingDependencyScanner52   bool HadMissingDeps() { return !nodes_missing_deps_.empty(); }
53 
54   void ProcessNodeDeps(Node* node, Node** dep_nodes, int dep_nodes_count);
55 
56   bool PathExistsBetween(Edge* from, Edge* to);
57 
58   MissingDependencyScannerDelegate* delegate_;
59   DepsLog* deps_log_;
60   State* state_;
61   DiskInterface* disk_interface_;
62   std::set<Node*> seen_;
63   std::set<Node*> nodes_missing_deps_;
64   std::set<Node*> generated_nodes_;
65   std::set<const Rule*> generator_rules_;
66   int missing_dep_path_count_;
67 
68  private:
69   using InnerAdjacencyMap = std::unordered_map<Edge*, bool>;
70   using AdjacencyMap = std::unordered_map<Edge*, InnerAdjacencyMap>;
71   AdjacencyMap adjacency_map_;
72 };
73 
74 #endif  // NINJA_MISSING_DEPS_H_
75