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

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

Issue 251593006: Functional JavaScript AST source position updates (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 abstract class NodeVisitor<T> { 7 abstract class NodeVisitor<T> {
8 T visitProgram(Program node); 8 T visitProgram(Program node);
9 9
10 T visitBlock(Block node); 10 T visitBlock(Block node);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 T visitInterpolatedSelector(InterpolatedSelector node) 163 T visitInterpolatedSelector(InterpolatedSelector node)
164 => visitInterpolatedNode(node); 164 => visitInterpolatedNode(node);
165 T visitInterpolatedStatement(InterpolatedStatement node) 165 T visitInterpolatedStatement(InterpolatedStatement node)
166 => visitInterpolatedNode(node); 166 => visitInterpolatedNode(node);
167 167
168 // Ignore comments by default. 168 // Ignore comments by default.
169 T visitComment(Comment node) => null; 169 T visitComment(Comment node) => null;
170 } 170 }
171 171
172 abstract class Node { 172 abstract class Node {
173 var sourcePosition; 173 get sourcePosition => _sourcePosition;
174 var endSourcePosition; 174 get endSourcePosition => _endSourcePosition;
175
176 var _sourcePosition;
177 var _endSourcePosition;
175 178
176 accept(NodeVisitor visitor); 179 accept(NodeVisitor visitor);
177 void visitChildren(NodeVisitor visitor); 180 void visitChildren(NodeVisitor visitor);
181 Node _clone(); // Single node clone
floitsch 2014/04/28 12:28:11 Comment. Does it need to clone positions?...
sra1 2014/04/28 18:24:09 No, because it is used only by code that sets the
floitsch 2014/04/30 15:36:01 I got it (reading the source). Just wanted you to
182
183 Node withPosition(var sourcePosition, var endSourcePosition) {
floitsch 2014/04/28 12:28:11 comments.
sra1 2014/04/28 18:24:09 Done.
184 if (sourcePosition == _sourcePosition &&
185 endSourcePosition == _endSourcePosition) {
186 return this;
187 }
188 Node clone = _clone();
189 // TODO(sra): Should existing data be 'sticky' if we overwrite with `null`?
190 clone._sourcePosition = sourcePosition;
191 clone._endSourcePosition = endSourcePosition;
192 return clone;
193 }
194
195 Node withLocation(var sourcePosition) =>
floitsch 2014/04/28 12:28:11 comments. In particular differentiating Position/L
sra1 2014/04/28 18:24:09 Done.
196 withPosition(sourcePosition, this.endSourcePosition);
178 197
179 VariableUse asVariableUse() => null; 198 VariableUse asVariableUse() => null;
180 199
181 Statement toStatement() { 200 Statement toStatement() {
182 throw new UnsupportedError('toStatement'); 201 throw new UnsupportedError('toStatement');
183 } 202 }
184 } 203 }
185 204
186 class Program extends Node { 205 class Program extends Node {
187 final List<Statement> body; 206 final List<Statement> body;
188 Program(this.body); 207 Program(this.body);
189 208
190 accept(NodeVisitor visitor) => visitor.visitProgram(this); 209 accept(NodeVisitor visitor) => visitor.visitProgram(this);
191 void visitChildren(NodeVisitor visitor) { 210 void visitChildren(NodeVisitor visitor) {
192 for (Statement statement in body) statement.accept(visitor); 211 for (Statement statement in body) statement.accept(visitor);
193 } 212 }
213 Program _clone() => new Program(body);
194 } 214 }
195 215
196 abstract class Statement extends Node { 216 abstract class Statement extends Node {
197 Statement toStatement() => this; 217 Statement toStatement() => this;
218
219 Statement withPosition(var sourcePosition, var endSourcePosition) =>
220 super.withPosition(sourcePosition, endSourcePosition);
198 } 221 }
199 222
200 class Block extends Statement { 223 class Block extends Statement {
201 final List<Statement> statements; 224 final List<Statement> statements;
202 Block(this.statements); 225 Block(this.statements);
203 Block.empty() : this.statements = <Statement>[]; 226 Block.empty() : this.statements = <Statement>[];
204 227
205 accept(NodeVisitor visitor) => visitor.visitBlock(this); 228 accept(NodeVisitor visitor) => visitor.visitBlock(this);
206 void visitChildren(NodeVisitor visitor) { 229 void visitChildren(NodeVisitor visitor) {
207 for (Statement statement in statements) statement.accept(visitor); 230 for (Statement statement in statements) statement.accept(visitor);
208 } 231 }
232 Block _clone() => new Block(statements);
209 } 233 }
210 234
211 class ExpressionStatement extends Statement { 235 class ExpressionStatement extends Statement {
212 final Expression expression; 236 final Expression expression;
213 ExpressionStatement(this.expression); 237 ExpressionStatement(this.expression);
214 238
215 accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this); 239 accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this);
216 void visitChildren(NodeVisitor visitor) { expression.accept(visitor); } 240 void visitChildren(NodeVisitor visitor) { expression.accept(visitor); }
241 ExpressionStatement _clone() => new ExpressionStatement(expression);
217 } 242 }
218 243
219 class EmptyStatement extends Statement { 244 class EmptyStatement extends Statement {
220 EmptyStatement(); 245 EmptyStatement();
221 246
222 accept(NodeVisitor visitor) => visitor.visitEmptyStatement(this); 247 accept(NodeVisitor visitor) => visitor.visitEmptyStatement(this);
223 void visitChildren(NodeVisitor visitor) {} 248 void visitChildren(NodeVisitor visitor) {}
249 EmptyStatement _clone() => new EmptyStatement();
224 } 250 }
225 251
226 class If extends Statement { 252 class If extends Statement {
227 final Expression condition; 253 final Expression condition;
228 final Node then; 254 final Node then;
229 final Node otherwise; 255 final Node otherwise;
230 256
231 If(this.condition, this.then, this.otherwise); 257 If(this.condition, this.then, this.otherwise);
232 If.noElse(this.condition, this.then) : this.otherwise = new EmptyStatement(); 258 If.noElse(this.condition, this.then) : this.otherwise = new EmptyStatement();
233 259
234 bool get hasElse => otherwise is !EmptyStatement; 260 bool get hasElse => otherwise is !EmptyStatement;
235 261
236 accept(NodeVisitor visitor) => visitor.visitIf(this); 262 accept(NodeVisitor visitor) => visitor.visitIf(this);
237 263
238 void visitChildren(NodeVisitor visitor) { 264 void visitChildren(NodeVisitor visitor) {
239 condition.accept(visitor); 265 condition.accept(visitor);
240 then.accept(visitor); 266 then.accept(visitor);
241 otherwise.accept(visitor); 267 otherwise.accept(visitor);
242 } 268 }
269
270 If _clone() => new If(condition, then, otherwise);
243 } 271 }
244 272
245 abstract class Loop extends Statement { 273 abstract class Loop extends Statement {
246 final Statement body; 274 final Statement body;
247 Loop(this.body); 275 Loop(this.body);
248 } 276 }
249 277
250 class For extends Loop { 278 class For extends Loop {
251 final Expression init; 279 final Expression init;
252 final Expression condition; 280 final Expression condition;
253 final Expression update; 281 final Expression update;
254 282
255 For(this.init, this.condition, this.update, Statement body) : super(body); 283 For(this.init, this.condition, this.update, Statement body) : super(body);
256 284
257 accept(NodeVisitor visitor) => visitor.visitFor(this); 285 accept(NodeVisitor visitor) => visitor.visitFor(this);
258 286
259 void visitChildren(NodeVisitor visitor) { 287 void visitChildren(NodeVisitor visitor) {
260 if (init != null) init.accept(visitor); 288 if (init != null) init.accept(visitor);
261 if (condition != null) condition.accept(visitor); 289 if (condition != null) condition.accept(visitor);
262 if (update != null) update.accept(visitor); 290 if (update != null) update.accept(visitor);
263 body.accept(visitor); 291 body.accept(visitor);
264 } 292 }
293
294 For _clone() => new For(init, condition, update, body);
265 } 295 }
266 296
267 class ForIn extends Loop { 297 class ForIn extends Loop {
268 // Note that [VariableDeclarationList] is a subclass of [Expression]. 298 // Note that [VariableDeclarationList] is a subclass of [Expression].
269 // Therefore we can type the leftHandSide as [Expression]. 299 // Therefore we can type the leftHandSide as [Expression].
270 final Expression leftHandSide; 300 final Expression leftHandSide;
271 final Expression object; 301 final Expression object;
272 302
273 ForIn(this.leftHandSide, this.object, Statement body) : super(body); 303 ForIn(this.leftHandSide, this.object, Statement body) : super(body);
274 304
275 accept(NodeVisitor visitor) => visitor.visitForIn(this); 305 accept(NodeVisitor visitor) => visitor.visitForIn(this);
276 306
277 void visitChildren(NodeVisitor visitor) { 307 void visitChildren(NodeVisitor visitor) {
278 leftHandSide.accept(visitor); 308 leftHandSide.accept(visitor);
279 object.accept(visitor); 309 object.accept(visitor);
280 body.accept(visitor); 310 body.accept(visitor);
281 } 311 }
312
313 ForIn _clone() => new ForIn(leftHandSide, object, body);
282 } 314 }
283 315
284 class While extends Loop { 316 class While extends Loop {
285 final Node condition; 317 final Node condition;
286 318
287 While(this.condition, Statement body) : super(body); 319 While(this.condition, Statement body) : super(body);
288 320
289 accept(NodeVisitor visitor) => visitor.visitWhile(this); 321 accept(NodeVisitor visitor) => visitor.visitWhile(this);
290 322
291 void visitChildren(NodeVisitor visitor) { 323 void visitChildren(NodeVisitor visitor) {
292 condition.accept(visitor); 324 condition.accept(visitor);
293 body.accept(visitor); 325 body.accept(visitor);
294 } 326 }
327
328 While _clone() => new While(condition, body);
295 } 329 }
296 330
297 class Do extends Loop { 331 class Do extends Loop {
298 final Expression condition; 332 final Expression condition;
299 333
300 Do(Statement body, this.condition) : super(body); 334 Do(Statement body, this.condition) : super(body);
301 335
302 accept(NodeVisitor visitor) => visitor.visitDo(this); 336 accept(NodeVisitor visitor) => visitor.visitDo(this);
303 337
304 void visitChildren(NodeVisitor visitor) { 338 void visitChildren(NodeVisitor visitor) {
305 body.accept(visitor); 339 body.accept(visitor);
306 condition.accept(visitor); 340 condition.accept(visitor);
307 } 341 }
342
343 Do _clone() => new Do(body, condition);
308 } 344 }
309 345
310 class Continue extends Statement { 346 class Continue extends Statement {
311 final String targetLabel; // Can be null. 347 final String targetLabel; // Can be null.
312 348
313 Continue(this.targetLabel); 349 Continue(this.targetLabel);
314 350
315 accept(NodeVisitor visitor) => visitor.visitContinue(this); 351 accept(NodeVisitor visitor) => visitor.visitContinue(this);
316 void visitChildren(NodeVisitor visitor) {} 352 void visitChildren(NodeVisitor visitor) {}
353
354 Continue _clone() => new Continue(targetLabel);
317 } 355 }
318 356
319 class Break extends Statement { 357 class Break extends Statement {
320 final String targetLabel; // Can be null. 358 final String targetLabel; // Can be null.
321 359
322 Break(this.targetLabel); 360 Break(this.targetLabel);
323 361
324 accept(NodeVisitor visitor) => visitor.visitBreak(this); 362 accept(NodeVisitor visitor) => visitor.visitBreak(this);
325 void visitChildren(NodeVisitor visitor) {} 363 void visitChildren(NodeVisitor visitor) {}
364
365 Break _clone() => new Break(targetLabel);
326 } 366 }
327 367
328 class Return extends Statement { 368 class Return extends Statement {
329 final Expression value; // Can be null. 369 final Expression value; // Can be null.
330 370
331 Return([this.value = null]); 371 Return([this.value = null]);
332 372
333 accept(NodeVisitor visitor) => visitor.visitReturn(this); 373 accept(NodeVisitor visitor) => visitor.visitReturn(this);
334 374
335 void visitChildren(NodeVisitor visitor) { 375 void visitChildren(NodeVisitor visitor) {
336 if (value != null) value.accept(visitor); 376 if (value != null) value.accept(visitor);
337 } 377 }
378
379 Return _clone() => new Return(value);
338 } 380 }
339 381
340 class Throw extends Statement { 382 class Throw extends Statement {
341 final Expression expression; 383 final Expression expression;
342 384
343 Throw(this.expression); 385 Throw(this.expression);
344 386
345 accept(NodeVisitor visitor) => visitor.visitThrow(this); 387 accept(NodeVisitor visitor) => visitor.visitThrow(this);
346 388
347 void visitChildren(NodeVisitor visitor) { 389 void visitChildren(NodeVisitor visitor) {
348 expression.accept(visitor); 390 expression.accept(visitor);
349 } 391 }
392
393 Throw _clone() => new Throw(expression);
350 } 394 }
351 395
352 class Try extends Statement { 396 class Try extends Statement {
353 final Block body; 397 final Block body;
354 final Catch catchPart; // Can be null if [finallyPart] is non-null. 398 final Catch catchPart; // Can be null if [finallyPart] is non-null.
355 final Block finallyPart; // Can be null if [catchPart] is non-null. 399 final Block finallyPart; // Can be null if [catchPart] is non-null.
356 400
357 Try(this.body, this.catchPart, this.finallyPart) { 401 Try(this.body, this.catchPart, this.finallyPart) {
358 assert(catchPart != null || finallyPart != null); 402 assert(catchPart != null || finallyPart != null);
359 } 403 }
360 404
361 accept(NodeVisitor visitor) => visitor.visitTry(this); 405 accept(NodeVisitor visitor) => visitor.visitTry(this);
362 406
363 void visitChildren(NodeVisitor visitor) { 407 void visitChildren(NodeVisitor visitor) {
364 body.accept(visitor); 408 body.accept(visitor);
365 if (catchPart != null) catchPart.accept(visitor); 409 if (catchPart != null) catchPart.accept(visitor);
366 if (finallyPart != null) finallyPart.accept(visitor); 410 if (finallyPart != null) finallyPart.accept(visitor);
367 } 411 }
412
413 Try _clone() => new Try(body, catchPart, finallyPart);
368 } 414 }
369 415
370 class Catch extends Node { 416 class Catch extends Node {
371 final VariableDeclaration declaration; 417 final VariableDeclaration declaration;
372 final Block body; 418 final Block body;
373 419
374 Catch(this.declaration, this.body); 420 Catch(this.declaration, this.body);
375 421
376 accept(NodeVisitor visitor) => visitor.visitCatch(this); 422 accept(NodeVisitor visitor) => visitor.visitCatch(this);
377 423
378 void visitChildren(NodeVisitor visitor) { 424 void visitChildren(NodeVisitor visitor) {
379 declaration.accept(visitor); 425 declaration.accept(visitor);
380 body.accept(visitor); 426 body.accept(visitor);
381 } 427 }
428
429 Catch _clone() => new Catch(declaration, body);
382 } 430 }
383 431
384 class Switch extends Statement { 432 class Switch extends Statement {
385 final Expression key; 433 final Expression key;
386 final List<SwitchClause> cases; 434 final List<SwitchClause> cases;
387 435
388 Switch(this.key, this.cases); 436 Switch(this.key, this.cases);
389 437
390 accept(NodeVisitor visitor) => visitor.visitSwitch(this); 438 accept(NodeVisitor visitor) => visitor.visitSwitch(this);
391 439
392 void visitChildren(NodeVisitor visitor) { 440 void visitChildren(NodeVisitor visitor) {
393 key.accept(visitor); 441 key.accept(visitor);
394 for (SwitchClause clause in cases) clause.accept(visitor); 442 for (SwitchClause clause in cases) clause.accept(visitor);
395 } 443 }
444
445 Switch _clone() => new Switch(key, cases);
396 } 446 }
397 447
398 abstract class SwitchClause extends Node { 448 abstract class SwitchClause extends Node {
399 final Block body; 449 final Block body;
400 450
401 SwitchClause(this.body); 451 SwitchClause(this.body);
452
453 SwitchClause _clone() => new SwitchClause(body);
402 } 454 }
403 455
404 class Case extends SwitchClause { 456 class Case extends SwitchClause {
405 final Expression expression; 457 final Expression expression;
406 458
407 Case(this.expression, Block body) : super(body); 459 Case(this.expression, Block body) : super(body);
408 460
409 accept(NodeVisitor visitor) => visitor.visitCase(this); 461 accept(NodeVisitor visitor) => visitor.visitCase(this);
410 462
411 void visitChildren(NodeVisitor visitor) { 463 void visitChildren(NodeVisitor visitor) {
412 expression.accept(visitor); 464 expression.accept(visitor);
413 body.accept(visitor); 465 body.accept(visitor);
414 } 466 }
467
468 Case _clone() => new Case(expression, body);
415 } 469 }
416 470
417 class Default extends SwitchClause { 471 class Default extends SwitchClause {
418 Default(Block body) : super(body); 472 Default(Block body) : super(body);
419 473
420 accept(NodeVisitor visitor) => visitor.visitDefault(this); 474 accept(NodeVisitor visitor) => visitor.visitDefault(this);
421 475
422 void visitChildren(NodeVisitor visitor) { 476 void visitChildren(NodeVisitor visitor) {
423 body.accept(visitor); 477 body.accept(visitor);
424 } 478 }
479
480 Default _clone() => new Default(body);
425 } 481 }
426 482
427 class FunctionDeclaration extends Statement { 483 class FunctionDeclaration extends Statement {
428 final VariableDeclaration name; 484 final VariableDeclaration name;
429 final Fun function; 485 final Fun function;
430 486
431 FunctionDeclaration(this.name, this.function); 487 FunctionDeclaration(this.name, this.function);
432 488
433 accept(NodeVisitor visitor) => visitor.visitFunctionDeclaration(this); 489 accept(NodeVisitor visitor) => visitor.visitFunctionDeclaration(this);
434 490
435 void visitChildren(NodeVisitor visitor) { 491 void visitChildren(NodeVisitor visitor) {
436 name.accept(visitor); 492 name.accept(visitor);
437 function.accept(visitor); 493 function.accept(visitor);
438 } 494 }
495
496 FunctionDeclaration _clone() => new FunctionDeclaration(name, function);
439 } 497 }
440 498
441 class LabeledStatement extends Statement { 499 class LabeledStatement extends Statement {
442 final String label; 500 final String label;
443 final Statement body; 501 final Statement body;
444 502
445 LabeledStatement(this.label, this.body); 503 LabeledStatement(this.label, this.body);
446 504
447 accept(NodeVisitor visitor) => visitor.visitLabeledStatement(this); 505 accept(NodeVisitor visitor) => visitor.visitLabeledStatement(this);
448 506
449 void visitChildren(NodeVisitor visitor) { 507 void visitChildren(NodeVisitor visitor) {
450 body.accept(visitor); 508 body.accept(visitor);
451 } 509 }
510
511 LabeledStatement _clone() => new LabeledStatement(label, body);
452 } 512 }
453 513
454 class LiteralStatement extends Statement { 514 class LiteralStatement extends Statement {
455 final String code; 515 final String code;
456 516
457 LiteralStatement(this.code); 517 LiteralStatement(this.code);
458 518
459 accept(NodeVisitor visitor) => visitor.visitLiteralStatement(this); 519 accept(NodeVisitor visitor) => visitor.visitLiteralStatement(this);
460 void visitChildren(NodeVisitor visitor) { } 520 void visitChildren(NodeVisitor visitor) { }
521
522 LiteralStatement _clone() => new LiteralStatement(code);
461 } 523 }
462 524
463 abstract class Expression extends Node { 525 abstract class Expression extends Node {
464 int get precedenceLevel; 526 int get precedenceLevel;
465 527
466 Statement toStatement() => new ExpressionStatement(this); 528 Statement toStatement() => new ExpressionStatement(this);
529
530 Expression withPosition(var sourcePosition, var endSourcePosition) =>
531 super.withPosition(sourcePosition, endSourcePosition);
467 } 532 }
468 533
469 /// Wrap a CodeBuffer as an expression. 534 /// Wrap a CodeBuffer as an expression.
470 class Blob extends Expression { 535 class Blob extends Expression {
471 // TODO(ahe): This class is an aid to convert everything to ASTs, remove when 536 // TODO(ahe): This class is an aid to convert everything to ASTs, remove when
472 // not needed anymore. 537 // not needed anymore.
473 538
474 final leg.CodeBuffer buffer; 539 final leg.CodeBuffer buffer;
475 540
476 Blob(this.buffer); 541 Blob(this.buffer);
477 542
478 accept(NodeVisitor visitor) => visitor.visitBlob(this); 543 accept(NodeVisitor visitor) => visitor.visitBlob(this);
479 544
480 void visitChildren(NodeVisitor visitor) {} 545 void visitChildren(NodeVisitor visitor) {}
481 546
547 Blob _clone() => new Blob(buffer);
548
482 int get precedenceLevel => PRIMARY; 549 int get precedenceLevel => PRIMARY;
550
483 } 551 }
484 552
485 class LiteralExpression extends Expression { 553 class LiteralExpression extends Expression {
486 final String template; 554 final String template;
487 final List<Expression> inputs; 555 final List<Expression> inputs;
488 556
489 LiteralExpression(this.template) : inputs = const []; 557 LiteralExpression(this.template) : inputs = const [];
490 LiteralExpression.withData(this.template, this.inputs); 558 LiteralExpression.withData(this.template, this.inputs);
491 559
492 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this); 560 accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this);
493 561
494 void visitChildren(NodeVisitor visitor) { 562 void visitChildren(NodeVisitor visitor) {
495 if (inputs != null) { 563 if (inputs != null) {
496 for (Expression expr in inputs) expr.accept(visitor); 564 for (Expression expr in inputs) expr.accept(visitor);
497 } 565 }
498 } 566 }
499 567
568 LiteralExpression _clone() => new LiteralExpression(template, inputs);
569
500 // Code that uses JS must take care of operator precedences, and 570 // Code that uses JS must take care of operator precedences, and
501 // put parenthesis if needed. 571 // put parenthesis if needed.
502 int get precedenceLevel => PRIMARY; 572 int get precedenceLevel => PRIMARY;
503 } 573 }
504 574
505 /** 575 /**
506 * [VariableDeclarationList] is a subclass of [Expression] to simplify the 576 * [VariableDeclarationList] is a subclass of [Expression] to simplify the
507 * AST. 577 * AST.
508 */ 578 */
509 class VariableDeclarationList extends Expression { 579 class VariableDeclarationList extends Expression {
510 final List<VariableInitialization> declarations; 580 final List<VariableInitialization> declarations;
511 581
512 VariableDeclarationList(this.declarations); 582 VariableDeclarationList(this.declarations);
513 583
514 accept(NodeVisitor visitor) => visitor.visitVariableDeclarationList(this); 584 accept(NodeVisitor visitor) => visitor.visitVariableDeclarationList(this);
515 585
516 void visitChildren(NodeVisitor visitor) { 586 void visitChildren(NodeVisitor visitor) {
517 for (VariableInitialization declaration in declarations) { 587 for (VariableInitialization declaration in declarations) {
518 declaration.accept(visitor); 588 declaration.accept(visitor);
519 } 589 }
520 } 590 }
521 591
592 VariableDeclarationList _clone() => new VariableDeclarationList(declarations);
593
522 int get precedenceLevel => EXPRESSION; 594 int get precedenceLevel => EXPRESSION;
523 } 595 }
524 596
525 class Sequence extends Expression { 597 class Sequence extends Expression {
526 final List<Expression> expressions; 598 final List<Expression> expressions;
527 599
528 Sequence(this.expressions); 600 Sequence(this.expressions);
529 601
530 accept(NodeVisitor visitor) => visitor.visitSequence(this); 602 accept(NodeVisitor visitor) => visitor.visitSequence(this);
531 603
532 void visitChildren(NodeVisitor visitor) { 604 void visitChildren(NodeVisitor visitor) {
533 for (Expression expr in expressions) expr.accept(visitor); 605 for (Expression expr in expressions) expr.accept(visitor);
534 } 606 }
535 607
608 Sequence _clone() => new Sequence(expressions);
609
536 int get precedenceLevel => EXPRESSION; 610 int get precedenceLevel => EXPRESSION;
537 } 611 }
538 612
539 class Assignment extends Expression { 613 class Assignment extends Expression {
540 final Expression leftHandSide; 614 final Expression leftHandSide;
541 // Null, if the assignment is not compound. 615 // Null, if the assignment is not compound.
542 final VariableReference compoundTarget; 616 final VariableReference compoundTarget;
543 final Expression value; // May be null, for [VariableInitialization]s. 617 final Expression value; // May be null, for [VariableInitialization]s.
544 618
545 Assignment(leftHandSide, value) 619 Assignment(leftHandSide, value)
546 : this._internal(leftHandSide, null, value); 620 : this._internal(leftHandSide, null, value);
547 Assignment.compound(leftHandSide, String op, value) 621 Assignment.compound(leftHandSide, String op, value)
548 : this._internal(leftHandSide, new VariableUse(op), value); 622 : this._internal(leftHandSide, new VariableUse(op), value);
549 Assignment._internal(this.leftHandSide, this.compoundTarget, this.value); 623 Assignment._internal(this.leftHandSide, this.compoundTarget, this.value);
550 624
551 int get precedenceLevel => ASSIGNMENT; 625 int get precedenceLevel => ASSIGNMENT;
552 626
553 bool get isCompound => compoundTarget != null; 627 bool get isCompound => compoundTarget != null;
554 String get op => compoundTarget == null ? null : compoundTarget.name; 628 String get op => compoundTarget == null ? null : compoundTarget.name;
555 629
556 accept(NodeVisitor visitor) => visitor.visitAssignment(this); 630 accept(NodeVisitor visitor) => visitor.visitAssignment(this);
557 631
558 void visitChildren(NodeVisitor visitor) { 632 void visitChildren(NodeVisitor visitor) {
559 leftHandSide.accept(visitor); 633 leftHandSide.accept(visitor);
560 if (compoundTarget != null) compoundTarget.accept(visitor); 634 if (compoundTarget != null) compoundTarget.accept(visitor);
561 if (value != null) value.accept(visitor); 635 if (value != null) value.accept(visitor);
562 } 636 }
637
638 Assignment _clone() =>
639 new Assignment._internal(leftHandSide, compoundTarget, value);
563 } 640 }
564 641
565 class VariableInitialization extends Assignment { 642 class VariableInitialization extends Assignment {
566 /** [value] may be null. */ 643 /** [value] may be null. */
567 VariableInitialization(VariableDeclaration declaration, Expression value) 644 VariableInitialization(VariableDeclaration declaration, Expression value)
568 : super(declaration, value); 645 : super(declaration, value);
569 646
570 VariableDeclaration get declaration => leftHandSide; 647 VariableDeclaration get declaration => leftHandSide;
571 648
572 accept(NodeVisitor visitor) => visitor.visitVariableInitialization(this); 649 accept(NodeVisitor visitor) => visitor.visitVariableInitialization(this);
650
651 VariableInitialization _clone() =>
652 new VariableInitialization(declaration, value);
573 } 653 }
574 654
575 class Conditional extends Expression { 655 class Conditional extends Expression {
576 final Expression condition; 656 final Expression condition;
577 final Expression then; 657 final Expression then;
578 final Expression otherwise; 658 final Expression otherwise;
579 659
580 Conditional(this.condition, this.then, this.otherwise); 660 Conditional(this.condition, this.then, this.otherwise);
581 661
582 accept(NodeVisitor visitor) => visitor.visitConditional(this); 662 accept(NodeVisitor visitor) => visitor.visitConditional(this);
583 663
584 void visitChildren(NodeVisitor visitor) { 664 void visitChildren(NodeVisitor visitor) {
585 condition.accept(visitor); 665 condition.accept(visitor);
586 then.accept(visitor); 666 then.accept(visitor);
587 otherwise.accept(visitor); 667 otherwise.accept(visitor);
588 } 668 }
589 669
670 Conditional _clone() => new Conditional(condition, then, otherwise);
671
590 int get precedenceLevel => ASSIGNMENT; 672 int get precedenceLevel => ASSIGNMENT;
591 } 673 }
592 674
593 class Call extends Expression { 675 class Call extends Expression {
594 Expression target; 676 Expression target;
595 List<Expression> arguments; 677 List<Expression> arguments;
596 678
597 Call(this.target, this.arguments); 679 Call(this.target, this.arguments);
598 680
599 accept(NodeVisitor visitor) => visitor.visitCall(this); 681 accept(NodeVisitor visitor) => visitor.visitCall(this);
600 682
601 void visitChildren(NodeVisitor visitor) { 683 void visitChildren(NodeVisitor visitor) {
602 target.accept(visitor); 684 target.accept(visitor);
603 for (Expression arg in arguments) arg.accept(visitor); 685 for (Expression arg in arguments) arg.accept(visitor);
604 } 686 }
605 687
688 Call _clone() => new Call(target, arguments);
689
606 int get precedenceLevel => CALL; 690 int get precedenceLevel => CALL;
607 } 691 }
608 692
609 class New extends Call { 693 class New extends Call {
610 New(Expression cls, List<Expression> arguments) : super(cls, arguments); 694 New(Expression cls, List<Expression> arguments) : super(cls, arguments);
611 695
612 accept(NodeVisitor visitor) => visitor.visitNew(this); 696 accept(NodeVisitor visitor) => visitor.visitNew(this);
697
698 New _clone() => new New(cls, arguments);
613 } 699 }
614 700
615 class Binary extends Call { 701 class Binary extends Call {
616 Binary(String op, Expression left, Expression right) 702 Binary(String op, Expression left, Expression right)
617 : super(new VariableUse(op), <Expression>[left, right]); 703 : this._internal(new VariableUse(op), <Expression>[left, right]);
704
705 Binary._internal(Expression target, List<Expression> arguments)
706 : super(target, arguments);
618 707
619 String get op { 708 String get op {
620 VariableUse use = target; 709 VariableUse use = target;
621 return use.name; 710 return use.name;
622 } 711 }
623 712
624 Expression get left => arguments[0]; 713 Expression get left => arguments[0];
625 Expression get right => arguments[1]; 714 Expression get right => arguments[1];
626 715
627 accept(NodeVisitor visitor) => visitor.visitBinary(this); 716 accept(NodeVisitor visitor) => visitor.visitBinary(this);
628 717
718 Binary _clone() => new Binary._internal(target, arguments);
719
629 int get precedenceLevel { 720 int get precedenceLevel {
630 // TODO(floitsch): switch to constant map. 721 // TODO(floitsch): switch to constant map.
631 switch (op) { 722 switch (op) {
632 case "*": 723 case "*":
633 case "/": 724 case "/":
634 case "%": 725 case "%":
635 return MULTIPLICATIVE; 726 return MULTIPLICATIVE;
636 case "+": 727 case "+":
637 case "-": 728 case "-":
638 return ADDITIVE; 729 return ADDITIVE;
(...skipping 27 matching lines...) Expand all
666 return EXPRESSION; 757 return EXPRESSION;
667 default: 758 default:
668 throw new leg.CompilerCancelledException( 759 throw new leg.CompilerCancelledException(
669 "Internal Error: Unhandled binary operator: $op"); 760 "Internal Error: Unhandled binary operator: $op");
670 } 761 }
671 } 762 }
672 } 763 }
673 764
674 class Prefix extends Call { 765 class Prefix extends Call {
675 Prefix(String op, Expression arg) 766 Prefix(String op, Expression arg)
676 : super(new VariableUse(op), <Expression>[arg]); 767 : this._internal(new VariableUse(op), <Expression>[arg]);
768
769 Prefix._internal(Expression target, List<xpression> arguments)
floitsch 2014/04/28 12:28:11 Expression.
sra1 2014/04/28 18:24:09 Done.
770 : super(target, arguments);
677 771
678 String get op => (target as VariableUse).name; 772 String get op => (target as VariableUse).name;
679 Expression get argument => arguments[0]; 773 Expression get argument => arguments[0];
680 774
681 accept(NodeVisitor visitor) => visitor.visitPrefix(this); 775 accept(NodeVisitor visitor) => visitor.visitPrefix(this);
682 776
777 Prefix _clone() => new Prefix._internal(target, arguments);
778
683 int get precedenceLevel => UNARY; 779 int get precedenceLevel => UNARY;
684 } 780 }
685 781
686 class Postfix extends Call { 782 class Postfix extends Call {
687 Postfix(String op, Expression arg) 783 Postfix(String op, Expression arg)
688 : super(new VariableUse(op), <Expression>[arg]); 784 : this._internal(new VariableUse(op), <Expression>[arg]);
785
786 Postfix._internal(Expression target, List<xpression> arguments)
floitsch 2014/04/28 12:28:11 Expression
sra1 2014/04/28 18:24:09 Done.
787 : super(target, arguments);
689 788
690 String get op => (target as VariableUse).name; 789 String get op => (target as VariableUse).name;
691 Expression get argument => arguments[0]; 790 Expression get argument => arguments[0];
692 791
693 accept(NodeVisitor visitor) => visitor.visitPostfix(this); 792 accept(NodeVisitor visitor) => visitor.visitPostfix(this);
694 793
794 Prefix _clone() => new Postfix._internal(target, arguments);
795
695 int get precedenceLevel => UNARY; 796 int get precedenceLevel => UNARY;
696 } 797 }
697 798
698 abstract class VariableReference extends Expression { 799 abstract class VariableReference extends Expression {
699 final String name; 800 final String name;
700 801
701 // We treat operators as if they were special functions. They can thus be 802 // We treat operators as if they were special functions. They can thus be
702 // referenced like other variables. 803 // referenced like other variables.
703 VariableReference(this.name); 804 VariableReference(this.name);
704 805
705 accept(NodeVisitor visitor); 806 accept(NodeVisitor visitor);
706 int get precedenceLevel => PRIMARY; 807 int get precedenceLevel => PRIMARY;
707 void visitChildren(NodeVisitor visitor) {} 808 void visitChildren(NodeVisitor visitor) {}
708 } 809 }
709 810
710 class VariableUse extends VariableReference { 811 class VariableUse extends VariableReference {
711 VariableUse(String name) : super(name); 812 VariableUse(String name) : super(name);
712 813
713 accept(NodeVisitor visitor) => visitor.visitVariableUse(this); 814 accept(NodeVisitor visitor) => visitor.visitVariableUse(this);
815 VariableUse _clone() => new VariableUse(name);
714 816
715 VariableUse asVariableUse() => this; 817 VariableUse asVariableUse() => this;
818
819 toString() => 'VariableUse($name)';
716 } 820 }
717 821
718 class VariableDeclaration extends VariableReference { 822 class VariableDeclaration extends VariableReference {
719 VariableDeclaration(String name) : super(name); 823 VariableDeclaration(String name) : super(name);
720 824
721 accept(NodeVisitor visitor) => visitor.visitVariableDeclaration(this); 825 accept(NodeVisitor visitor) => visitor.visitVariableDeclaration(this);
826 VariableDeclaration _clone() => new VariableDeclaration(name);
722 } 827 }
723 828
724 class Parameter extends VariableDeclaration { 829 class Parameter extends VariableDeclaration {
725 Parameter(String id) : super(id); 830 Parameter(String id) : super(id);
726 831
727 accept(NodeVisitor visitor) => visitor.visitParameter(this); 832 accept(NodeVisitor visitor) => visitor.visitParameter(this);
833 Parameter _clone() => new Parameter(name);
728 } 834 }
729 835
730 class This extends Parameter { 836 class This extends Parameter {
731 This() : super("this"); 837 This() : super("this");
732 838
733 accept(NodeVisitor visitor) => visitor.visitThis(this); 839 accept(NodeVisitor visitor) => visitor.visitThis(this);
840 This _clone() => new This();
734 } 841 }
735 842
736 class NamedFunction extends Expression { 843 class NamedFunction extends Expression {
737 final VariableDeclaration name; 844 final VariableDeclaration name;
738 final Fun function; 845 final Fun function;
739 846
740 NamedFunction(this.name, this.function); 847 NamedFunction(this.name, this.function);
741 848
742 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); 849 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this);
743 850
744 void visitChildren(NodeVisitor visitor) { 851 void visitChildren(NodeVisitor visitor) {
745 name.accept(visitor); 852 name.accept(visitor);
746 function.accept(visitor); 853 function.accept(visitor);
747 } 854 }
855 NamedFunction _clone() => new NamedFunction(name, function);
748 856
749 int get precedenceLevel => CALL; 857 int get precedenceLevel => CALL;
750 } 858 }
751 859
752 class Fun extends Expression { 860 class Fun extends Expression {
753 final List<Parameter> params; 861 final List<Parameter> params;
754 final Block body; 862 final Block body;
755 863
756 Fun(this.params, this.body); 864 Fun(this.params, this.body);
757 865
758 accept(NodeVisitor visitor) => visitor.visitFun(this); 866 accept(NodeVisitor visitor) => visitor.visitFun(this);
759 867
760 void visitChildren(NodeVisitor visitor) { 868 void visitChildren(NodeVisitor visitor) {
761 for (Parameter param in params) param.accept(visitor); 869 for (Parameter param in params) param.accept(visitor);
762 body.accept(visitor); 870 body.accept(visitor);
763 } 871 }
764 872
873 Fun _clone() => new Fun(params, body);
874
765 int get precedenceLevel => CALL; 875 int get precedenceLevel => CALL;
766 } 876 }
767 877
768 class PropertyAccess extends Expression { 878 class PropertyAccess extends Expression {
769 final Expression receiver; 879 final Expression receiver;
770 final Expression selector; 880 final Expression selector;
771 881
772 PropertyAccess(this.receiver, this.selector); 882 PropertyAccess(this.receiver, this.selector);
773 PropertyAccess.field(this.receiver, String fieldName) 883 PropertyAccess.field(this.receiver, String fieldName)
774 : selector = new LiteralString('"$fieldName"'); 884 : selector = new LiteralString('"$fieldName"');
775 PropertyAccess.indexed(this.receiver, int index) 885 PropertyAccess.indexed(this.receiver, int index)
776 : selector = new LiteralNumber('$index'); 886 : selector = new LiteralNumber('$index');
777 887
778 accept(NodeVisitor visitor) => visitor.visitAccess(this); 888 accept(NodeVisitor visitor) => visitor.visitAccess(this);
779 889
780 void visitChildren(NodeVisitor visitor) { 890 void visitChildren(NodeVisitor visitor) {
781 receiver.accept(visitor); 891 receiver.accept(visitor);
782 selector.accept(visitor); 892 selector.accept(visitor);
783 } 893 }
784 894
895 PropertyAccess _clone() => new PropertyAccess(receiver, selector);
896
785 int get precedenceLevel => CALL; 897 int get precedenceLevel => CALL;
786 } 898 }
787 899
788 abstract class Literal extends Expression { 900 abstract class Literal extends Expression {
789 void visitChildren(NodeVisitor visitor) {} 901 void visitChildren(NodeVisitor visitor) {}
790 902
791 int get precedenceLevel => PRIMARY; 903 int get precedenceLevel => PRIMARY;
792 } 904 }
793 905
794 class LiteralBool extends Literal { 906 class LiteralBool extends Literal {
795 final bool value; 907 final bool value;
796 908
797 LiteralBool(this.value); 909 LiteralBool(this.value);
798 910
799 accept(NodeVisitor visitor) => visitor.visitLiteralBool(this); 911 accept(NodeVisitor visitor) => visitor.visitLiteralBool(this);
800 // [visitChildren] inherited from [Literal]. 912 // [visitChildren] inherited from [Literal].
913 LiteralBool _clone() => new LiteralBool(value);
801 } 914 }
802 915
803 class LiteralNull extends Literal { 916 class LiteralNull extends Literal {
804 LiteralNull(); 917 LiteralNull();
805 918
806 accept(NodeVisitor visitor) => visitor.visitLiteralNull(this); 919 accept(NodeVisitor visitor) => visitor.visitLiteralNull(this);
920 LiteralNull _clone() => new LiteralNull();
807 } 921 }
808 922
809 class LiteralString extends Literal { 923 class LiteralString extends Literal {
810 final String value; 924 final String value;
811 925
812 /** 926 /**
813 * Constructs a LiteralString from a string value. 927 * Constructs a LiteralString from a string value.
814 * 928 *
815 * The constructor does not add the required quotes. If [value] is 929 * The constructor does not add the required quotes. If [value] is
816 * not surrounded by quotes, the resulting object is invalid as a JS 930 * not surrounded by quotes, the resulting object is invalid as a JS
817 * value. 931 * value.
818 */ 932 */
819 LiteralString(this.value); 933 LiteralString(this.value);
820 934
821 accept(NodeVisitor visitor) => visitor.visitLiteralString(this); 935 accept(NodeVisitor visitor) => visitor.visitLiteralString(this);
936 LiteralString _clone() => new LiteralString(value);
822 } 937 }
823 938
824 class LiteralNumber extends Literal { 939 class LiteralNumber extends Literal {
825 final String value; 940 final String value;
826 941
827 LiteralNumber(this.value); 942 LiteralNumber(this.value);
828 943
829 accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this); 944 accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this);
945 LiteralNumber _clone() => new LiteralNumber(value);
830 } 946 }
831 947
832 class ArrayInitializer extends Expression { 948 class ArrayInitializer extends Expression {
833 final int length; 949 final int length;
834 // We represent the array as sparse list of elements. Each element knows its 950 // We represent the array as sparse list of elements. Each element knows its
835 // position in the array. 951 // position in the array.
836 final List<ArrayElement> elements; 952 final List<ArrayElement> elements;
837 953
838 ArrayInitializer(this.length, this.elements); 954 ArrayInitializer(this.length, this.elements);
839 955
840 factory ArrayInitializer.from(Iterable<Expression> expressions) => 956 factory ArrayInitializer.from(Iterable<Expression> expressions) =>
841 new ArrayInitializer(expressions.length, _convert(expressions)); 957 new ArrayInitializer(expressions.length, _convert(expressions));
842 958
843 accept(NodeVisitor visitor) => visitor.visitArrayInitializer(this); 959 accept(NodeVisitor visitor) => visitor.visitArrayInitializer(this);
844 960
845 void visitChildren(NodeVisitor visitor) { 961 void visitChildren(NodeVisitor visitor) {
846 for (ArrayElement element in elements) element.accept(visitor); 962 for (ArrayElement element in elements) element.accept(visitor);
847 } 963 }
848 964
965 ArrayInitializer _clone() => new ArrayInitializer(length, elements);
966
849 int get precedenceLevel => PRIMARY; 967 int get precedenceLevel => PRIMARY;
850 968
851 static List<ArrayElement> _convert(Iterable<Expression> expressions) { 969 static List<ArrayElement> _convert(Iterable<Expression> expressions) {
852 int index = 0; 970 int index = 0;
853 return expressions.map( 971 return expressions.map(
854 (expression) => new ArrayElement(index++, expression)) 972 (expression) => new ArrayElement(index++, expression))
855 .toList(); 973 .toList();
856 } 974 }
857 } 975 }
858 976
859 /** 977 /**
860 * An expression inside an [ArrayInitializer]. An [ArrayElement] knows 978 * An expression inside an [ArrayInitializer]. An [ArrayElement] knows
861 * its position in the containing [ArrayInitializer]. 979 * its position in the containing [ArrayInitializer].
862 */ 980 */
863 class ArrayElement extends Node { 981 class ArrayElement extends Node {
864 int index; 982 final int index;
865 Expression value; 983 final Expression value;
866 984
867 ArrayElement(this.index, this.value); 985 ArrayElement(this.index, this.value);
868 986
869 accept(NodeVisitor visitor) => visitor.visitArrayElement(this); 987 accept(NodeVisitor visitor) => visitor.visitArrayElement(this);
870 988
871 void visitChildren(NodeVisitor visitor) { 989 void visitChildren(NodeVisitor visitor) {
872 value.accept(visitor); 990 value.accept(visitor);
873 } 991 }
992
993 ArrayElement _clone() => new ArrayElement(index, value);
874 } 994 }
875 995
876 class ObjectInitializer extends Expression { 996 class ObjectInitializer extends Expression {
877 List<Property> properties; 997 final List<Property> properties;
878 bool isOneLiner; 998 final bool isOneLiner;
879 999
880 /** 1000 /**
881 * Constructs a new object-initializer containing the given [properties]. 1001 * Constructs a new object-initializer containing the given [properties].
882 * 1002 *
883 * [isOneLiner] describes the behaviour when pretty-printing (non-minified). 1003 * [isOneLiner] describes the behaviour when pretty-printing (non-minified).
884 * If true print all properties on the same line. 1004 * If true print all properties on the same line.
885 * If false print each property on a seperate line. 1005 * If false print each property on a seperate line.
886 */ 1006 */
887 ObjectInitializer(this.properties, {this.isOneLiner: true}); 1007 ObjectInitializer(this.properties, {this.isOneLiner: true});
888 1008
889 accept(NodeVisitor visitor) => visitor.visitObjectInitializer(this); 1009 accept(NodeVisitor visitor) => visitor.visitObjectInitializer(this);
890 1010
891 void visitChildren(NodeVisitor visitor) { 1011 void visitChildren(NodeVisitor visitor) {
892 for (Property init in properties) init.accept(visitor); 1012 for (Property init in properties) init.accept(visitor);
893 } 1013 }
894 1014
1015 ObjectInitializer _clone() =>
1016 new ObjectInitializer(properties, isOneLiner: isOneLiner);
1017
895 int get precedenceLevel => PRIMARY; 1018 int get precedenceLevel => PRIMARY;
896 } 1019 }
897 1020
898 class Property extends Node { 1021 class Property extends Node {
899 Literal name; 1022 final Literal name;
900 Expression value; 1023 final Expression value;
901 1024
902 Property(this.name, this.value); 1025 Property(this.name, this.value);
903 1026
904 accept(NodeVisitor visitor) => visitor.visitProperty(this); 1027 accept(NodeVisitor visitor) => visitor.visitProperty(this);
905 1028
906 void visitChildren(NodeVisitor visitor) { 1029 void visitChildren(NodeVisitor visitor) {
907 name.accept(visitor); 1030 name.accept(visitor);
908 value.accept(visitor); 1031 value.accept(visitor);
909 } 1032 }
1033
1034 Property _clone() => new Property(name, value);
910 } 1035 }
911 1036
912 /// Tag class for all interpolated positions. 1037 /// Tag class for all interpolated positions.
913 abstract class InterpolatedNode implements Node { 1038 abstract class InterpolatedNode implements Node {
914 get name; // 'int' for positional interpolated nodes, 'String' for named. 1039 get name; // 'int' for positional interpolated nodes, 'String' for named.
915 } 1040 }
916 1041
917 class InterpolatedExpression extends Expression implements InterpolatedNode { 1042 class InterpolatedExpression extends Expression implements InterpolatedNode {
918 final name; 1043 final name;
919 1044
920 InterpolatedExpression(this.name); 1045 InterpolatedExpression(this.name);
921 1046
922 accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this); 1047 accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this);
923 void visitChildren(NodeVisitor visitor) {} 1048 void visitChildren(NodeVisitor visitor) {}
1049 InterpolatedExpression _clone() => new InterpolatedExpression(name);
924 1050
925 int get precedenceLevel => PRIMARY; 1051 int get precedenceLevel => PRIMARY;
926 } 1052 }
927 1053
928 class InterpolatedLiteral extends Literal implements InterpolatedNode { 1054 class InterpolatedLiteral extends Literal implements InterpolatedNode {
929 final name; 1055 final name;
930 1056
931 InterpolatedLiteral(this.name); 1057 InterpolatedLiteral(this.name);
932 1058
933 accept(NodeVisitor visitor) => visitor.visitInterpolatedLiteral(this); 1059 accept(NodeVisitor visitor) => visitor.visitInterpolatedLiteral(this);
934 void visitChildren(NodeVisitor visitor) {} 1060 void visitChildren(NodeVisitor visitor) {}
1061 InterpolatedLiteral _clone() => new InterpolatedLiteral(name);
935 } 1062 }
936 1063
937 class InterpolatedParameter extends Expression 1064 class InterpolatedParameter extends Expression
938 implements Parameter, InterpolatedNode { 1065 implements Parameter, InterpolatedNode {
939 final name; 1066 final name;
940 1067
941 InterpolatedParameter(this.name); 1068 InterpolatedParameter(this.name);
942 1069
943 accept(NodeVisitor visitor) => visitor.visitInterpolatedParameter(this); 1070 accept(NodeVisitor visitor) => visitor.visitInterpolatedParameter(this);
944 void visitChildren(NodeVisitor visitor) {} 1071 void visitChildren(NodeVisitor visitor) {}
1072 InterpolatedParameter _clone() => new InterpolatedParameter(name);
945 1073
946 int get precedenceLevel => PRIMARY; 1074 int get precedenceLevel => PRIMARY;
947 } 1075 }
948 1076
949 class InterpolatedSelector extends Expression implements InterpolatedNode { 1077 class InterpolatedSelector extends Expression implements InterpolatedNode {
950 final name; 1078 final name;
951 1079
952 InterpolatedSelector(this.name); 1080 InterpolatedSelector(this.name);
953 1081
954 accept(NodeVisitor visitor) => visitor.visitInterpolatedSelector(this); 1082 accept(NodeVisitor visitor) => visitor.visitInterpolatedSelector(this);
955 void visitChildren(NodeVisitor visitor) {} 1083 void visitChildren(NodeVisitor visitor) {}
1084 InterpolatedSelector _clone() => new InterpolatedSelector(name);
956 1085
957 int get precedenceLevel => PRIMARY; 1086 int get precedenceLevel => PRIMARY;
958 } 1087 }
959 1088
960 class InterpolatedStatement extends Statement implements InterpolatedNode { 1089 class InterpolatedStatement extends Statement implements InterpolatedNode {
961 final name; 1090 final name;
962 1091
963 InterpolatedStatement(this.name); 1092 InterpolatedStatement(this.name);
964 1093
965 accept(NodeVisitor visitor) => visitor.visitInterpolatedStatement(this); 1094 accept(NodeVisitor visitor) => visitor.visitInterpolatedStatement(this);
966 void visitChildren(NodeVisitor visitor) {} 1095 void visitChildren(NodeVisitor visitor) {}
1096 InterpolatedStatement _clone() => new InterpolatedStatement(name);
967 } 1097 }
968 1098
969 /** 1099 /**
970 * [RegExpLiteral]s, despite being called "Literal", do not inherit from 1100 * [RegExpLiteral]s, despite being called "Literal", do not inherit from
971 * [Literal]. Indeed, regular expressions in JavaScript have a side-effect and 1101 * [Literal]. Indeed, regular expressions in JavaScript have a side-effect and
972 * are thus not in the same category as numbers or strings. 1102 * are thus not in the same category as numbers or strings.
973 */ 1103 */
974 class RegExpLiteral extends Expression { 1104 class RegExpLiteral extends Expression {
975 /** Contains the pattern and the flags.*/ 1105 /** Contains the pattern and the flags.*/
976 String pattern; 1106 final String pattern;
977 1107
978 RegExpLiteral(this.pattern); 1108 RegExpLiteral(this.pattern);
979 1109
980 accept(NodeVisitor visitor) => visitor.visitRegExpLiteral(this); 1110 accept(NodeVisitor visitor) => visitor.visitRegExpLiteral(this);
981 void visitChildren(NodeVisitor visitor) {} 1111 void visitChildren(NodeVisitor visitor) {}
1112 RegExpLiteral _clone() => new RegExpLiteral(pattern);
982 1113
983 int get precedenceLevel => PRIMARY; 1114 int get precedenceLevel => PRIMARY;
984 } 1115 }
985 1116
986 /** 1117 /**
987 * A comment. 1118 * A comment.
988 * 1119 *
989 * Extends [Statement] so we can add comments before statements in 1120 * Extends [Statement] so we can add comments before statements in
990 * [Block] and [Program]. 1121 * [Block] and [Program].
991 */ 1122 */
992 class Comment extends Statement { 1123 class Comment extends Statement {
993 final String comment; 1124 final String comment;
994 1125
995 Comment(this.comment); 1126 Comment(this.comment);
996 1127
997 accept(NodeVisitor visitor) => visitor.visitComment(this); 1128 accept(NodeVisitor visitor) => visitor.visitComment(this);
1129 Comment _clone() => new Comment(comment);
998 1130
999 void visitChildren(NodeVisitor visitor) {} 1131 void visitChildren(NodeVisitor visitor) {}
1000 } 1132 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698