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 abstract class Visitor<R> { | 5 abstract class Visitor<R> { |
6 const Visitor(); | 6 const Visitor(); |
7 | 7 |
8 abstract R visitNode(Node node); | 8 abstract R visitNode(Node node); |
9 | 9 |
10 R visitBlock(Block node) => visitStatement(node); | 10 R visitBlock(Block node) => visitStatement(node); |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 Token getBeginToken() => newToken; | 425 Token getBeginToken() => newToken; |
426 | 426 |
427 Token getEndToken() => send.getEndToken(); | 427 Token getEndToken() => send.getEndToken(); |
428 } | 428 } |
429 | 429 |
430 class NodeList extends Node implements Iterable<Node> { | 430 class NodeList extends Node implements Iterable<Node> { |
431 final Link<Node> nodes; | 431 final Link<Node> nodes; |
432 final Token beginToken; | 432 final Token beginToken; |
433 final Token endToken; | 433 final Token endToken; |
434 final SourceString delimiter; | 434 final SourceString delimiter; |
435 bool isEmpty() => nodes.isEmpty(); | 435 bool get isEmpty => nodes.isEmpty; |
436 | 436 |
437 NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]); | 437 NodeList([this.beginToken, this.nodes, this.endToken, this.delimiter]); |
438 | 438 |
439 Iterator<Node> iterator() => nodes.iterator(); | 439 Iterator<Node> iterator() => nodes.iterator(); |
440 | 440 |
441 NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node)); | 441 NodeList.singleton(Node node) : this(null, const Link<Node>().prepend(node)); |
442 NodeList.empty() : this(null, const Link<Node>()); | 442 NodeList.empty() : this(null, const Link<Node>()); |
443 | 443 |
444 NodeList asNodeList() => this; | 444 NodeList asNodeList() => this; |
445 | 445 |
446 int length() { | 446 int length() { |
447 int result = 0; | 447 int result = 0; |
448 for (Link<Node> cursor = nodes; !cursor.isEmpty(); cursor = cursor.tail) { | 448 for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) { |
449 result++; | 449 result++; |
450 } | 450 } |
451 return result; | 451 return result; |
452 } | 452 } |
453 | 453 |
454 accept(Visitor visitor) => visitor.visitNodeList(this); | 454 accept(Visitor visitor) => visitor.visitNodeList(this); |
455 | 455 |
456 visitChildren(Visitor visitor) { | 456 visitChildren(Visitor visitor) { |
457 if (nodes == null) return; | 457 if (nodes == null) return; |
458 for (Link<Node> link = nodes; !link.isEmpty(); link = link.tail) { | 458 for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) { |
459 if (link.head != null) link.head.accept(visitor); | 459 if (link.head != null) link.head.accept(visitor); |
460 } | 460 } |
461 } | 461 } |
462 | 462 |
463 Token getBeginToken() { | 463 Token getBeginToken() { |
464 if (beginToken != null) return beginToken; | 464 if (beginToken != null) return beginToken; |
465 if (nodes != null) { | 465 if (nodes != null) { |
466 for (Link<Node> link = nodes; !link.isEmpty(); link = link.tail) { | 466 for (Link<Node> link = nodes; !link.isEmpty; link = link.tail) { |
467 if (link.head.getBeginToken() != null) { | 467 if (link.head.getBeginToken() != null) { |
468 return link.head.getBeginToken(); | 468 return link.head.getBeginToken(); |
469 } | 469 } |
470 if (link.head.getEndToken() != null) { | 470 if (link.head.getEndToken() != null) { |
471 return link.head.getEndToken(); | 471 return link.head.getEndToken(); |
472 } | 472 } |
473 } | 473 } |
474 } | 474 } |
475 return endToken; | 475 return endToken; |
476 } | 476 } |
477 | 477 |
478 Token getEndToken() { | 478 Token getEndToken() { |
479 if (endToken != null) return endToken; | 479 if (endToken != null) return endToken; |
480 if (nodes != null) { | 480 if (nodes != null) { |
481 Link<Node> link = nodes; | 481 Link<Node> link = nodes; |
482 if (link.isEmpty()) return beginToken; | 482 if (link.isEmpty) return beginToken; |
483 while (!link.tail.isEmpty()) link = link.tail; | 483 while (!link.tail.isEmpty) link = link.tail; |
484 if (link.head.getEndToken() != null) return link.head.getEndToken(); | 484 if (link.head.getEndToken() != null) return link.head.getEndToken(); |
485 if (link.head.getBeginToken() != null) return link.head.getBeginToken(); | 485 if (link.head.getBeginToken() != null) return link.head.getBeginToken(); |
486 } | 486 } |
487 return beginToken; | 487 return beginToken; |
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 class Block extends Statement { | 491 class Block extends Statement { |
492 final NodeList statements; | 492 final NodeList statements; |
493 | 493 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 if (name != null) name.accept(visitor); | 652 if (name != null) name.accept(visitor); |
653 if (parameters != null) parameters.accept(visitor); | 653 if (parameters != null) parameters.accept(visitor); |
654 if (initializers != null) initializers.accept(visitor); | 654 if (initializers != null) initializers.accept(visitor); |
655 if (body != null) body.accept(visitor); | 655 if (body != null) body.accept(visitor); |
656 } | 656 } |
657 | 657 |
658 bool hasBody() { | 658 bool hasBody() { |
659 // TODO(karlklose,ahe): refactor AST nodes (issue 1713). | 659 // TODO(karlklose,ahe): refactor AST nodes (issue 1713). |
660 if (body.asReturn() != null) return true; | 660 if (body.asReturn() != null) return true; |
661 NodeList statements = body.asBlock().statements; | 661 NodeList statements = body.asBlock().statements; |
662 return (!statements.nodes.isEmpty() || | 662 return (!statements.nodes.isEmpty || |
663 !identical(statements.getBeginToken().kind, $SEMICOLON)); | 663 !identical(statements.getBeginToken().kind, $SEMICOLON)); |
664 } | 664 } |
665 | 665 |
666 Token getBeginToken() { | 666 Token getBeginToken() { |
667 Token token = firstBeginToken(modifiers, returnType); | 667 Token token = firstBeginToken(modifiers, returnType); |
668 if (token != null) return token; | 668 if (token != null) return token; |
669 if (getOrSet != null) return getOrSet; | 669 if (getOrSet != null) return getOrSet; |
670 return firstBeginToken(name, parameters); | 670 return firstBeginToken(name, parameters); |
671 } | 671 } |
672 | 672 |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 static const int FLAG_CONST = FLAG_VAR << 1; | 1151 static const int FLAG_CONST = FLAG_VAR << 1; |
1152 static const int FLAG_FACTORY = FLAG_CONST << 1; | 1152 static const int FLAG_FACTORY = FLAG_CONST << 1; |
1153 static const int FLAG_EXTERNAL = FLAG_FACTORY << 1; | 1153 static const int FLAG_EXTERNAL = FLAG_FACTORY << 1; |
1154 | 1154 |
1155 Modifiers(NodeList nodes) : this.withFlags(nodes, computeFlags(nodes.nodes)); | 1155 Modifiers(NodeList nodes) : this.withFlags(nodes, computeFlags(nodes.nodes)); |
1156 | 1156 |
1157 Modifiers.withFlags(this.nodes, this.flags); | 1157 Modifiers.withFlags(this.nodes, this.flags); |
1158 | 1158 |
1159 static int computeFlags(Link<Node> nodes) { | 1159 static int computeFlags(Link<Node> nodes) { |
1160 int flags = 0; | 1160 int flags = 0; |
1161 for (; !nodes.isEmpty(); nodes = nodes.tail) { | 1161 for (; !nodes.isEmpty; nodes = nodes.tail) { |
1162 String value = nodes.head.asIdentifier().source.stringValue; | 1162 String value = nodes.head.asIdentifier().source.stringValue; |
1163 if (identical(value, 'static')) flags |= FLAG_STATIC; | 1163 if (identical(value, 'static')) flags |= FLAG_STATIC; |
1164 else if (identical(value, 'abstract')) flags |= FLAG_ABSTRACT; | 1164 else if (identical(value, 'abstract')) flags |= FLAG_ABSTRACT; |
1165 else if (identical(value, 'final')) flags |= FLAG_FINAL; | 1165 else if (identical(value, 'final')) flags |= FLAG_FINAL; |
1166 else if (identical(value, 'var')) flags |= FLAG_VAR; | 1166 else if (identical(value, 'var')) flags |= FLAG_VAR; |
1167 else if (identical(value, 'const')) flags |= FLAG_CONST; | 1167 else if (identical(value, 'const')) flags |= FLAG_CONST; |
1168 else if (identical(value, 'factory')) flags |= FLAG_FACTORY; | 1168 else if (identical(value, 'factory')) flags |= FLAG_FACTORY; |
1169 else if (identical(value, 'external')) flags |= FLAG_EXTERNAL; | 1169 else if (identical(value, 'external')) flags |= FLAG_EXTERNAL; |
1170 else throw 'internal error: ${nodes.head}'; | 1170 else throw 'internal error: ${nodes.head}'; |
1171 } | 1171 } |
1172 return flags; | 1172 return flags; |
1173 } | 1173 } |
1174 | 1174 |
1175 Node findModifier(String modifier) { | 1175 Node findModifier(String modifier) { |
1176 Link<Node> nodeList = nodes.nodes; | 1176 Link<Node> nodeList = nodes.nodes; |
1177 for (; !nodeList.isEmpty(); nodeList = nodeList.tail) { | 1177 for (; !nodeList.isEmpty; nodeList = nodeList.tail) { |
1178 String value = nodeList.head.asIdentifier().source.stringValue; | 1178 String value = nodeList.head.asIdentifier().source.stringValue; |
1179 if(identical(value, modifier)) { | 1179 if(identical(value, modifier)) { |
1180 return nodeList.head; | 1180 return nodeList.head; |
1181 } | 1181 } |
1182 } | 1182 } |
1183 return null; | 1183 return null; |
1184 } | 1184 } |
1185 | 1185 |
1186 Modifiers asModifiers() => this; | 1186 Modifiers asModifiers() => this; |
1187 Token getBeginToken() => nodes.getBeginToken(); | 1187 Token getBeginToken() => nodes.getBeginToken(); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 visitChildren(Visitor visitor) { | 1485 visitChildren(Visitor visitor) { |
1486 labelsAndCases.accept(visitor); | 1486 labelsAndCases.accept(visitor); |
1487 statements.accept(visitor); | 1487 statements.accept(visitor); |
1488 } | 1488 } |
1489 | 1489 |
1490 Token getBeginToken() { | 1490 Token getBeginToken() { |
1491 return startToken; | 1491 return startToken; |
1492 } | 1492 } |
1493 | 1493 |
1494 Token getEndToken() { | 1494 Token getEndToken() { |
1495 if (statements.nodes.isEmpty()) { | 1495 if (statements.nodes.isEmpty) { |
1496 // All cases must have at least one expression or be the default. | 1496 // All cases must have at least one expression or be the default. |
1497 if (defaultKeyword != null) { | 1497 if (defaultKeyword != null) { |
1498 // The colon after 'default'. | 1498 // The colon after 'default'. |
1499 return defaultKeyword.next; | 1499 return defaultKeyword.next; |
1500 } | 1500 } |
1501 // The colon after the last expression. | 1501 // The colon after the last expression. |
1502 return labelsAndCases.getEndToken(); | 1502 return labelsAndCases.getEndToken(); |
1503 } else { | 1503 } else { |
1504 return statements.getEndToken(); | 1504 return statements.getEndToken(); |
1505 } | 1505 } |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 visitChildren(Visitor visitor) { | 1887 visitChildren(Visitor visitor) { |
1888 tryBlock.accept(visitor); | 1888 tryBlock.accept(visitor); |
1889 catchBlocks.accept(visitor); | 1889 catchBlocks.accept(visitor); |
1890 if (finallyBlock != null) finallyBlock.accept(visitor); | 1890 if (finallyBlock != null) finallyBlock.accept(visitor); |
1891 } | 1891 } |
1892 | 1892 |
1893 Token getBeginToken() => tryKeyword; | 1893 Token getBeginToken() => tryKeyword; |
1894 | 1894 |
1895 Token getEndToken() { | 1895 Token getEndToken() { |
1896 if (finallyBlock != null) return finallyBlock.getEndToken(); | 1896 if (finallyBlock != null) return finallyBlock.getEndToken(); |
1897 if (!catchBlocks.isEmpty()) return catchBlocks.getEndToken(); | 1897 if (!catchBlocks.isEmpty) return catchBlocks.getEndToken(); |
1898 return tryBlock.getEndToken(); | 1898 return tryBlock.getEndToken(); |
1899 } | 1899 } |
1900 } | 1900 } |
1901 | 1901 |
1902 class Cascade extends Expression { | 1902 class Cascade extends Expression { |
1903 final Expression expression; | 1903 final Expression expression; |
1904 Cascade(this.expression); | 1904 Cascade(this.expression); |
1905 | 1905 |
1906 Cascade asCascade() => this; | 1906 Cascade asCascade() => this; |
1907 accept(Visitor visitor) => visitor.visitCascade(this); | 1907 accept(Visitor visitor) => visitor.visitCascade(this); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 final Token catchKeyword; | 1941 final Token catchKeyword; |
1942 | 1942 |
1943 CatchBlock(this.type, this.formals, this.block, | 1943 CatchBlock(this.type, this.formals, this.block, |
1944 this.onKeyword, this.catchKeyword); | 1944 this.onKeyword, this.catchKeyword); |
1945 | 1945 |
1946 CatchBlock asCatchBlock() => this; | 1946 CatchBlock asCatchBlock() => this; |
1947 | 1947 |
1948 accept(Visitor visitor) => visitor.visitCatchBlock(this); | 1948 accept(Visitor visitor) => visitor.visitCatchBlock(this); |
1949 | 1949 |
1950 Node get exception { | 1950 Node get exception { |
1951 if (formals == null || formals.nodes.isEmpty()) return null; | 1951 if (formals == null || formals.nodes.isEmpty) return null; |
1952 VariableDefinitions declarations = formals.nodes.head; | 1952 VariableDefinitions declarations = formals.nodes.head; |
1953 return declarations.definitions.nodes.head; | 1953 return declarations.definitions.nodes.head; |
1954 } | 1954 } |
1955 | 1955 |
1956 Node get trace { | 1956 Node get trace { |
1957 if (formals == null || formals.nodes.isEmpty()) return null; | 1957 if (formals == null || formals.nodes.isEmpty) return null; |
1958 Link<Node> declarations = formals.nodes.tail; | 1958 Link<Node> declarations = formals.nodes.tail; |
1959 if (declarations.isEmpty()) return null; | 1959 if (declarations.isEmpty) return null; |
1960 VariableDefinitions head = declarations.head; | 1960 VariableDefinitions head = declarations.head; |
1961 return head.definitions.nodes.head; | 1961 return head.definitions.nodes.head; |
1962 } | 1962 } |
1963 | 1963 |
1964 visitChildren(Visitor visitor) { | 1964 visitChildren(Visitor visitor) { |
1965 if (type != null) type.accept(visitor); | 1965 if (type != null) type.accept(visitor); |
1966 if (formals != null) formals.accept(visitor); | 1966 if (formals != null) formals.accept(visitor); |
1967 block.accept(visitor); | 1967 block.accept(visitor); |
1968 } | 1968 } |
1969 | 1969 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 * argument). | 2015 * argument). |
2016 * | 2016 * |
2017 * TODO(ahe): This method is controversial, the team needs to discuss | 2017 * TODO(ahe): This method is controversial, the team needs to discuss |
2018 * if top-level methods are acceptable and what naming conventions to | 2018 * if top-level methods are acceptable and what naming conventions to |
2019 * use. | 2019 * use. |
2020 */ | 2020 */ |
2021 initializerDo(Node node, f(Node node)) { | 2021 initializerDo(Node node, f(Node node)) { |
2022 SendSet send = node.asSendSet(); | 2022 SendSet send = node.asSendSet(); |
2023 if (send != null) return f(send.arguments.head); | 2023 if (send != null) return f(send.arguments.head); |
2024 } | 2024 } |
OLD | NEW |