| 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 |