Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: tools/gn/scope.cc

Issue 287693002: Support private values in GN. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix semicolon Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/scope.h ('k') | tools/gn/scope_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/scope.h" 5 #include "tools/gn/scope.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "tools/gn/parse_tree.h" 9 #include "tools/gn/parse_tree.h"
10 #include "tools/gn/template.h" 10 #include "tools/gn/template.h"
11 11
12 namespace { 12 namespace {
13 13
14 // FLags set in the mode_flags_ of a scope. If a bit is set, it applies 14 // FLags set in the mode_flags_ of a scope. If a bit is set, it applies
15 // recursively to all dependent scopes. 15 // recursively to all dependent scopes.
16 const unsigned kProcessingBuildConfigFlag = 1; 16 const unsigned kProcessingBuildConfigFlag = 1;
17 const unsigned kProcessingImportFlag = 2; 17 const unsigned kProcessingImportFlag = 2;
18 18
19 // Returns true if this variable name should be considered private. Private
20 // values start with an underscore, and are not imported from "gni" files
21 // when processing an import.
22 bool IsPrivateVar(const base::StringPiece& name) {
23 return name.empty() || name[0] == '_';
24 }
25
19 } // namespace 26 } // namespace
20 27
21 Scope::Scope(const Settings* settings) 28 Scope::Scope(const Settings* settings)
22 : const_containing_(NULL), 29 : const_containing_(NULL),
23 mutable_containing_(NULL), 30 mutable_containing_(NULL),
24 settings_(settings), 31 settings_(settings),
25 mode_flags_(0), 32 mode_flags_(0),
26 item_collector_(NULL) { 33 item_collector_(NULL) {
27 } 34 }
28 35
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 r.value.set_origin(set_node); 129 r.value.set_origin(set_node);
123 return &r.value; 130 return &r.value;
124 } 131 }
125 132
126 void Scope::RemoveIdentifier(const base::StringPiece& ident) { 133 void Scope::RemoveIdentifier(const base::StringPiece& ident) {
127 RecordMap::iterator found = values_.find(ident); 134 RecordMap::iterator found = values_.find(ident);
128 if (found != values_.end()) 135 if (found != values_.end())
129 values_.erase(found); 136 values_.erase(found);
130 } 137 }
131 138
139 void Scope::RemovePrivateIdentifiers() {
140 // Do it in two phases to avoid mutating while iterating. Our hash map is
141 // currently backed by several different vendor-specific implementations and
142 // I'm not sure if all of them support mutating while iterating. Since this
143 // is not perf-critical, do the safe thing.
144 std::vector<base::StringPiece> to_remove;
145 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) {
146 if (IsPrivateVar(i->first))
147 to_remove.push_back(i->first);
148 }
149
150 for (size_t i = 0; i < to_remove.size(); i++)
151 values_.erase(to_remove[i]);
152 }
153
132 bool Scope::AddTemplate(const std::string& name, const Template* templ) { 154 bool Scope::AddTemplate(const std::string& name, const Template* templ) {
133 if (GetTemplate(name)) 155 if (GetTemplate(name))
134 return false; 156 return false;
135 templates_[name] = templ; 157 templates_[name] = templ;
136 return true; 158 return true;
137 } 159 }
138 160
139 const Template* Scope::GetTemplate(const std::string& name) const { 161 const Template* Scope::GetTemplate(const std::string& name) const {
140 TemplateMap::const_iterator found = templates_.find(name); 162 TemplateMap::const_iterator found = templates_.find(name);
141 if (found != templates_.end()) 163 if (found != templates_.end())
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 216 }
195 return true; 217 return true;
196 } 218 }
197 219
198 void Scope::GetCurrentScopeValues(KeyValueMap* output) const { 220 void Scope::GetCurrentScopeValues(KeyValueMap* output) const {
199 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) 221 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i)
200 (*output)[i->first] = i->second.value; 222 (*output)[i->first] = i->second.value;
201 } 223 }
202 224
203 bool Scope::NonRecursiveMergeTo(Scope* dest, 225 bool Scope::NonRecursiveMergeTo(Scope* dest,
204 bool clobber_existing, 226 const MergeOptions& options,
205 const ParseNode* node_for_err, 227 const ParseNode* node_for_err,
206 const char* desc_for_err, 228 const char* desc_for_err,
207 Err* err) const { 229 Err* err) const {
208 // Values. 230 // Values.
209 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) { 231 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) {
232 if (options.skip_private_vars && IsPrivateVar(i->first))
233 continue; // Skip this private var.
234
210 const Value& new_value = i->second.value; 235 const Value& new_value = i->second.value;
211 if (!clobber_existing) { 236 if (!options.clobber_existing) {
212 const Value* existing_value = dest->GetValue(i->first); 237 const Value* existing_value = dest->GetValue(i->first);
213 if (existing_value && new_value != *existing_value) { 238 if (existing_value && new_value != *existing_value) {
214 // Value present in both the source and the dest. 239 // Value present in both the source and the dest.
215 std::string desc_string(desc_for_err); 240 std::string desc_string(desc_for_err);
216 *err = Err(node_for_err, "Value collision.", 241 *err = Err(node_for_err, "Value collision.",
217 "This " + desc_string + " contains \"" + i->first.as_string() + 242 "This " + desc_string + " contains \"" + i->first.as_string() +
218 "\""); 243 "\"");
219 err->AppendSubErr(Err(i->second.value, "defined here.", 244 err->AppendSubErr(Err(i->second.value, "defined here.",
220 "Which would clobber the one in your current scope")); 245 "Which would clobber the one in your current scope"));
221 err->AppendSubErr(Err(*existing_value, "defined here.", 246 err->AppendSubErr(Err(*existing_value, "defined here.",
222 "Executing " + desc_string + " should not conflict with anything " 247 "Executing " + desc_string + " should not conflict with anything "
223 "in the current\nscope unless the values are identical.")); 248 "in the current\nscope unless the values are identical."));
224 return false; 249 return false;
225 } 250 }
226 } 251 }
227 dest->values_[i->first] = i->second; 252 dest->values_[i->first] = i->second;
253
254 if (options.mark_used)
255 dest->MarkUsed(i->first);
228 } 256 }
229 257
230 // Target defaults are owning pointers. 258 // Target defaults are owning pointers.
231 for (NamedScopeMap::const_iterator i = target_defaults_.begin(); 259 for (NamedScopeMap::const_iterator i = target_defaults_.begin();
232 i != target_defaults_.end(); ++i) { 260 i != target_defaults_.end(); ++i) {
233 if (!clobber_existing) { 261 if (!options.clobber_existing) {
234 if (dest->GetTargetDefaults(i->first)) { 262 if (dest->GetTargetDefaults(i->first)) {
235 // TODO(brettw) it would be nice to know the origin of a 263 // TODO(brettw) it would be nice to know the origin of a
236 // set_target_defaults so we can give locations for the colliding target 264 // set_target_defaults so we can give locations for the colliding target
237 // defaults. 265 // defaults.
238 std::string desc_string(desc_for_err); 266 std::string desc_string(desc_for_err);
239 *err = Err(node_for_err, "Target defaults collision.", 267 *err = Err(node_for_err, "Target defaults collision.",
240 "This " + desc_string + " contains target defaults for\n" 268 "This " + desc_string + " contains target defaults for\n"
241 "\"" + i->first + "\" which would clobber one for the\n" 269 "\"" + i->first + "\" which would clobber one for the\n"
242 "same target type in your current scope. It's unfortunate that I'm " 270 "same target type in your current scope. It's unfortunate that I'm "
243 "too stupid\nto tell you the location of where the target defaults " 271 "too stupid\nto tell you the location of where the target defaults "
244 "were set. Usually\nthis happens in the BUILDCONFIG.gn file."); 272 "were set. Usually\nthis happens in the BUILDCONFIG.gn file.");
245 return false; 273 return false;
246 } 274 }
247 } 275 }
248 276
249 // Be careful to delete any pointer we're about to clobber. 277 // Be careful to delete any pointer we're about to clobber.
250 Scope** dest_scope = &dest->target_defaults_[i->first]; 278 Scope** dest_scope = &dest->target_defaults_[i->first];
251 if (*dest_scope) 279 if (*dest_scope)
252 delete *dest_scope; 280 delete *dest_scope;
253 *dest_scope = new Scope(settings_); 281 *dest_scope = new Scope(settings_);
254 i->second->NonRecursiveMergeTo(*dest_scope, clobber_existing, node_for_err, 282 i->second->NonRecursiveMergeTo(*dest_scope, options, node_for_err,
255 "<SHOULDN'T HAPPEN>", err); 283 "<SHOULDN'T HAPPEN>", err);
256 } 284 }
257 285
258 // Sources assignment filter. 286 // Sources assignment filter.
259 if (sources_assignment_filter_) { 287 if (sources_assignment_filter_) {
260 if (!clobber_existing) { 288 if (!options.clobber_existing) {
261 if (dest->GetSourcesAssignmentFilter()) { 289 if (dest->GetSourcesAssignmentFilter()) {
262 // Sources assignment filter present in both the source and the dest. 290 // Sources assignment filter present in both the source and the dest.
263 std::string desc_string(desc_for_err); 291 std::string desc_string(desc_for_err);
264 *err = Err(node_for_err, "Assignment filter collision.", 292 *err = Err(node_for_err, "Assignment filter collision.",
265 "The " + desc_string + " contains a sources_assignment_filter " 293 "The " + desc_string + " contains a sources_assignment_filter "
266 "which\nwould clobber the one in your current scope."); 294 "which\nwould clobber the one in your current scope.");
267 return false; 295 return false;
268 } 296 }
269 } 297 }
270 dest->sources_assignment_filter_.reset( 298 dest->sources_assignment_filter_.reset(
271 new PatternList(*sources_assignment_filter_)); 299 new PatternList(*sources_assignment_filter_));
272 } 300 }
273 301
274 // Templates. 302 // Templates.
275 for (TemplateMap::const_iterator i = templates_.begin(); 303 for (TemplateMap::const_iterator i = templates_.begin();
276 i != templates_.end(); ++i) { 304 i != templates_.end(); ++i) {
277 if (!clobber_existing) { 305 if (options.skip_private_vars && IsPrivateVar(i->first))
306 continue; // Skip this private template.
307
308 if (!options.clobber_existing) {
278 const Template* existing_template = dest->GetTemplate(i->first); 309 const Template* existing_template = dest->GetTemplate(i->first);
279 if (existing_template) { 310 if (existing_template) {
280 // Rule present in both the source and the dest. 311 // Rule present in both the source and the dest.
281 std::string desc_string(desc_for_err); 312 std::string desc_string(desc_for_err);
282 *err = Err(node_for_err, "Template collision.", 313 *err = Err(node_for_err, "Template collision.",
283 "This " + desc_string + " contains a template \"" + 314 "This " + desc_string + " contains a template \"" +
284 i->first + "\""); 315 i->first + "\"");
285 err->AppendSubErr(Err(i->second->GetDefinitionRange(), "defined here.", 316 err->AppendSubErr(Err(i->second->GetDefinitionRange(), "defined here.",
286 "Which would clobber the one in your current scope")); 317 "Which would clobber the one in your current scope"));
287 err->AppendSubErr(Err(existing_template->GetDefinitionRange(), 318 err->AppendSubErr(Err(existing_template->GetDefinitionRange(),
(...skipping 19 matching lines...) Expand all
307 result.reset(new Scope(const_containing_)); 338 result.reset(new Scope(const_containing_));
308 } else if (mutable_containing_) { 339 } else if (mutable_containing_) {
309 // There are more nested mutable scopes. Recursively go up the stack to 340 // There are more nested mutable scopes. Recursively go up the stack to
310 // get the closure. 341 // get the closure.
311 result = mutable_containing_->MakeClosure(); 342 result = mutable_containing_->MakeClosure();
312 } else { 343 } else {
313 // This is a standalone scope, just copy it. 344 // This is a standalone scope, just copy it.
314 result.reset(new Scope(settings_)); 345 result.reset(new Scope(settings_));
315 } 346 }
316 347
348 // Want to clobber since we've flattened some nested scopes, and our parent
349 // scope may have a duplicate value set.
350 MergeOptions options;
351 options.clobber_existing = true;
352
317 // Add in our variables and we're done. 353 // Add in our variables and we're done.
318 Err err; 354 Err err;
319 NonRecursiveMergeTo(result.get(), true, NULL, "<SHOULDN'T HAPPEN>", &err); 355 NonRecursiveMergeTo(result.get(), options, NULL, "<SHOULDN'T HAPPEN>", &err);
320 DCHECK(!err.has_error()); 356 DCHECK(!err.has_error());
321 return result.Pass(); 357 return result.Pass();
322 } 358 }
323 359
324 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { 360 Scope* Scope::MakeTargetDefaults(const std::string& target_type) {
325 if (GetTargetDefaults(target_type)) 361 if (GetTargetDefaults(target_type))
326 return NULL; 362 return NULL;
327 363
328 Scope** dest = &target_defaults_[target_type]; 364 Scope** dest = &target_defaults_[target_type];
329 if (*dest) { 365 if (*dest) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 } 461 }
426 462
427 void Scope::AddProvider(ProgrammaticProvider* p) { 463 void Scope::AddProvider(ProgrammaticProvider* p) {
428 programmatic_providers_.insert(p); 464 programmatic_providers_.insert(p);
429 } 465 }
430 466
431 void Scope::RemoveProvider(ProgrammaticProvider* p) { 467 void Scope::RemoveProvider(ProgrammaticProvider* p) {
432 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end()); 468 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end());
433 programmatic_providers_.erase(p); 469 programmatic_providers_.erase(p);
434 } 470 }
OLDNEW
« no previous file with comments | « tools/gn/scope.h ('k') | tools/gn/scope_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698