| 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 tree; | 5 part of tree; |
| 6 | 6 |
| 7 abstract class Visitor<R> { | 7 abstract class Visitor<R> { |
| 8 const Visitor(); | 8 const Visitor(); |
| 9 | 9 |
| 10 R visitNode(Node node); | 10 R visitNode(Node node); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 Send asSend() => this; | 281 Send asSend() => this; |
| 282 | 282 |
| 283 accept(Visitor visitor) => visitor.visitSend(this); | 283 accept(Visitor visitor) => visitor.visitSend(this); |
| 284 | 284 |
| 285 visitChildren(Visitor visitor) { | 285 visitChildren(Visitor visitor) { |
| 286 if (receiver != null) receiver.accept(visitor); | 286 if (receiver != null) receiver.accept(visitor); |
| 287 if (selector != null) selector.accept(visitor); | 287 if (selector != null) selector.accept(visitor); |
| 288 if (argumentsNode != null) argumentsNode.accept(visitor); | 288 if (argumentsNode != null) argumentsNode.accept(visitor); |
| 289 } | 289 } |
| 290 | 290 |
| 291 int argumentCount() => (argumentsNode == null) ? -1 : argumentsNode.length; | 291 int argumentCount() { |
| 292 return (argumentsNode == null) ? -1 : argumentsNode.slowLength(); |
| 293 } |
| 292 | 294 |
| 293 bool get isSuperCall { | 295 bool get isSuperCall { |
| 294 return receiver != null && | 296 return receiver != null && |
| 295 receiver.asIdentifier() != null && | 297 receiver.asIdentifier() != null && |
| 296 receiver.asIdentifier().isSuper(); | 298 receiver.asIdentifier().isSuper(); |
| 297 } | 299 } |
| 298 bool get isOperator => selector is Operator; | 300 bool get isOperator => selector is Operator; |
| 299 bool get isPropertyAccess => argumentsNode == null; | 301 bool get isPropertyAccess => argumentsNode == null; |
| 300 bool get isFunctionObjectInvocation => selector == null; | 302 bool get isFunctionObjectInvocation => selector == null; |
| 301 bool get isPrefix => argumentsNode is Prefix; | 303 bool get isPrefix => argumentsNode is Prefix; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 bool isConst() { | 405 bool isConst() { |
| 404 return identical(newToken.stringValue, 'const') | 406 return identical(newToken.stringValue, 'const') |
| 405 || identical(newToken.stringValue, '@'); | 407 || identical(newToken.stringValue, '@'); |
| 406 } | 408 } |
| 407 | 409 |
| 408 Token getBeginToken() => newToken; | 410 Token getBeginToken() => newToken; |
| 409 | 411 |
| 410 Token getEndToken() => send.getEndToken(); | 412 Token getEndToken() => send.getEndToken(); |
| 411 } | 413 } |
| 412 | 414 |
| 413 class NodeList extends Node implements Iterable<Node> { | 415 class NodeList extends Node { |
| 414 final Link<Node> nodes; | 416 final Link<Node> nodes; |
| 415 final Token beginToken; | 417 final Token beginToken; |
| 416 final Token endToken; | 418 final Token endToken; |
| 417 final SourceString delimiter; | 419 final SourceString delimiter; |
| 418 bool get isEmpty => nodes.isEmpty; | 420 bool get isEmpty => nodes.isEmpty; |
| 419 | 421 |
| 420 NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]); | 422 NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]); |
| 421 | 423 |
| 422 Iterator<Node> get iterator => nodes.iterator; | 424 Iterator<Node> get iterator => nodes.iterator; |
| 423 | 425 |
| 424 NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node)); | 426 NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node)); |
| 425 NodeList.empty() : this(null, const Link<Node>()); | 427 NodeList.empty() : this(null, const Link<Node>()); |
| 426 | 428 |
| 427 NodeList asNodeList() => this; | 429 NodeList asNodeList() => this; |
| 428 | 430 |
| 429 int get length { | 431 int slowLength() { |
| 430 int result = 0; | 432 int result = 0; |
| 431 for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) { | 433 for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) { |
| 432 result++; | 434 result++; |
| 433 } | 435 } |
| 434 return result; | 436 return result; |
| 435 } | 437 } |
| 436 | 438 |
| 437 accept(Visitor visitor) => visitor.visitNodeList(this); | 439 accept(Visitor visitor) => visitor.visitNodeList(this); |
| 438 | 440 |
| 439 visitChildren(Visitor visitor) { | 441 visitChildren(Visitor visitor) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 462 if (endToken != null) return endToken; | 464 if (endToken != null) return endToken; |
| 463 if (nodes != null) { | 465 if (nodes != null) { |
| 464 Link<Node> link = nodes; | 466 Link<Node> link = nodes; |
| 465 if (link.isEmpty) return beginToken; | 467 if (link.isEmpty) return beginToken; |
| 466 while (!link.tail.isEmpty) link = link.tail; | 468 while (!link.tail.isEmpty) link = link.tail; |
| 467 if (link.head.getEndToken() != null) return link.head.getEndToken(); | 469 if (link.head.getEndToken() != null) return link.head.getEndToken(); |
| 468 if (link.head.getBeginToken() != null) return link.head.getBeginToken(); | 470 if (link.head.getBeginToken() != null) return link.head.getBeginToken(); |
| 469 } | 471 } |
| 470 return beginToken; | 472 return beginToken; |
| 471 } | 473 } |
| 472 | |
| 473 // ------------------- Iterable methods ------------------------------------- | |
| 474 // | |
| 475 // TODO(floitsch): these functions should be pulled in through a mixin | |
| 476 // mechanism. | |
| 477 Iterable mappedBy(f(Node element)) => new MappedIterable(this, f); | |
| 478 | |
| 479 Iterable<Node> where(bool f(Node element)) | |
| 480 => new WhereIterable<Node>(this, f); | |
| 481 | |
| 482 bool contains(Node element) { | |
| 483 for (Node e in this) { | |
| 484 if (e == element) return true; | |
| 485 } | |
| 486 return false; | |
| 487 } | |
| 488 | |
| 489 void forEach(void f(Node element)) { | |
| 490 for (Node element in this) f(element); | |
| 491 } | |
| 492 | |
| 493 String join([String separator]) => Collections.join(this, separator); | |
| 494 | |
| 495 dynamic reduce(var initialValue, | |
| 496 dynamic combine(var previousValue, Node element)) { | |
| 497 var value = initialValue; | |
| 498 for (Node element in this) value = combine(value, element); | |
| 499 return value; | |
| 500 } | |
| 501 | |
| 502 bool every(bool f(Node element)) { | |
| 503 for (Node element in this) { | |
| 504 if (!f(element)) return false; | |
| 505 } | |
| 506 return true; | |
| 507 } | |
| 508 | |
| 509 bool any(bool f(Node element)) { | |
| 510 for (Node element in this) { | |
| 511 if (f(element)) return true; | |
| 512 } | |
| 513 return false; | |
| 514 } | |
| 515 | |
| 516 List<Node> toList() => new List<Node>.from(this); | |
| 517 | |
| 518 Set<Node> toSet() => new Set<Node>.from(this); | |
| 519 | |
| 520 Iterable<Node> take(int n) => new TakeIterable<Node>(this, n); | |
| 521 | |
| 522 Iterable<Node> takeWhile(bool test(Node value)) { | |
| 523 return new TakeWhileIterable<Node>(this, test); | |
| 524 } | |
| 525 | |
| 526 Iterable<Node> skip(int n) => new SkipIterable<Node>(this, n); | |
| 527 | |
| 528 Iterable<Node> skipWhile(bool test(Node value)) { | |
| 529 return new SkipWhileIterable<Node>(this, test); | |
| 530 } | |
| 531 | |
| 532 Node get first { | |
| 533 return Collections.first(this); | |
| 534 } | |
| 535 | |
| 536 Node get last { | |
| 537 return Collections.last(this); | |
| 538 } | |
| 539 | |
| 540 Node get single { | |
| 541 return Collections.single(this); | |
| 542 } | |
| 543 | |
| 544 Node min([int compare(Node a, Node b)]) => Collections.min(this, compare); | |
| 545 | |
| 546 Node max([int compare(Node a, Node b)]) => Collections.max(this, compare); | |
| 547 | |
| 548 Node firstMatching(bool test(Node value), {Node orElse()}) { | |
| 549 return Collections.firstMatching(this, test, orElse); | |
| 550 } | |
| 551 | |
| 552 Node lastMatching(bool test(Node value), {Node orElse()}) { | |
| 553 return Collections.lastMatching(this, test, orElse); | |
| 554 } | |
| 555 | |
| 556 Node singleMatching(bool test(Node value)) { | |
| 557 return Collections.singleMatching(this, test); | |
| 558 } | |
| 559 | |
| 560 Node elementAt(int index) { | |
| 561 return Collections.elementAt(this, index); | |
| 562 } | |
| 563 } | 474 } |
| 564 | 475 |
| 565 class Block extends Statement { | 476 class Block extends Statement { |
| 566 final NodeList statements; | 477 final NodeList statements; |
| 567 | 478 |
| 568 Block(this.statements); | 479 Block(this.statements); |
| 569 | 480 |
| 570 Block asBlock() => this; | 481 Block asBlock() => this; |
| 571 | 482 |
| 572 accept(Visitor visitor) => visitor.visitBlock(this); | 483 accept(Visitor visitor) => visitor.visitBlock(this); |
| (...skipping 1516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 * argument). | 2000 * argument). |
| 2090 * | 2001 * |
| 2091 * TODO(ahe): This method is controversial, the team needs to discuss | 2002 * TODO(ahe): This method is controversial, the team needs to discuss |
| 2092 * if top-level methods are acceptable and what naming conventions to | 2003 * if top-level methods are acceptable and what naming conventions to |
| 2093 * use. | 2004 * use. |
| 2094 */ | 2005 */ |
| 2095 initializerDo(Node node, f(Node node)) { | 2006 initializerDo(Node node, f(Node node)) { |
| 2096 SendSet send = node.asSendSet(); | 2007 SendSet send = node.asSendSet(); |
| 2097 if (send != null) return f(send.arguments.head); | 2008 if (send != null) return f(send.arguments.head); |
| 2098 } | 2009 } |
| OLD | NEW |