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