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