Index: tools/gn/scope.cc |
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc |
index 2bf9dd467da7903b5ff4a874915d5f1481429fea..dc22367eb573feeca85b7604a80eca35e99414b6 100644 |
--- a/tools/gn/scope.cc |
+++ b/tools/gn/scope.cc |
@@ -25,6 +25,15 @@ bool IsPrivateVar(const base::StringPiece& name) { |
} // namespace |
+// Defaults to all false, which are the things least likely to cause errors. |
+Scope::MergeOptions::MergeOptions() |
+ : clobber_existing(false), |
+ skip_private_vars(false), |
+ mark_dest_used(false) { |
+} |
+ |
+Scope::MergeOptions::~MergeOptions() { |
+} |
Scope::ProgrammaticProvider::~ProgrammaticProvider() { |
scope_->RemoveProvider(this); |
@@ -249,17 +258,23 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
Err* err) const { |
// Values. |
for (const auto& pair : values_) { |
- if (options.skip_private_vars && IsPrivateVar(pair.first)) |
+ const base::StringPiece& current_name = pair.first; |
+ if (options.skip_private_vars && IsPrivateVar(current_name)) |
continue; // Skip this private var. |
+ if (!options.excluded_values.empty() && |
+ options.excluded_values.find(current_name.as_string()) != |
+ options.excluded_values.end()) { |
+ continue; // Skip this excluded value. |
+ } |
const Value& new_value = pair.second.value; |
if (!options.clobber_existing) { |
- const Value* existing_value = dest->GetValue(pair.first); |
+ const Value* existing_value = dest->GetValue(current_name); |
if (existing_value && new_value != *existing_value) { |
// Value present in both the source and the dest. |
std::string desc_string(desc_for_err); |
*err = Err(node_for_err, "Value collision.", |
- "This " + desc_string + " contains \"" + pair.first.as_string() + |
+ "This " + desc_string + " contains \"" + current_name.as_string() + |
"\""); |
err->AppendSubErr(Err(pair.second.value, "defined here.", |
"Which would clobber the one in your current scope")); |
@@ -269,23 +284,30 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
return false; |
} |
} |
- dest->values_[pair.first] = pair.second; |
+ dest->values_[current_name] = pair.second; |
if (options.mark_dest_used) |
- dest->MarkUsed(pair.first); |
+ dest->MarkUsed(current_name); |
} |
// Target defaults are owning pointers. |
for (const auto& pair : target_defaults_) { |
+ const std::string& current_name = pair.first; |
+ if (!options.excluded_values.empty() && |
+ options.excluded_values.find(current_name) != |
+ options.excluded_values.end()) { |
+ continue; // Skip the excluded value. |
+ } |
+ |
if (!options.clobber_existing) { |
- if (dest->GetTargetDefaults(pair.first)) { |
+ if (dest->GetTargetDefaults(current_name)) { |
// TODO(brettw) it would be nice to know the origin of a |
// set_target_defaults so we can give locations for the colliding target |
// defaults. |
std::string desc_string(desc_for_err); |
*err = Err(node_for_err, "Target defaults collision.", |
"This " + desc_string + " contains target defaults for\n" |
- "\"" + pair.first + "\" which would clobber one for the\n" |
+ "\"" + current_name + "\" which would clobber one for the\n" |
"same target type in your current scope. It's unfortunate that I'm " |
"too stupid\nto tell you the location of where the target defaults " |
"were set. Usually\nthis happens in the BUILDCONFIG.gn file."); |
@@ -294,7 +316,7 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
} |
// Be careful to delete any pointer we're about to clobber. |
- Scope** dest_scope = &dest->target_defaults_[pair.first]; |
+ Scope** dest_scope = &dest->target_defaults_[current_name]; |
if (*dest_scope) |
delete *dest_scope; |
*dest_scope = new Scope(settings_); |
@@ -320,11 +342,17 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
// Templates. |
for (const auto& pair : templates_) { |
- if (options.skip_private_vars && IsPrivateVar(pair.first)) |
+ const std::string& current_name = pair.first; |
+ if (options.skip_private_vars && IsPrivateVar(current_name)) |
continue; // Skip this private template. |
+ if (!options.excluded_values.empty() && |
+ options.excluded_values.find(current_name) != |
+ options.excluded_values.end()) { |
+ continue; // Skip the excluded value. |
+ } |
if (!options.clobber_existing) { |
- const Template* existing_template = dest->GetTemplate(pair.first); |
+ const Template* existing_template = dest->GetTemplate(current_name); |
// Since templates are refcounted, we can check if it's the same one by |
// comparing pointers. |
if (existing_template && pair.second.get() != existing_template) { |
@@ -333,7 +361,7 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
std::string desc_string(desc_for_err); |
*err = Err(node_for_err, "Template collision.", |
"This " + desc_string + " contains a template \"" + |
- pair.first + "\""); |
+ current_name + "\""); |
err->AppendSubErr(Err(pair.second->GetDefinitionRange(), |
"defined here.", |
"Which would clobber the one in your current scope")); |
@@ -346,7 +374,7 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
} |
// Be careful to delete any pointer we're about to clobber. |
- dest->templates_[pair.first] = pair.second; |
+ dest->templates_[current_name] = pair.second; |
} |
return true; |