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/source_file.h" |
10 #include "tools/gn/template.h" | 11 #include "tools/gn/template.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 // FLags set in the mode_flags_ of a scope. If a bit is set, it applies | 15 // FLags set in the mode_flags_ of a scope. If a bit is set, it applies |
15 // recursively to all dependent scopes. | 16 // recursively to all dependent scopes. |
16 const unsigned kProcessingBuildConfigFlag = 1; | 17 const unsigned kProcessingBuildConfigFlag = 1; |
17 const unsigned kProcessingImportFlag = 2; | 18 const unsigned kProcessingImportFlag = 2; |
18 | 19 |
19 // Returns true if this variable name should be considered private. Private | 20 // Returns true if this variable name should be considered private. Private |
(...skipping 12 matching lines...) Expand all Loading... |
32 mark_dest_used(false) { | 33 mark_dest_used(false) { |
33 } | 34 } |
34 | 35 |
35 Scope::MergeOptions::~MergeOptions() { | 36 Scope::MergeOptions::~MergeOptions() { |
36 } | 37 } |
37 | 38 |
38 Scope::ProgrammaticProvider::~ProgrammaticProvider() { | 39 Scope::ProgrammaticProvider::~ProgrammaticProvider() { |
39 scope_->RemoveProvider(this); | 40 scope_->RemoveProvider(this); |
40 } | 41 } |
41 | 42 |
42 Scope::Scope(const Settings* settings) | 43 Scope::Scope(const Settings* settings, |
| 44 const std::set<uint32_t>& source_files_hashes) |
43 : const_containing_(nullptr), | 45 : const_containing_(nullptr), |
44 mutable_containing_(nullptr), | 46 mutable_containing_(nullptr), |
45 settings_(settings), | 47 settings_(settings), |
46 mode_flags_(0), | 48 mode_flags_(0), |
47 item_collector_(nullptr) { | 49 item_collector_(nullptr), |
48 } | 50 source_files_hashes_(source_files_hashes) {} |
49 | 51 |
50 Scope::Scope(Scope* parent) | 52 Scope::Scope(Scope* parent) |
51 : const_containing_(nullptr), | 53 : const_containing_(nullptr), |
52 mutable_containing_(parent), | 54 mutable_containing_(parent), |
53 settings_(parent->settings()), | 55 settings_(parent->settings()), |
54 mode_flags_(0), | 56 mode_flags_(0), |
55 item_collector_(nullptr) { | 57 item_collector_(nullptr), |
56 } | 58 source_files_hashes_(parent->source_files_hashes_) {} |
57 | 59 |
58 Scope::Scope(const Scope* parent) | 60 Scope::Scope(const Scope* parent) |
59 : const_containing_(parent), | 61 : const_containing_(parent), |
60 mutable_containing_(nullptr), | 62 mutable_containing_(nullptr), |
61 settings_(parent->settings()), | 63 settings_(parent->settings()), |
62 mode_flags_(0), | 64 mode_flags_(0), |
63 item_collector_(nullptr) { | 65 item_collector_(nullptr), |
64 } | 66 source_files_hashes_(parent->source_files_hashes_) {} |
65 | 67 |
66 Scope::~Scope() { | 68 Scope::~Scope() { |
67 } | 69 } |
68 | 70 |
69 void Scope::DetachFromContaining() { | 71 void Scope::DetachFromContaining() { |
70 const_containing_ = nullptr; | 72 const_containing_ = nullptr; |
71 mutable_containing_ = nullptr; | 73 mutable_containing_ = nullptr; |
72 } | 74 } |
73 | 75 |
74 bool Scope::HasValues(SearchNested search_nested) const { | 76 bool Scope::HasValues(SearchNested search_nested) const { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 "same target type in your current scope. It's unfortunate that " | 334 "same target type in your current scope. It's unfortunate that " |
333 "I'm too stupid\nto tell you the location of where the target " | 335 "I'm too stupid\nto tell you the location of where the target " |
334 "defaults were set. Usually\nthis happens in the BUILDCONFIG.gn " | 336 "defaults were set. Usually\nthis happens in the BUILDCONFIG.gn " |
335 "file or in a related .gni file.\n"); | 337 "file or in a related .gni file.\n"); |
336 return false; | 338 return false; |
337 } | 339 } |
338 } | 340 } |
339 } | 341 } |
340 | 342 |
341 std::unique_ptr<Scope>& dest_scope = dest->target_defaults_[current_name]; | 343 std::unique_ptr<Scope>& dest_scope = dest->target_defaults_[current_name]; |
342 dest_scope = base::MakeUnique<Scope>(settings_); | 344 dest_scope = base::MakeUnique<Scope>(settings_, source_files_hashes_); |
343 pair.second->NonRecursiveMergeTo(dest_scope.get(), options, node_for_err, | 345 pair.second->NonRecursiveMergeTo(dest_scope.get(), options, node_for_err, |
344 "<SHOULDN'T HAPPEN>", err); | 346 "<SHOULDN'T HAPPEN>", err); |
345 } | 347 } |
346 | 348 |
347 // Sources assignment filter. | 349 // Sources assignment filter. |
348 if (sources_assignment_filter_) { | 350 if (sources_assignment_filter_) { |
349 if (!options.clobber_existing) { | 351 if (!options.clobber_existing) { |
350 if (dest->GetSourcesAssignmentFilter()) { | 352 if (dest->GetSourcesAssignmentFilter()) { |
351 // Sources assignment filter present in both the source and the dest. | 353 // Sources assignment filter present in both the source and the dest. |
352 std::string desc_string(desc_for_err); | 354 std::string desc_string(desc_for_err); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 "Executing " + desc_string + " should not conflict with anything " | 392 "Executing " + desc_string + " should not conflict with anything " |
391 "in the current\nscope.")); | 393 "in the current\nscope.")); |
392 return false; | 394 return false; |
393 } | 395 } |
394 } | 396 } |
395 | 397 |
396 // Be careful to delete any pointer we're about to clobber. | 398 // Be careful to delete any pointer we're about to clobber. |
397 dest->templates_[current_name] = pair.second; | 399 dest->templates_[current_name] = pair.second; |
398 } | 400 } |
399 | 401 |
| 402 // Source files. |
| 403 dest->source_files_hashes_.insert(source_files_hashes_.begin(), |
| 404 source_files_hashes_.end()); |
| 405 |
400 return true; | 406 return true; |
401 } | 407 } |
402 | 408 |
403 std::unique_ptr<Scope> Scope::MakeClosure() const { | 409 std::unique_ptr<Scope> Scope::MakeClosure() const { |
404 std::unique_ptr<Scope> result; | 410 std::unique_ptr<Scope> result; |
405 if (const_containing_) { | 411 if (const_containing_) { |
406 // We reached the top of the mutable scope stack. The result scope just | 412 // We reached the top of the mutable scope stack. The result scope just |
407 // references the const scope (which will never change). | 413 // references the const scope (which will never change). |
408 result.reset(new Scope(const_containing_)); | 414 result.reset(new Scope(const_containing_)); |
409 } else if (mutable_containing_) { | 415 } else if (mutable_containing_) { |
410 // There are more nested mutable scopes. Recursively go up the stack to | 416 // There are more nested mutable scopes. Recursively go up the stack to |
411 // get the closure. | 417 // get the closure. |
412 result = mutable_containing_->MakeClosure(); | 418 result = mutable_containing_->MakeClosure(); |
413 } else { | 419 } else { |
414 // This is a standalone scope, just copy it. | 420 // This is a standalone scope, just copy it. |
415 result.reset(new Scope(settings_)); | 421 result.reset(new Scope(settings_, source_files_hashes_)); |
416 } | 422 } |
417 | 423 |
418 // Want to clobber since we've flattened some nested scopes, and our parent | 424 // Want to clobber since we've flattened some nested scopes, and our parent |
419 // scope may have a duplicate value set. | 425 // scope may have a duplicate value set. |
420 MergeOptions options; | 426 MergeOptions options; |
421 options.clobber_existing = true; | 427 options.clobber_existing = true; |
422 | 428 |
423 // Add in our variables and we're done. | 429 // Add in our variables and we're done. |
424 Err err; | 430 Err err; |
425 NonRecursiveMergeTo(result.get(), options, nullptr, "<SHOULDN'T HAPPEN>", | 431 NonRecursiveMergeTo(result.get(), options, nullptr, "<SHOULDN'T HAPPEN>", |
426 &err); | 432 &err); |
427 DCHECK(!err.has_error()); | 433 DCHECK(!err.has_error()); |
428 return result; | 434 return result; |
429 } | 435 } |
430 | 436 |
431 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { | 437 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { |
432 std::unique_ptr<Scope>& dest = target_defaults_[target_type]; | 438 std::unique_ptr<Scope>& dest = target_defaults_[target_type]; |
433 dest = base::MakeUnique<Scope>(settings_); | 439 dest = base::MakeUnique<Scope>(settings_, source_files_hashes_); |
434 return dest.get(); | 440 return dest.get(); |
435 } | 441 } |
436 | 442 |
437 const Scope* Scope::GetTargetDefaults(const std::string& target_type) const { | 443 const Scope* Scope::GetTargetDefaults(const std::string& target_type) const { |
438 NamedScopeMap::const_iterator found = target_defaults_.find(target_type); | 444 NamedScopeMap::const_iterator found = target_defaults_.find(target_type); |
439 if (found != target_defaults_.end()) | 445 if (found != target_defaults_.end()) |
440 return found->second.get(); | 446 return found->second.get(); |
441 if (containing()) | 447 if (containing()) |
442 return containing()->GetTargetDefaults(target_type); | 448 return containing()->GetTargetDefaults(target_type); |
443 return nullptr; | 449 return nullptr; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 } | 494 } |
489 | 495 |
490 const SourceDir& Scope::GetSourceDir() const { | 496 const SourceDir& Scope::GetSourceDir() const { |
491 if (!source_dir_.is_null()) | 497 if (!source_dir_.is_null()) |
492 return source_dir_; | 498 return source_dir_; |
493 if (containing()) | 499 if (containing()) |
494 return containing()->GetSourceDir(); | 500 return containing()->GetSourceDir(); |
495 return source_dir_; | 501 return source_dir_; |
496 } | 502 } |
497 | 503 |
| 504 void Scope::AddSourceFile(const SourceFile& source_file) { |
| 505 source_files_hashes_.insert(base::Hash(source_file.value())); |
| 506 } |
| 507 |
498 Scope::ItemVector* Scope::GetItemCollector() { | 508 Scope::ItemVector* Scope::GetItemCollector() { |
499 if (item_collector_) | 509 if (item_collector_) |
500 return item_collector_; | 510 return item_collector_; |
501 if (mutable_containing()) | 511 if (mutable_containing()) |
502 return mutable_containing()->GetItemCollector(); | 512 return mutable_containing()->GetItemCollector(); |
503 return nullptr; | 513 return nullptr; |
504 } | 514 } |
505 | 515 |
506 void Scope::SetProperty(const void* key, void* value) { | 516 void Scope::SetProperty(const void* key, void* value) { |
507 if (!value) { | 517 if (!value) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 return false; | 549 return false; |
540 for (const auto& pair : a) { | 550 for (const auto& pair : a) { |
541 const auto& found_b = b.find(pair.first); | 551 const auto& found_b = b.find(pair.first); |
542 if (found_b == b.end()) | 552 if (found_b == b.end()) |
543 return false; // Item in 'a' but not 'b'. | 553 return false; // Item in 'a' but not 'b'. |
544 if (pair.second.value != found_b->second.value) | 554 if (pair.second.value != found_b->second.value) |
545 return false; // Values for variable in 'a' and 'b' are different. | 555 return false; // Values for variable in 'a' and 'b' are different. |
546 } | 556 } |
547 return true; | 557 return true; |
548 } | 558 } |
OLD | NEW |