Index: tools/gn/scope.cc |
diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc |
index b2d8d66fb3aa21926eb0d0b9d692286c822a9ed5..88951fdf41c3138994443a01db923ff8fd50de9b 100644 |
--- a/tools/gn/scope.cc |
+++ b/tools/gn/scope.cc |
@@ -123,6 +123,12 @@ Value* Scope::SetValue(const base::StringPiece& ident, |
return &r.value; |
} |
+void Scope::DeleteValue(const base::StringPiece& ident) { |
+ RecordMap::iterator found = values_.find(ident); |
+ if (found != values_.end()) |
+ values_.erase(found); |
+} |
+ |
bool Scope::AddTemplate(const std::string& name, const Template* templ) { |
if (GetTemplate(name)) |
return false; |
@@ -194,15 +200,25 @@ void Scope::GetCurrentScopeValues(KeyValueMap* output) const { |
(*output)[i->first] = i->second.value; |
} |
+void Scope::GetCurrentScopeVariables( |
+ std::vector<base::StringPiece>* output) const { |
+ output->reserve(values_.size()); |
+ for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) |
+ output->push_back(i->first); |
+} |
+ |
bool Scope::NonRecursiveMergeTo(Scope* dest, |
- bool clobber_existing, |
+ const MergeOptions& options, |
const ParseNode* node_for_err, |
const char* desc_for_err, |
Err* err) const { |
// Values. |
for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) { |
+ if (!options.copy_private_vars && IsPrivateVar(i->first)) |
+ continue; // Skip this private var. |
+ |
const Value& new_value = i->second.value; |
- if (!clobber_existing) { |
+ if (!options.clobber_existing) { |
const Value* existing_value = dest->GetValue(i->first); |
if (existing_value && new_value != *existing_value) { |
// Value present in both the source and the dest. |
@@ -219,12 +235,15 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
} |
} |
dest->values_[i->first] = i->second; |
+ |
+ if (options.mark_used) |
+ dest->MarkUsed(i->first); |
} |
// Target defaults are owning pointers. |
for (NamedScopeMap::const_iterator i = target_defaults_.begin(); |
i != target_defaults_.end(); ++i) { |
- if (!clobber_existing) { |
+ if (!options.clobber_existing) { |
if (dest->GetTargetDefaults(i->first)) { |
// TODO(brettw) it would be nice to know the origin of a |
// set_target_defaults so we can give locations for the colliding target |
@@ -245,13 +264,13 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
if (*dest_scope) |
delete *dest_scope; |
*dest_scope = new Scope(settings_); |
- i->second->NonRecursiveMergeTo(*dest_scope, clobber_existing, node_for_err, |
+ i->second->NonRecursiveMergeTo(*dest_scope, options, node_for_err, |
"<SHOULDN'T HAPPEN>", err); |
} |
// Sources assignment filter. |
if (sources_assignment_filter_) { |
- if (!clobber_existing) { |
+ if (!options.clobber_existing) { |
if (dest->GetSourcesAssignmentFilter()) { |
// Sources assignment filter present in both the source and the dest. |
std::string desc_string(desc_for_err); |
@@ -268,7 +287,10 @@ bool Scope::NonRecursiveMergeTo(Scope* dest, |
// Templates. |
for (TemplateMap::const_iterator i = templates_.begin(); |
i != templates_.end(); ++i) { |
- if (!clobber_existing) { |
+ if (!options.copy_private_vars && IsPrivateVar(i->first)) |
+ continue; // Skip this private template. |
+ |
+ if (!options.clobber_existing) { |
const Template* existing_template = dest->GetTemplate(i->first); |
if (existing_template) { |
// Rule present in both the source and the dest. |
@@ -308,9 +330,14 @@ scoped_ptr<Scope> Scope::MakeClosure() const { |
result.reset(new Scope(settings_)); |
} |
+ // Want to clobber since we've flattened some nested scopes, and our parent |
+ // scope may have a duplicate value set. |
+ MergeOptions options; |
+ options.clobber_existing = true; |
+ |
// Add in our variables and we're done. |
Err err; |
- NonRecursiveMergeTo(result.get(), true, NULL, "<SHOULDN'T HAPPEN>", &err); |
+ NonRecursiveMergeTo(result.get(), options, NULL, "<SHOULDN'T HAPPEN>", &err); |
DCHECK(!err.has_error()); |
return result.Pass(); |
} |
@@ -418,6 +445,11 @@ void* Scope::GetProperty(const void* key, const Scope** found_on_scope) const { |
return NULL; |
} |
+// static |
+bool Scope::IsPrivateVar(const base::StringPiece& name) { |
+ return name.empty() || name[0] == '_'; |
+} |
+ |
void Scope::AddProvider(ProgrammaticProvider* p) { |
programmatic_providers_.insert(p); |
} |