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
24struct DepsLog;
25struct DiskInterface;
26struct Edge;
27struct Node;
28struct Rule;
29struct State;
30
31class MissingDependencyScannerDelegate {
32 public:
33 virtual ~MissingDependencyScannerDelegate();
34 virtual void OnMissingDep(Node* node, const std::string& path,
35 const Rule& generator) = 0;
36};
37
38class 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
45struct 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();
52 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