OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/scope.h" | 5 #include "tools/gn/scope.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "tools/gn/parse_tree.h" | 9 #include "tools/gn/parse_tree.h" |
10 #include "tools/gn/template.h" | 10 #include "tools/gn/template.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // Target defaults are owning pointers. | 291 // Target defaults are owning pointers. |
292 for (const auto& pair : target_defaults_) { | 292 for (const auto& pair : target_defaults_) { |
293 const std::string& current_name = pair.first; | 293 const std::string& current_name = pair.first; |
294 if (!options.excluded_values.empty() && | 294 if (!options.excluded_values.empty() && |
295 options.excluded_values.find(current_name) != | 295 options.excluded_values.find(current_name) != |
296 options.excluded_values.end()) { | 296 options.excluded_values.end()) { |
297 continue; // Skip the excluded value. | 297 continue; // Skip the excluded value. |
298 } | 298 } |
299 | 299 |
300 if (!options.clobber_existing) { | 300 if (!options.clobber_existing) { |
301 if (dest->GetTargetDefaults(current_name)) { | 301 const Scope* dest_defaults = dest->GetTargetDefaults(current_name); |
302 // TODO(brettw) it would be nice to know the origin of a | 302 if (dest_defaults) { |
303 // set_target_defaults so we can give locations for the colliding target | 303 if (RecordMapValuesEqual(pair.second->values_, |
304 // defaults. | 304 dest_defaults->values_)) { |
305 std::string desc_string(desc_for_err); | 305 // Values of the two defaults are equivalent, just ignore the |
306 *err = Err(node_for_err, "Target defaults collision.", | 306 // collision. |
307 "This " + desc_string + " contains target defaults for\n" | 307 continue; |
308 "\"" + current_name + "\" which would clobber one for the\n" | 308 } else { |
309 "same target type in your current scope. It's unfortunate that I'm " | 309 // TODO(brettw) it would be nice to know the origin of a |
310 "too stupid\nto tell you the location of where the target defaults " | 310 // set_target_defaults so we can give locations for the colliding |
311 "were set. Usually\nthis happens in the BUILDCONFIG.gn file."); | 311 // target defaults. |
312 return false; | 312 std::string desc_string(desc_for_err); |
| 313 *err = Err(node_for_err, "Target defaults collision.", |
| 314 "This " + desc_string + " contains target defaults for\n" |
| 315 "\"" + current_name + "\" which would clobber one for the\n" |
| 316 "same target type in your current scope. It's unfortunate that " |
| 317 "I'm too stupid\nto tell you the location of where the target " |
| 318 "defaults were set. Usually\nthis happens in the BUILDCONFIG.gn " |
| 319 "file or in a related .gni file.\n"); |
| 320 return false; |
| 321 } |
313 } | 322 } |
314 } | 323 } |
315 | 324 |
316 std::unique_ptr<Scope>& dest_scope = dest->target_defaults_[current_name]; | 325 std::unique_ptr<Scope>& dest_scope = dest->target_defaults_[current_name]; |
317 dest_scope = base::WrapUnique(new Scope(settings_)); | 326 dest_scope = base::WrapUnique(new Scope(settings_)); |
318 pair.second->NonRecursiveMergeTo(dest_scope.get(), options, node_for_err, | 327 pair.second->NonRecursiveMergeTo(dest_scope.get(), options, node_for_err, |
319 "<SHOULDN'T HAPPEN>", err); | 328 "<SHOULDN'T HAPPEN>", err); |
320 } | 329 } |
321 | 330 |
322 // Sources assignment filter. | 331 // Sources assignment filter. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 | 406 |
398 // Add in our variables and we're done. | 407 // Add in our variables and we're done. |
399 Err err; | 408 Err err; |
400 NonRecursiveMergeTo(result.get(), options, nullptr, "<SHOULDN'T HAPPEN>", | 409 NonRecursiveMergeTo(result.get(), options, nullptr, "<SHOULDN'T HAPPEN>", |
401 &err); | 410 &err); |
402 DCHECK(!err.has_error()); | 411 DCHECK(!err.has_error()); |
403 return result; | 412 return result; |
404 } | 413 } |
405 | 414 |
406 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { | 415 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { |
407 if (GetTargetDefaults(target_type)) | |
408 return nullptr; | |
409 | |
410 std::unique_ptr<Scope>& dest = target_defaults_[target_type]; | 416 std::unique_ptr<Scope>& dest = target_defaults_[target_type]; |
411 if (dest) { | |
412 NOTREACHED(); // Already set. | |
413 return dest.get(); | |
414 } | |
415 dest = base::WrapUnique(new Scope(settings_)); | 417 dest = base::WrapUnique(new Scope(settings_)); |
416 return dest.get(); | 418 return dest.get(); |
417 } | 419 } |
418 | 420 |
419 const Scope* Scope::GetTargetDefaults(const std::string& target_type) const { | 421 const Scope* Scope::GetTargetDefaults(const std::string& target_type) const { |
420 NamedScopeMap::const_iterator found = target_defaults_.find(target_type); | 422 NamedScopeMap::const_iterator found = target_defaults_.find(target_type); |
421 if (found != target_defaults_.end()) | 423 if (found != target_defaults_.end()) |
422 return found->second.get(); | 424 return found->second.get(); |
423 if (containing()) | 425 if (containing()) |
424 return containing()->GetTargetDefaults(target_type); | 426 return containing()->GetTargetDefaults(target_type); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 509 } |
508 | 510 |
509 void Scope::AddProvider(ProgrammaticProvider* p) { | 511 void Scope::AddProvider(ProgrammaticProvider* p) { |
510 programmatic_providers_.insert(p); | 512 programmatic_providers_.insert(p); |
511 } | 513 } |
512 | 514 |
513 void Scope::RemoveProvider(ProgrammaticProvider* p) { | 515 void Scope::RemoveProvider(ProgrammaticProvider* p) { |
514 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end()); | 516 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end()); |
515 programmatic_providers_.erase(p); | 517 programmatic_providers_.erase(p); |
516 } | 518 } |
| 519 |
| 520 // static |
| 521 bool Scope::RecordMapValuesEqual(const RecordMap& a, const RecordMap& b) { |
| 522 if (a.size() != b.size()) |
| 523 return false; |
| 524 for (const auto& pair : a) { |
| 525 const auto& found_b = b.find(pair.first); |
| 526 if (found_b == b.end()) |
| 527 return false; // Item in 'a' but not 'b'. |
| 528 if (pair.second.value != found_b->second.value) |
| 529 return false; // Values for variable in 'a' and 'b' are different. |
| 530 } |
| 531 return true; |
| 532 } |
OLD | NEW |