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

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

Issue 136723008: Remove some appending behavior from GN. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 | « no previous file | tools/gn/operators_unittest.cc » ('j') | tools/gn/operators_unittest.cc » ('J')
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/operators.h" 5 #include "tools/gn/operators.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "tools/gn/err.h" 8 #include "tools/gn/err.h"
9 #include "tools/gn/parse_tree.h" 9 #include "tools/gn/parse_tree.h"
10 #include "tools/gn/scope.h" 10 #include "tools/gn/scope.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 96
97 // Assignment ----------------------------------------------------------------- 97 // Assignment -----------------------------------------------------------------
98 98
99 Value ExecuteEquals(Scope* scope, 99 Value ExecuteEquals(Scope* scope,
100 const BinaryOpNode* op_node, 100 const BinaryOpNode* op_node,
101 const Token& left, 101 const Token& left,
102 const Value& right, 102 const Value& right,
103 Err* err) { 103 Err* err) {
104 const Value* old_value = scope->GetValue(left.value(), false); 104 const Value* old_value = scope->GetValue(left.value(), false);
105 if (old_value) { 105 if (old_value) {
106 if (scope->IsSetButUnused(left.value())) { 106 // Throw an error when overwriting a nonempty list with another nonempty
107 // Throw an error for re-assigning without using the value first. The 107 // list item. This is to detect the case where you write
108 // exception is that you can overwrite an empty list with another list 108 // defines = ["FOO"]
109 // since this is the way to get around the "can't overwrite a nonempty 109 // and you overwrote inherited ones, when instead you mean to append:
110 // list with another nonempty list" restriction. 110 // defines += ["FOO"]
111 if (old_value->type() != Value::LIST || 111 if (old_value->type() == Value::LIST &&
112 !old_value->list_value().empty()) { 112 !old_value->list_value().empty() &&
113 *err = Err(op_node->left()->GetRange(), "Overwriting unused variable.", 113 right.type() == Value::LIST &&
114 "This overwrites a previous assignment to \"" + 114 !right.list_value().empty()) {
115 left.value().as_string() + "\" that had no effect."); 115 *err = Err(op_node->left()->GetRange(), "Replacing nonempty list.",
116 err->AppendSubErr(Err(*scope->GetValue(left.value()), 116 std::string("This overwrites a previously-defined nonempty list ") +
117 "Previously set here.", 117 "(length " +
118 "Maybe you wanted \"+=\" to append instead?")); 118 base::IntToString(static_cast<int>(old_value->list_value().size()))
119 return Value(); 119 + ").");
120 } 120 err->AppendSubErr(Err(*old_value, "for previous definition",
121 } else { 121 "with another one (length " +
122 // Throw an error when overwriting a nonempty list with another nonempty 122 base::IntToString(static_cast<int>(right.list_value().size())) +
123 // list item. This is to detect the case where you write 123 "). Did you mean " +
124 // defines = ["FOO"] 124 "\"+=\" to append instead? If you\nreally want to do this, do\n " +
125 // and you overwrote inherited ones, when instead you mean to append: 125 left.value().as_string() + " = []\nbefore reassigning."));
126 // defines += ["FOO"] 126 return Value();
127 if (old_value->type() == Value::LIST &&
128 !old_value->list_value().empty() &&
129 right.type() == Value::LIST &&
130 !right.list_value().empty()) {
131 *err = Err(op_node->left()->GetRange(), "Replacing nonempty list.",
132 std::string("This overwrites a previously-defined nonempty list ") +
133 "(length " +
134 base::IntToString(static_cast<int>(old_value->list_value().size()))
135 + ").");
136 err->AppendSubErr(Err(*old_value, "for previous definition",
137 "with another one (length " +
138 base::IntToString(static_cast<int>(right.list_value().size())) +
139 "). Did you mean " +
140 "\"+=\" to append instead? If you\nreally want to do this, do\n " +
141 left.value().as_string() + " = []\nbefore reassigning."));
142 return Value();
143 }
144 } 127 }
145 } 128 }
146 if (err->has_error()) 129 if (err->has_error())
147 return Value(); 130 return Value();
148 131
149 if (right.type() == Value::LIST && left.value() == kSourcesName) { 132 if (right.type() == Value::LIST && left.value() == kSourcesName) {
150 // Assigning to sources, filter the list. Here we do the filtering and 133 // Assigning to sources, filter the list. Here we do the filtering and
151 // copying in one step to save an extra list copy (the lists may be 134 // copying in one step to save an extra list copy (the lists may be
152 // long). 135 // long).
153 Value* set_value = scope->SetValue(left.value(), 136 Value* set_value = scope->SetValue(left.value(),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 return; 186 return;
204 187
205 default: 188 default:
206 break; 189 break;
207 } 190 }
208 break; 191 break;
209 192
210 // Left-hand-side list. 193 // Left-hand-side list.
211 case Value::LIST: 194 case Value::LIST:
212 switch (right.type()) { 195 switch (right.type()) {
213 case Value::INTEGER: // list + integer -> list append.
214 case Value::STRING: // list + string -> list append.
215 if (left_token.value() == kSourcesName)
216 AppendFilteredSourcesToValue(scope, right, left);
217 else
218 left->list_value().push_back(right);
219 return;
220
221 case Value::LIST: // list + list -> list concat. 196 case Value::LIST: // list + list -> list concat.
222 if (left_token.value() == kSourcesName) { 197 if (left_token.value() == kSourcesName) {
223 // Filter additions through the assignment filter. 198 // Filter additions through the assignment filter.
224 AppendFilteredSourcesToValue(scope, right, left); 199 AppendFilteredSourcesToValue(scope, right, left);
225 } else { 200 } else {
226 // Normal list concat. 201 // Normal list concat.
227 for (size_t i = 0; i < right.list_value().size(); i++) 202 for (size_t i = 0; i < right.list_value().size(); i++)
228 left->list_value().push_back(right.list_value()[i]); 203 left->list_value().push_back(right.list_value()[i]);
229 } 204 }
230 return; 205 return;
231 206
232 default: 207 default:
233 break; 208 *err = Err(op_node->op(), "Incompatible types to add.",
209 "To append a single item to a list do \"foo += [ bar ]\".");
210 return;
234 } 211 }
235 212
236 default: 213 default:
237 break; 214 break;
238 } 215 }
239 216
240 *err = Err(op_node->op(), "Incompatible types to add.", 217 *err = Err(op_node->op(), "Incompatible types to add.",
241 std::string("I see a ") + Value::DescribeType(left->type()) + " and a " + 218 std::string("I see a ") + Value::DescribeType(left->type()) + " and a " +
242 Value::DescribeType(right.type()) + "."); 219 Value::DescribeType(right.type()) + ".");
243 } 220 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 break; 256 break;
280 } 257 }
281 break; 258 break;
282 259
283 // Left-hand-side string. 260 // Left-hand-side string.
284 case Value::STRING: 261 case Value::STRING:
285 break; // All are errors. 262 break; // All are errors.
286 263
287 // Left-hand-side list. 264 // Left-hand-side list.
288 case Value::LIST: 265 case Value::LIST:
289 RemoveMatchesFromList(op_node, left, right, err); 266 if (!right.type() != Value::LIST) {
scottmg 2014/01/15 00:32:07 is !right.type() what you meant?
267 *err = Err(op_node->op(), "Incompatible types to subtract.",
268 "To remove a single item from a list do \"foo -= [ bar ]\".");
269 } else {
270 RemoveMatchesFromList(op_node, left, right, err);
271 }
290 return; 272 return;
291 273
292 default: 274 default:
293 break; 275 break;
294 } 276 }
295 277
296 *err = Err(op_node->op(), "Incompatible types to subtract.", 278 *err = Err(op_node->op(), "Incompatible types to subtract.",
297 std::string("I see a ") + Value::DescribeType(left->type()) + " and a " + 279 std::string("I see a ") + Value::DescribeType(left->type()) + " and a " +
298 Value::DescribeType(right.type()) + "."); 280 Value::DescribeType(right.type()) + ".");
299 } 281 }
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 return ExecuteLess(scope, op_node, left_value, right_value, err); 567 return ExecuteLess(scope, op_node, left_value, right_value, err);
586 568
587 // ||, &&. 569 // ||, &&.
588 if (op.type() == Token::BOOLEAN_OR) 570 if (op.type() == Token::BOOLEAN_OR)
589 return ExecuteOr(scope, op_node, left_value, right_value, err); 571 return ExecuteOr(scope, op_node, left_value, right_value, err);
590 if (op.type() == Token::BOOLEAN_AND) 572 if (op.type() == Token::BOOLEAN_AND)
591 return ExecuteAnd(scope, op_node, left_value, right_value, err); 573 return ExecuteAnd(scope, op_node, left_value, right_value, err);
592 574
593 return Value(); 575 return Value();
594 } 576 }
OLDNEW
« no previous file with comments | « no previous file | tools/gn/operators_unittest.cc » ('j') | tools/gn/operators_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698