OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/header_checker.h" | 5 #include "tools/gn/header_checker.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 "to MID. This will apply DEST's direct dependent configs to SOURCE.\n"; | 116 "to MID. This will apply DEST's direct dependent configs to SOURCE.\n"; |
117 } | 117 } |
118 | 118 |
119 } // namespace | 119 } // namespace |
120 | 120 |
121 HeaderChecker::HeaderChecker(const BuildSettings* build_settings, | 121 HeaderChecker::HeaderChecker(const BuildSettings* build_settings, |
122 const std::vector<const Target*>& targets) | 122 const std::vector<const Target*>& targets) |
123 : main_loop_(base::MessageLoop::current()), | 123 : main_loop_(base::MessageLoop::current()), |
124 build_settings_(build_settings) { | 124 build_settings_(build_settings) { |
125 for (size_t i = 0; i < targets.size(); i++) | 125 for (size_t i = 0; i < targets.size(); i++) |
126 AddTargetToFileMap(targets[i]); | 126 AddTargetToFileMap(targets[i], &file_map_); |
127 } | 127 } |
128 | 128 |
129 HeaderChecker::~HeaderChecker() { | 129 HeaderChecker::~HeaderChecker() { |
130 } | 130 } |
131 | 131 |
132 bool HeaderChecker::Run(std::vector<Err>* errors) { | 132 bool HeaderChecker::Run(const std::vector<const Target*>& to_check, |
133 ScopedTrace trace(TraceItem::TRACE_CHECK_HEADERS, "Check headers"); | 133 std::vector<Err>* errors) { |
| 134 if (to_check.empty()) { |
| 135 // Check all files. |
| 136 RunCheckOverFiles(file_map_); |
| 137 } else { |
| 138 // Run only over the files in the given targets. |
| 139 FileMap files_to_check; |
| 140 for (size_t i = 0; i < to_check.size(); i++) |
| 141 AddTargetToFileMap(to_check[i], &files_to_check); |
| 142 RunCheckOverFiles(files_to_check); |
| 143 } |
134 | 144 |
135 if (file_map_.empty()) | 145 if (errors_.empty()) |
136 return true; | 146 return true; |
| 147 *errors = errors_; |
| 148 return false; |
| 149 } |
| 150 |
| 151 void HeaderChecker::RunCheckOverFiles(const FileMap& files) { |
| 152 if (files.empty()) |
| 153 return; |
137 | 154 |
138 scoped_refptr<base::SequencedWorkerPool> pool( | 155 scoped_refptr<base::SequencedWorkerPool> pool( |
139 new base::SequencedWorkerPool(16, "HeaderChecker")); | 156 new base::SequencedWorkerPool(16, "HeaderChecker")); |
140 for (FileMap::const_iterator file_i = file_map_.begin(); | 157 for (FileMap::const_iterator file_i = files.begin(); |
141 file_i != file_map_.end(); ++file_i) { | 158 file_i != files.end(); ++file_i) { |
142 const TargetVector& vect = file_i->second; | 159 const TargetVector& vect = file_i->second; |
143 | 160 |
144 // Only check C-like source files (RC files also have includes). | 161 // Only check C-like source files (RC files also have includes). |
145 SourceFileType type = GetSourceFileType(file_i->first); | 162 SourceFileType type = GetSourceFileType(file_i->first); |
146 if (type != SOURCE_CC && type != SOURCE_H && type != SOURCE_C && | 163 if (type != SOURCE_CC && type != SOURCE_H && type != SOURCE_C && |
147 type != SOURCE_M && type != SOURCE_MM && type != SOURCE_RC) | 164 type != SOURCE_M && type != SOURCE_MM && type != SOURCE_RC) |
148 continue; | 165 continue; |
149 | 166 |
150 for (size_t vect_i = 0; vect_i < vect.size(); ++vect_i) { | 167 for (size_t vect_i = 0; vect_i < vect.size(); ++vect_i) { |
151 pool->PostWorkerTaskWithShutdownBehavior( | 168 pool->PostWorkerTaskWithShutdownBehavior( |
152 FROM_HERE, | 169 FROM_HERE, |
153 base::Bind(&HeaderChecker::DoWork, this, | 170 base::Bind(&HeaderChecker::DoWork, this, |
154 vect[vect_i].target, file_i->first), | 171 vect[vect_i].target, file_i->first), |
155 base::SequencedWorkerPool::BLOCK_SHUTDOWN); | 172 base::SequencedWorkerPool::BLOCK_SHUTDOWN); |
156 } | 173 } |
157 } | 174 } |
158 | 175 |
159 // After this call we're single-threaded again. | 176 // After this call we're single-threaded again. |
160 pool->Shutdown(); | 177 pool->Shutdown(); |
161 | |
162 if (errors_.empty()) | |
163 return true; | |
164 *errors = errors_; | |
165 return false; | |
166 } | 178 } |
167 | 179 |
168 void HeaderChecker::DoWork(const Target* target, const SourceFile& file) { | 180 void HeaderChecker::DoWork(const Target* target, const SourceFile& file) { |
169 Err err; | 181 Err err; |
170 if (!CheckFile(target, file, &err)) { | 182 if (!CheckFile(target, file, &err)) { |
171 base::AutoLock lock(lock_); | 183 base::AutoLock lock(lock_); |
172 errors_.push_back(err); | 184 errors_.push_back(err); |
173 } | 185 } |
174 } | 186 } |
175 | 187 |
176 void HeaderChecker::AddTargetToFileMap(const Target* target) { | 188 // static |
| 189 void HeaderChecker::AddTargetToFileMap(const Target* target, FileMap* dest) { |
177 // Files in the sources have this public bit by default. | 190 // Files in the sources have this public bit by default. |
178 bool default_public = target->all_headers_public(); | 191 bool default_public = target->all_headers_public(); |
179 | 192 |
180 // First collect the normal files, they get the default visibility. | 193 // First collect the normal files, they get the default visibility. |
181 std::map<SourceFile, bool> files_to_public; | 194 std::map<SourceFile, bool> files_to_public; |
182 const Target::FileList& sources = target->sources(); | 195 const Target::FileList& sources = target->sources(); |
183 for (size_t i = 0; i < sources.size(); i++) | 196 for (size_t i = 0; i < sources.size(); i++) |
184 files_to_public[sources[i]] = default_public; | 197 files_to_public[sources[i]] = default_public; |
185 | 198 |
186 // Add in the public files, forcing them to public. This may overwrite some | 199 // Add in the public files, forcing them to public. This may overwrite some |
187 // entries, and it may add new ones. | 200 // entries, and it may add new ones. |
188 const Target::FileList& public_list = target->public_headers(); | 201 const Target::FileList& public_list = target->public_headers(); |
189 if (default_public) | 202 if (default_public) |
190 DCHECK(public_list.empty()); // List only used when default is not public. | 203 DCHECK(public_list.empty()); // List only used when default is not public. |
191 for (size_t i = 0; i < public_list.size(); i++) | 204 for (size_t i = 0; i < public_list.size(); i++) |
192 files_to_public[public_list[i]] = true; | 205 files_to_public[public_list[i]] = true; |
193 | 206 |
194 // Add the merged list to the master list of all files. | 207 // Add the merged list to the master list of all files. |
195 for (std::map<SourceFile, bool>::const_iterator i = files_to_public.begin(); | 208 for (std::map<SourceFile, bool>::const_iterator i = files_to_public.begin(); |
196 i != files_to_public.end(); ++i) | 209 i != files_to_public.end(); ++i) |
197 file_map_[i->first].push_back(TargetInfo(target, i->second)); | 210 (*dest)[i->first].push_back(TargetInfo(target, i->second)); |
198 } | 211 } |
199 | 212 |
200 bool HeaderChecker::IsFileInOuputDir(const SourceFile& file) const { | 213 bool HeaderChecker::IsFileInOuputDir(const SourceFile& file) const { |
201 const std::string& build_dir = build_settings_->build_dir().value(); | 214 const std::string& build_dir = build_settings_->build_dir().value(); |
202 return file.value().compare(0, build_dir.size(), build_dir) == 0; | 215 return file.value().compare(0, build_dir.size(), build_dir) == 0; |
203 } | 216 } |
204 | 217 |
205 // This current assumes all include paths are relative to the source root | 218 // This current assumes all include paths are relative to the source root |
206 // which is generally the case for Chromium. | 219 // which is generally the case for Chromium. |
207 // | 220 // |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 chain[i]->forward_dependent_configs(); | 497 chain[i]->forward_dependent_configs(); |
485 if (std::find_if(forwarded.begin(), forwarded.end(), | 498 if (std::find_if(forwarded.begin(), forwarded.end(), |
486 LabelPtrPtrEquals<Target>(chain[i - 1])) == | 499 LabelPtrPtrEquals<Target>(chain[i - 1])) == |
487 forwarded.end()) | 500 forwarded.end()) |
488 return i; | 501 return i; |
489 } | 502 } |
490 | 503 |
491 CHECK(false) << "Unable to diagnose dependent config chain problem."; | 504 CHECK(false) << "Unable to diagnose dependent config chain problem."; |
492 return 0; | 505 return 0; |
493 } | 506 } |
OLD | NEW |