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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js/template.dart

Issue 671513013: dart2js: Accept named holes in js-templates. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of js; 5 part of js;
6 6
7 class TemplateManager { 7 class TemplateManager {
8 Map<String, Template> expressionTemplates = new Map<String, Template>(); 8 Map<String, Template> expressionTemplates = new Map<String, Template>();
9 Map<String, Template> statementTemplates = new Map<String, Template>(); 9 Map<String, Template> statementTemplates = new Map<String, Template>();
10 10
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 return generator.analysis.count == 0; 83 return generator.analysis.count == 0;
84 } 84 }
85 85
86 void _compile() { 86 void _compile() {
87 InstantiatorGeneratorVisitor generator = 87 InstantiatorGeneratorVisitor generator =
88 new InstantiatorGeneratorVisitor(forceCopy); 88 new InstantiatorGeneratorVisitor(forceCopy);
89 instantiator = generator.compile(ast); 89 instantiator = generator.compile(ast);
90 positionalArgumentCount = generator.analysis.count; 90 positionalArgumentCount = generator.analysis.count;
91 } 91 }
92 92
93 Node instantiate(List arguments) { 93 /// Instantiates the template with the given [arguments].
94 ///
95 /// This method fills in the holes with the given arguments. The [arguments]
96 /// must be either a [List] or a [Map].
97 Node instantiate(var arguments) {
94 if (arguments is List) { 98 if (arguments is List) {
95 if (arguments.length != positionalArgumentCount) { 99 if (arguments.length != positionalArgumentCount) {
96 throw 'Wrong number of template arguments, given ${arguments.length}, ' 100 throw 'Wrong number of template arguments, given ${arguments.length}, '
97 'expected $positionalArgumentCount'; 101 'expected $positionalArgumentCount';
98 } 102 }
99 return instantiator(arguments); 103 return instantiator(arguments);
100 } 104 }
101 // TODO(sra): Add named placeholders and a Map of arguments. 105 assert(arguments is Map);
sra1 2014/10/22 21:50:28 It might be nice to collect the set of names in th
floitsch 2014/11/03 18:12:58 Done.
102 throw new UnimplementedError('Template arguments must be a list'); 106 return instantiator(arguments);
103 } 107 }
104 } 108 }
105 109
106 /** 110 /**
107 * An Instantiator is a Function that generates a JS AST tree or List of 111 * An Instantiator is a Function that generates a JS AST tree or List of
108 * trees. [arguments] is a List for positional templates, or (TODO) Map for 112 * trees. [arguments] is a List for positional templates, or Map for
109 * named templates. 113 * named templates.
110 */ 114 */
111 typedef Node Instantiator(var arguments); 115 typedef Node Instantiator(var arguments);
112 116
113 117
114 /** 118 /**
115 * InstantiatorGeneratorVisitor compiles a template. This class compiles a tree 119 * InstantiatorGeneratorVisitor compiles a template. This class compiles a tree
116 * containing [InterpolatedNode]s into a function that will create a copy of the 120 * containing [InterpolatedNode]s into a function that will create a copy of the
117 * tree with the interpolated nodes substituted with provided values. 121 * tree with the interpolated nodes substituted with provided values.
118 */ 122 */
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 166 }
163 167
164 static RegExp identiferRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$'); 168 static RegExp identiferRE = new RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$');
165 169
166 static Expression convertStringToVariableUse(String value) { 170 static Expression convertStringToVariableUse(String value) {
167 assert(identiferRE.hasMatch(value)); 171 assert(identiferRE.hasMatch(value));
168 return new VariableUse(value); 172 return new VariableUse(value);
169 } 173 }
170 174
171 Instantiator visitInterpolatedExpression(InterpolatedExpression node) { 175 Instantiator visitInterpolatedExpression(InterpolatedExpression node) {
172 int position = node.name; 176 var name = node.name;
173 return (arguments) { 177 return (arguments) {
174 var value = arguments[position]; 178 var value = arguments[name];
175 if (value is Expression) return value; 179 if (value is Expression) return value;
176 if (value is String) return convertStringToVariableUse(value);; 180 if (value is String) return convertStringToVariableUse(value);;
177 error('Interpolated value #$position is not an Expression: $value'); 181 error('Interpolated value #$name is not an Expression: $value');
178 }; 182 };
179 } 183 }
180 184
181 Instantiator visitSplayableExpression(Node node) { 185 Instantiator visitSplayableExpression(Node node) {
182 if (node is InterpolatedExpression) { 186 if (node is InterpolatedExpression) {
183 int position = node.name; 187 var name = node.name;
184 return (arguments) { 188 return (arguments) {
185 var value = arguments[position]; 189 var value = arguments[name];
186 Expression toExpression(item) { 190 Expression toExpression(item) {
187 if (item is Expression) return item; 191 if (item is Expression) return item;
188 if (item is String) return convertStringToVariableUse(item); 192 if (item is String) return convertStringToVariableUse(item);
189 return error('Interpolated value #$position is not ' 193 return error('Interpolated value #$name is not '
190 'an Expression or List of Expressions: $value'); 194 'an Expression or List of Expressions: $value');
191 } 195 }
192 if (value is Iterable) return value.map(toExpression); 196 if (value is Iterable) return value.map(toExpression);
193 return toExpression(value); 197 return toExpression(value);
194 }; 198 };
195 } 199 }
196 return visit(node); 200 return visit(node);
197 } 201 }
198 202
199 Instantiator visitInterpolatedLiteral(InterpolatedLiteral node) { 203 Instantiator visitInterpolatedLiteral(InterpolatedLiteral node) {
200 int position = node.name; 204 var name = node.name;
201 return (arguments) { 205 return (arguments) {
202 var value = arguments[position]; 206 var value = arguments[name];
203 if (value is Literal) return value; 207 if (value is Literal) return value;
204 error('Interpolated value #$position is not a Literal: $value'); 208 error('Interpolated value #$name is not a Literal: $value');
205 }; 209 };
206 } 210 }
207 211
208 Instantiator visitInterpolatedParameter(InterpolatedParameter node) { 212 Instantiator visitInterpolatedParameter(InterpolatedParameter node) {
209 int position = node.name; 213 var name = node.name;
210 return (arguments) { 214 return (arguments) {
211 var value = arguments[position]; 215 var value = arguments[name];
212 216
213 Parameter toParameter(item) { 217 Parameter toParameter(item) {
214 if (item is Parameter) return item; 218 if (item is Parameter) return item;
215 if (item is String) return new Parameter(item); 219 if (item is String) return new Parameter(item);
216 return error('Interpolated value #$position is not a Parameter or ' 220 return error('Interpolated value #$name is not a Parameter or '
217 'List of Parameters: $value'); 221 'List of Parameters: $value');
218 } 222 }
219 if (value is Iterable) return value.map(toParameter); 223 if (value is Iterable) return value.map(toParameter);
220 return toParameter(value); 224 return toParameter(value);
221 }; 225 };
222 } 226 }
223 227
224 Instantiator visitInterpolatedSelector(InterpolatedSelector node) { 228 Instantiator visitInterpolatedSelector(InterpolatedSelector node) {
225 // A selector is an expression, as in `a[selector]`. 229 // A selector is an expression, as in `a[selector]`.
226 // A String argument converted into a LiteralString, so `a.#` with argument 230 // A String argument converted into a LiteralString, so `a.#` with argument
227 // 'foo' generates `a["foo"]` which prints as `a.foo`. 231 // 'foo' generates `a["foo"]` which prints as `a.foo`.
228 int position = node.name; 232 var name = node.name;
229 return (arguments) { 233 return (arguments) {
230 var value = arguments[position]; 234 var value = arguments[name];
231 if (value is Expression) return value; 235 if (value is Expression) return value;
232 if (value is String) return new LiteralString('"$value"'); 236 if (value is String) return new LiteralString('"$value"');
233 error('Interpolated value #$position is not a selector: $value'); 237 error('Interpolated value #$name is not a selector: $value');
234 }; 238 };
235 } 239 }
236 240
237 Instantiator visitInterpolatedStatement(InterpolatedStatement node) { 241 Instantiator visitInterpolatedStatement(InterpolatedStatement node) {
238 int position = node.name; 242 var name = node.name;
239 return (arguments) { 243 return (arguments) {
240 var value = arguments[position]; 244 var value = arguments[name];
241 if (value is Node) return value.toStatement(); 245 if (value is Node) return value.toStatement();
242 error('Interpolated value #$position is not a Statement: $value'); 246 error('Interpolated value #$name is not a Statement: $value');
243 }; 247 };
244 } 248 }
245 249
246 Instantiator visitSplayableStatement(Node node) { 250 Instantiator visitSplayableStatement(Node node) {
247 if (node is InterpolatedStatement) { 251 if (node is InterpolatedStatement) {
248 int position = node.name; 252 var name = node.name;
249 return (arguments) { 253 return (arguments) {
250 var value = arguments[position]; 254 var value = arguments[name];
251 Statement toStatement(item) { 255 Statement toStatement(item) {
252 if (item is Statement) return item; 256 if (item is Statement) return item;
253 if (item is Expression) return item.toStatement();; 257 if (item is Expression) return item.toStatement();;
254 return error('Interpolated value #$position is not ' 258 return error('Interpolated value #$name is not '
255 'a Statement or List of Statements: $value'); 259 'a Statement or List of Statements: $value');
256 } 260 }
257 if (value is Iterable) return value.map(toStatement); 261 if (value is Iterable) return value.map(toStatement);
258 return toStatement(value); 262 return toStatement(value);
259 }; 263 };
260 } 264 }
261 return visit(node); 265 return visit(node);
262 } 266 }
263 267
264 Instantiator visitProgram(Program node) { 268 Instantiator visitProgram(Program node) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 if (node.condition is InterpolatedExpression) { 319 if (node.condition is InterpolatedExpression) {
316 return visitIfConditionalCompilation(node); 320 return visitIfConditionalCompilation(node);
317 } else { 321 } else {
318 return visitIfNormal(node); 322 return visitIfNormal(node);
319 } 323 }
320 } 324 }
321 325
322 Instantiator visitIfConditionalCompilation(If node) { 326 Instantiator visitIfConditionalCompilation(If node) {
323 // Special version of visitInterpolatedExpression that permits bools. 327 // Special version of visitInterpolatedExpression that permits bools.
324 compileCondition(InterpolatedExpression node) { 328 compileCondition(InterpolatedExpression node) {
325 int position = node.name; 329 var name = node.name;
326 return (arguments) { 330 return (arguments) {
327 var value = arguments[position]; 331 var value = arguments[name];
328 if (value is bool) return value; 332 if (value is bool) return value;
329 if (value is Expression) return value; 333 if (value is Expression) return value;
330 if (value is String) return convertStringToVariableUse(value);; 334 if (value is String) return convertStringToVariableUse(value);;
331 error('Interpolated value #$position is not an Expression: $value'); 335 error('Interpolated value #$name is not an Expression: $value');
332 }; 336 };
333 } 337 }
334 var makeCondition = compileCondition(node.condition); 338 var makeCondition = compileCondition(node.condition);
335 Instantiator makeThen = visit(node.then); 339 Instantiator makeThen = visit(node.then);
336 Instantiator makeOtherwise = visit(node.otherwise); 340 Instantiator makeOtherwise = visit(node.otherwise);
337 return (arguments) { 341 return (arguments) {
338 var condition = makeCondition(arguments); 342 var condition = makeCondition(arguments);
339 if (condition is bool) { 343 if (condition is bool) {
340 if (condition == true) { 344 if (condition == true) {
341 return makeThen(arguments); 345 return makeThen(arguments);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 if (count != before) containsInterpolatedNode.add(node); 675 if (count != before) containsInterpolatedNode.add(node);
672 return null; 676 return null;
673 } 677 }
674 678
675 visitInterpolatedNode(InterpolatedNode node) { 679 visitInterpolatedNode(InterpolatedNode node) {
676 interpolatedNodes.add(node); 680 interpolatedNodes.add(node);
677 containsInterpolatedNode.add(node); 681 containsInterpolatedNode.add(node);
678 ++count; 682 ++count;
679 } 683 }
680 } 684 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698