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

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

Powered by Google App Engine
This is Rietveld 408576698