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

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: docs 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
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"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 116
117 Value* Scope::SetValue(const base::StringPiece& ident, 117 Value* Scope::SetValue(const base::StringPiece& ident,
118 const Value& v, 118 const Value& v,
119 const ParseNode* set_node) { 119 const ParseNode* set_node) {
120 Record& r = values_[ident]; // Clears any existing value. 120 Record& r = values_[ident]; // Clears any existing value.
121 r.value = v; 121 r.value = v;
122 r.value.set_origin(set_node); 122 r.value.set_origin(set_node);
123 return &r.value; 123 return &r.value;
124 } 124 }
125 125
126 void Scope::DeleteValue(const base::StringPiece& ident) {
127 RecordMap::iterator found = values_.find(ident);
128 if (found != values_.end())
129 values_.erase(found);
130 }
131
126 bool Scope::AddTemplate(const std::string& name, const Template* templ) { 132 bool Scope::AddTemplate(const std::string& name, const Template* templ) {
127 if (GetTemplate(name)) 133 if (GetTemplate(name))
128 return false; 134 return false;
129 templates_[name] = templ; 135 templates_[name] = templ;
130 return true; 136 return true;
131 } 137 }
132 138
133 const Template* Scope::GetTemplate(const std::string& name) const { 139 const Template* Scope::GetTemplate(const std::string& name) const {
134 TemplateMap::const_iterator found = templates_.find(name); 140 TemplateMap::const_iterator found = templates_.find(name);
135 if (found != templates_.end()) 141 if (found != templates_.end())
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 193 }
188 } 194 }
189 return true; 195 return true;
190 } 196 }
191 197
192 void Scope::GetCurrentScopeValues(KeyValueMap* output) const { 198 void Scope::GetCurrentScopeValues(KeyValueMap* output) const {
193 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) 199 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i)
194 (*output)[i->first] = i->second.value; 200 (*output)[i->first] = i->second.value;
195 } 201 }
196 202
203 void Scope::GetCurrentScopeVariables(
204 std::vector<base::StringPiece>* output) const {
205 output->reserve(values_.size());
206 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i)
207 output->push_back(i->first);
208 }
209
197 bool Scope::NonRecursiveMergeTo(Scope* dest, 210 bool Scope::NonRecursiveMergeTo(Scope* dest,
198 bool clobber_existing, 211 const MergeOptions& options,
199 const ParseNode* node_for_err, 212 const ParseNode* node_for_err,
200 const char* desc_for_err, 213 const char* desc_for_err,
201 Err* err) const { 214 Err* err) const {
202 // Values. 215 // Values.
203 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) { 216 for (RecordMap::const_iterator i = values_.begin(); i != values_.end(); ++i) {
217 if (!options.copy_private_vars && IsPrivateVar(i->first))
218 continue; // Skip this private var.
219
204 const Value& new_value = i->second.value; 220 const Value& new_value = i->second.value;
205 if (!clobber_existing) { 221 if (!options.clobber_existing) {
206 const Value* existing_value = dest->GetValue(i->first); 222 const Value* existing_value = dest->GetValue(i->first);
207 if (existing_value && new_value != *existing_value) { 223 if (existing_value && new_value != *existing_value) {
208 // Value present in both the source and the dest. 224 // Value present in both the source and the dest.
209 std::string desc_string(desc_for_err); 225 std::string desc_string(desc_for_err);
210 *err = Err(node_for_err, "Value collision.", 226 *err = Err(node_for_err, "Value collision.",
211 "This " + desc_string + " contains \"" + i->first.as_string() + 227 "This " + desc_string + " contains \"" + i->first.as_string() +
212 "\""); 228 "\"");
213 err->AppendSubErr(Err(i->second.value, "defined here.", 229 err->AppendSubErr(Err(i->second.value, "defined here.",
214 "Which would clobber the one in your current scope")); 230 "Which would clobber the one in your current scope"));
215 err->AppendSubErr(Err(*existing_value, "defined here.", 231 err->AppendSubErr(Err(*existing_value, "defined here.",
216 "Executing " + desc_string + " should not conflict with anything " 232 "Executing " + desc_string + " should not conflict with anything "
217 "in the current\nscope unless the values are identical.")); 233 "in the current\nscope unless the values are identical."));
218 return false; 234 return false;
219 } 235 }
220 } 236 }
221 dest->values_[i->first] = i->second; 237 dest->values_[i->first] = i->second;
238
239 if (options.mark_used)
240 dest->MarkUsed(i->first);
222 } 241 }
223 242
224 // Target defaults are owning pointers. 243 // Target defaults are owning pointers.
225 for (NamedScopeMap::const_iterator i = target_defaults_.begin(); 244 for (NamedScopeMap::const_iterator i = target_defaults_.begin();
226 i != target_defaults_.end(); ++i) { 245 i != target_defaults_.end(); ++i) {
227 if (!clobber_existing) { 246 if (!options.clobber_existing) {
228 if (dest->GetTargetDefaults(i->first)) { 247 if (dest->GetTargetDefaults(i->first)) {
229 // TODO(brettw) it would be nice to know the origin of a 248 // TODO(brettw) it would be nice to know the origin of a
230 // set_target_defaults so we can give locations for the colliding target 249 // set_target_defaults so we can give locations for the colliding target
231 // defaults. 250 // defaults.
232 std::string desc_string(desc_for_err); 251 std::string desc_string(desc_for_err);
233 *err = Err(node_for_err, "Target defaults collision.", 252 *err = Err(node_for_err, "Target defaults collision.",
234 "This " + desc_string + " contains target defaults for\n" 253 "This " + desc_string + " contains target defaults for\n"
235 "\"" + i->first + "\" which would clobber one for the\n" 254 "\"" + i->first + "\" which would clobber one for the\n"
236 "same target type in your current scope. It's unfortunate that I'm " 255 "same target type in your current scope. It's unfortunate that I'm "
237 "too stupid\nto tell you the location of where the target defaults " 256 "too stupid\nto tell you the location of where the target defaults "
238 "were set. Usually\nthis happens in the BUILDCONFIG.gn file."); 257 "were set. Usually\nthis happens in the BUILDCONFIG.gn file.");
239 return false; 258 return false;
240 } 259 }
241 } 260 }
242 261
243 // Be careful to delete any pointer we're about to clobber. 262 // Be careful to delete any pointer we're about to clobber.
244 Scope** dest_scope = &dest->target_defaults_[i->first]; 263 Scope** dest_scope = &dest->target_defaults_[i->first];
245 if (*dest_scope) 264 if (*dest_scope)
246 delete *dest_scope; 265 delete *dest_scope;
247 *dest_scope = new Scope(settings_); 266 *dest_scope = new Scope(settings_);
248 i->second->NonRecursiveMergeTo(*dest_scope, clobber_existing, node_for_err, 267 i->second->NonRecursiveMergeTo(*dest_scope, options, node_for_err,
249 "<SHOULDN'T HAPPEN>", err); 268 "<SHOULDN'T HAPPEN>", err);
250 } 269 }
251 270
252 // Sources assignment filter. 271 // Sources assignment filter.
253 if (sources_assignment_filter_) { 272 if (sources_assignment_filter_) {
254 if (!clobber_existing) { 273 if (!options.clobber_existing) {
255 if (dest->GetSourcesAssignmentFilter()) { 274 if (dest->GetSourcesAssignmentFilter()) {
256 // Sources assignment filter present in both the source and the dest. 275 // Sources assignment filter present in both the source and the dest.
257 std::string desc_string(desc_for_err); 276 std::string desc_string(desc_for_err);
258 *err = Err(node_for_err, "Assignment filter collision.", 277 *err = Err(node_for_err, "Assignment filter collision.",
259 "The " + desc_string + " contains a sources_assignment_filter " 278 "The " + desc_string + " contains a sources_assignment_filter "
260 "which\nwould clobber the one in your current scope."); 279 "which\nwould clobber the one in your current scope.");
261 return false; 280 return false;
262 } 281 }
263 } 282 }
264 dest->sources_assignment_filter_.reset( 283 dest->sources_assignment_filter_.reset(
265 new PatternList(*sources_assignment_filter_)); 284 new PatternList(*sources_assignment_filter_));
266 } 285 }
267 286
268 // Templates. 287 // Templates.
269 for (TemplateMap::const_iterator i = templates_.begin(); 288 for (TemplateMap::const_iterator i = templates_.begin();
270 i != templates_.end(); ++i) { 289 i != templates_.end(); ++i) {
271 if (!clobber_existing) { 290 if (!options.copy_private_vars && IsPrivateVar(i->first))
291 continue; // Skip this private template.
292
293 if (!options.clobber_existing) {
272 const Template* existing_template = dest->GetTemplate(i->first); 294 const Template* existing_template = dest->GetTemplate(i->first);
273 if (existing_template) { 295 if (existing_template) {
274 // Rule present in both the source and the dest. 296 // Rule present in both the source and the dest.
275 std::string desc_string(desc_for_err); 297 std::string desc_string(desc_for_err);
276 *err = Err(node_for_err, "Template collision.", 298 *err = Err(node_for_err, "Template collision.",
277 "This " + desc_string + " contains a template \"" + 299 "This " + desc_string + " contains a template \"" +
278 i->first + "\""); 300 i->first + "\"");
279 err->AppendSubErr(Err(i->second->GetDefinitionRange(), "defined here.", 301 err->AppendSubErr(Err(i->second->GetDefinitionRange(), "defined here.",
280 "Which would clobber the one in your current scope")); 302 "Which would clobber the one in your current scope"));
281 err->AppendSubErr(Err(existing_template->GetDefinitionRange(), 303 err->AppendSubErr(Err(existing_template->GetDefinitionRange(),
(...skipping 19 matching lines...) Expand all
301 result.reset(new Scope(const_containing_)); 323 result.reset(new Scope(const_containing_));
302 } else if (mutable_containing_) { 324 } else if (mutable_containing_) {
303 // There are more nested mutable scopes. Recursively go up the stack to 325 // There are more nested mutable scopes. Recursively go up the stack to
304 // get the closure. 326 // get the closure.
305 result = mutable_containing_->MakeClosure(); 327 result = mutable_containing_->MakeClosure();
306 } else { 328 } else {
307 // This is a standalone scope, just copy it. 329 // This is a standalone scope, just copy it.
308 result.reset(new Scope(settings_)); 330 result.reset(new Scope(settings_));
309 } 331 }
310 332
333 // Want to clobber since we've flattened some nested scopes, and our parent
334 // scope may have a duplicate value set.
335 MergeOptions options;
336 options.clobber_existing = true;
337
311 // Add in our variables and we're done. 338 // Add in our variables and we're done.
312 Err err; 339 Err err;
313 NonRecursiveMergeTo(result.get(), true, NULL, "<SHOULDN'T HAPPEN>", &err); 340 NonRecursiveMergeTo(result.get(), options, NULL, "<SHOULDN'T HAPPEN>", &err);
314 DCHECK(!err.has_error()); 341 DCHECK(!err.has_error());
315 return result.Pass(); 342 return result.Pass();
316 } 343 }
317 344
318 Scope* Scope::MakeTargetDefaults(const std::string& target_type) { 345 Scope* Scope::MakeTargetDefaults(const std::string& target_type) {
319 if (GetTargetDefaults(target_type)) 346 if (GetTargetDefaults(target_type))
320 return NULL; 347 return NULL;
321 348
322 Scope** dest = &target_defaults_[target_type]; 349 Scope** dest = &target_defaults_[target_type];
323 if (*dest) { 350 if (*dest) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 if (found != properties_.end()) { 438 if (found != properties_.end()) {
412 if (found_on_scope) 439 if (found_on_scope)
413 *found_on_scope = this; 440 *found_on_scope = this;
414 return found->second; 441 return found->second;
415 } 442 }
416 if (containing()) 443 if (containing())
417 return containing()->GetProperty(key, found_on_scope); 444 return containing()->GetProperty(key, found_on_scope);
418 return NULL; 445 return NULL;
419 } 446 }
420 447
448 // static
449 bool Scope::IsPrivateVar(const base::StringPiece& name) {
450 return name.empty() || name[0] == '_';
451 }
452
421 void Scope::AddProvider(ProgrammaticProvider* p) { 453 void Scope::AddProvider(ProgrammaticProvider* p) {
422 programmatic_providers_.insert(p); 454 programmatic_providers_.insert(p);
423 } 455 }
424 456
425 void Scope::RemoveProvider(ProgrammaticProvider* p) { 457 void Scope::RemoveProvider(ProgrammaticProvider* p) {
426 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end()); 458 DCHECK(programmatic_providers_.find(p) != programmatic_providers_.end());
427 programmatic_providers_.erase(p); 459 programmatic_providers_.erase(p);
428 } 460 }
OLDNEW
« tools/gn/scope.h ('K') | « 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