| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |