| Index: tools/gn/scope.cc
|
| diff --git a/tools/gn/scope.cc b/tools/gn/scope.cc
|
| index ebaf0eff66bf648fca25ae56b929f8a0055a0514..4e049ebbc545ad997de936ffd37ffdaca7197967 100644
|
| --- a/tools/gn/scope.cc
|
| +++ b/tools/gn/scope.cc
|
| @@ -16,6 +16,13 @@ namespace {
|
| const unsigned kProcessingBuildConfigFlag = 1;
|
| const unsigned kProcessingImportFlag = 2;
|
|
|
| +// Returns true if this variable name should be considered private. Private
|
| +// values start with an underscore, and are not imported from "gni" files
|
| +// when processing an import.
|
| +bool IsPrivateVar(const base::StringPiece& name) {
|
| + return name.empty() || name[0] == '_';
|
| +}
|
| +
|
| } // namespace
|
|
|
| Scope::Scope(const Settings* settings)
|
| @@ -129,6 +136,21 @@ void Scope::RemoveIdentifier(const base::StringPiece& ident) {
|
| values_.erase(found);
|
| }
|
|
|
| +void Scope::RemovePrivateIdentifiers() {
|
| + // Do it in two phases to avoid mutating while iterating. Our hash map is
|
| + // currently backed by several different vendor-specific implementations and
|
| + // I'm not sure if all of them support mutating while iterating. Since this
|
| + // is not perf-critical, do the safe thing.
|
| + std::vector<base::StringPiece> to_remove;
|
| + for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) {
|
| + if (IsPrivateVar(i->first))
|
| + to_remove.push_back(i->first);
|
| + }
|
| +
|
| + for (size_t i = 0; i < to_remove.size(); i++)
|
| + values_.erase(to_remove[i]);
|
| +}
|
| +
|
| bool Scope::AddTemplate(const std::string& name, const Template* templ) {
|
| if (GetTemplate(name))
|
| return false;
|
| @@ -201,14 +223,17 @@ void Scope::GetCurrentScopeValues(KeyValueMap* output) const {
|
| }
|
|
|
| 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.skip_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.
|
| @@ -225,12 +250,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
|
| @@ -251,13 +279,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);
|
| @@ -274,7 +302,10 @@ bool Scope::NonRecursiveMergeTo(Scope* dest,
|
| // Templates.
|
| for (TemplateMap::const_iterator i = templates_.begin();
|
| i != templates_.end(); ++i) {
|
| - if (!clobber_existing) {
|
| + if (options.skip_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.
|
| @@ -314,9 +345,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();
|
| }
|
|
|