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