Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface Visitor<R> { | 5 interface Visitor<R> { |
| 6 R visitBlock(Block node); | 6 R visitBlock(Block node); |
| 7 R visitBreakStatement(BreakStatement node); | 7 R visitBreakStatement(BreakStatement node); |
| 8 R visitCatchBlock(CatchBlock node); | 8 R visitCatchBlock(CatchBlock node); |
| 9 R visitClassNode(ClassNode node); | 9 R visitClassNode(ClassNode node); |
| 10 R visitConditional(Conditional node); | 10 R visitConditional(Conditional node); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 StringInterpolation asStringInterpolation() => null; | 139 StringInterpolation asStringInterpolation() => null; |
| 140 StringInterpolationPart asStringInterpolationPart() => null; | 140 StringInterpolationPart asStringInterpolationPart() => null; |
| 141 SwitchCase asSwitchCase() => null; | 141 SwitchCase asSwitchCase() => null; |
| 142 SwitchStatement asSwitchStatement() => null; | 142 SwitchStatement asSwitchStatement() => null; |
| 143 Throw asThrow() => null; | 143 Throw asThrow() => null; |
| 144 TryStatement asTryStatement() => null; | 144 TryStatement asTryStatement() => null; |
| 145 TypeAnnotation asTypeAnnotation() => null; | 145 TypeAnnotation asTypeAnnotation() => null; |
| 146 Typedef asTypedef() => null; | 146 Typedef asTypedef() => null; |
| 147 VariableDefinitions asVariableDefinitions() => null; | 147 VariableDefinitions asVariableDefinitions() => null; |
| 148 While asWhile() => null; | 148 While asWhile() => null; |
| 149 | |
| 150 bool isValidBreakTarget() => false; | |
| 151 bool isValidContinueTarget() => false; | |
| 149 } | 152 } |
| 150 | 153 |
| 151 class ClassNode extends Node { | 154 class ClassNode extends Node { |
| 152 final Identifier name; | 155 final Identifier name; |
| 153 final TypeAnnotation superclass; | 156 final TypeAnnotation superclass; |
| 154 final NodeList interfaces; | 157 final NodeList interfaces; |
| 155 | 158 |
| 156 // Using a NodeList to record the keyword "default". | 159 // Using a NodeList to record the keyword "default". |
| 157 // TODO(ahe): Consider if there is a better way to represent this. | 160 // TODO(ahe): Consider if there is a better way to represent this. |
| 158 final NodeList defaultClause; | 161 final NodeList defaultClause; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 } | 196 } |
| 194 | 197 |
| 195 class Statement extends Node { | 198 class Statement extends Node { |
| 196 Statement(); | 199 Statement(); |
| 197 | 200 |
| 198 Statement asStatement() => this; | 201 Statement asStatement() => this; |
| 199 | 202 |
| 200 // TODO(ahe): make class abstract instead of adding an abstract method. | 203 // TODO(ahe): make class abstract instead of adding an abstract method. |
| 201 abstract accept(Visitor visitor); | 204 abstract accept(Visitor visitor); |
| 202 | 205 |
| 203 bool isValidContinueTarget() => false; | 206 bool isValidBreakTarget() => true; |
| 204 } | 207 } |
| 205 | 208 |
| 206 /** | 209 /** |
| 207 * A message send aka method invocation. In Dart, most operations can | 210 * A message send aka method invocation. In Dart, most operations can |
| 208 * (and should) be considered as message sends. Getters and setters | 211 * (and should) be considered as message sends. Getters and setters |
| 209 * are just methods with a special syntax. Consequently, we model | 212 * are just methods with a special syntax. Consequently, we model |
| 210 * property access, assignment, operators, and method calls with this | 213 * property access, assignment, operators, and method calls with this |
| 211 * one node. | 214 * one node. |
| 212 */ | 215 */ |
| 213 class Send extends Expression { | 216 class Send extends Expression { |
| (...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1402 visitChildren(Visitor visitor) { | 1405 visitChildren(Visitor visitor) { |
| 1403 parenthesizedExpression.accept(visitor); | 1406 parenthesizedExpression.accept(visitor); |
| 1404 cases.accept(visitor); | 1407 cases.accept(visitor); |
| 1405 } | 1408 } |
| 1406 | 1409 |
| 1407 Token getBeginToken() => switchKeyword; | 1410 Token getBeginToken() => switchKeyword; |
| 1408 | 1411 |
| 1409 Token getEndToken() => cases.getEndToken(); | 1412 Token getEndToken() => cases.getEndToken(); |
| 1410 } | 1413 } |
| 1411 | 1414 |
| 1412 class SwitchCase extends Node { | 1415 class SwitchCase extends Node { |
|
ahe
2012/03/13 10:17:15
A short comment would be helpful, something like:
| |
| 1413 final Identifier label; | 1416 final Identifier label; |
| 1414 final Expression expression; | 1417 final NodeList expressions; |
| 1418 final Token defaultKeyword; | |
| 1415 final NodeList statements; | 1419 final NodeList statements; |
| 1416 | 1420 |
| 1417 final Token caseKeyword; | 1421 final Token startToken; |
| 1418 | 1422 |
| 1419 SwitchCase(this.label, this.expression, this.statements, this.caseKeyword); | 1423 SwitchCase(this.label, this.expressions, this.defaultKeyword, |
| 1424 this.statements, this.startToken); | |
| 1420 | 1425 |
| 1421 SwitchCase asSwitchCase() => this; | 1426 SwitchCase asSwitchCase() => this; |
| 1422 | 1427 |
| 1428 bool get isDefaultCase() => defaultKeyword !== null; | |
| 1429 | |
| 1423 accept(Visitor visitor) => visitor.visitSwitchCase(this); | 1430 accept(Visitor visitor) => visitor.visitSwitchCase(this); |
| 1424 | 1431 |
| 1425 visitChildren(Visitor visitor) { | 1432 visitChildren(Visitor visitor) { |
| 1426 if (label !== null) label.accept(visitor); | 1433 if (label !== null) label.accept(visitor); |
| 1427 expression.accept(visitor); | 1434 expressions.accept(visitor); |
| 1428 statements.accept(visitor); | 1435 statements.accept(visitor); |
| 1429 } | 1436 } |
| 1430 | 1437 |
| 1431 Token getBeginToken() { | 1438 Token getBeginToken() { |
| 1432 if (label !== null) return label.getBeginToken(); | 1439 return startToken; |
| 1433 return caseKeyword; | |
| 1434 } | 1440 } |
| 1435 | 1441 |
| 1436 Token getEndToken() { | 1442 Token getEndToken() { |
| 1437 if (statements.nodes.isEmpty()) { | 1443 if (statements.nodes.isEmpty()) { |
| 1444 // All cases must have at least one expression or be the default. | |
| 1445 if (defaultKeyword !== null) { | |
| 1446 // The colon after 'default'. | |
| 1447 return defaultKeyword.next; | |
| 1448 } | |
| 1438 // The colon after the expression. | 1449 // The colon after the expression. |
| 1439 return expression.getEndToken().next; | 1450 return expressions.getEndToken().next; |
| 1440 } else { | 1451 } else { |
| 1441 return statements.getEndToken(); | 1452 return statements.getEndToken(); |
| 1442 } | 1453 } |
| 1443 } | 1454 } |
| 1444 } | |
| 1445 | 1455 |
| 1446 class DefaultCase extends Node { | 1456 List<Token> caseKeywords() { |
|
ahe
2012/03/13 10:17:15
Please return a Link for consistency.
Lasse Reichstein Nielsen
2012/03/13 12:09:38
Done.
| |
| 1447 final Identifier label; | 1457 Token token = begin; |
| 1448 final NodeList statements; | 1458 if (label !== null) { |
| 1449 | 1459 // Skip past <Identifier> ':'. |
|
ahe
2012/03/13 10:17:15
// Skip past the label: <Identifier> ':'.
Lasse Reichstein Nielsen
2012/03/13 12:09:38
Done.
| |
| 1450 final Token defaultKeyword; | 1460 token = token.next.next; |
| 1451 | |
| 1452 DefaultCase(this.label, this.statements, this.defaultKeyword); | |
| 1453 | |
| 1454 DefaultCase asDefaultCase() => this; | |
| 1455 | |
| 1456 accept(Visitor visitor) => visitor.visitDefaultCase(this); | |
| 1457 | |
| 1458 visitChildren(Visitor visitor) { | |
| 1459 if (label !== null) label.accept(visitor); | |
| 1460 statements.accept(visitor); | |
| 1461 } | |
| 1462 | |
| 1463 Token getBeginToken() { | |
| 1464 if (label !== null) return label.getBeginToken(); | |
| 1465 return defaultKeyword; | |
| 1466 } | |
| 1467 | |
| 1468 Token getEndToken() { | |
| 1469 if (statements.nodes.isEmpty()) { | |
| 1470 // The colon after default. | |
| 1471 return defaultKeyword.next; | |
| 1472 } else { | |
| 1473 return statements.getEndToken(); | |
| 1474 } | 1461 } |
| 1462 List<Token> result = <Token>[]; | |
| 1463 while (token.stringValue === "case") { | |
| 1464 result.add(token); | |
| 1465 // Skip past 'case' <Expression> ':'. | |
| 1466 token = token.next.next.next; | |
|
Lasse Reichstein Nielsen
2012/03/13 12:09:38
Oh, and this doesn't actually work. Fixing.
| |
| 1467 } | |
| 1468 return result; | |
| 1475 } | 1469 } |
| 1476 } | 1470 } |
| 1477 | 1471 |
| 1478 class GotoStatement extends Statement { | 1472 class GotoStatement extends Statement { |
| 1479 final Identifier target; | 1473 final Identifier target; |
| 1480 final Token keywordToken; | 1474 final Token keywordToken; |
| 1481 final Token semicolonToken; | 1475 final Token semicolonToken; |
| 1482 | 1476 |
| 1483 GotoStatement(this.target, this.keywordToken, this.semicolonToken); | 1477 GotoStatement(this.target, this.keywordToken, this.semicolonToken); |
| 1484 | 1478 |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1707 static bool isConstructorRedirect(Send node) { | 1701 static bool isConstructorRedirect(Send node) { |
| 1708 return (node.receiver === null && | 1702 return (node.receiver === null && |
| 1709 node.selector.asIdentifier() !== null && | 1703 node.selector.asIdentifier() !== null && |
| 1710 node.selector.asIdentifier().isThis()) || | 1704 node.selector.asIdentifier().isThis()) || |
| 1711 (node.receiver !== null && | 1705 (node.receiver !== null && |
| 1712 node.receiver.asIdentifier() !== null && | 1706 node.receiver.asIdentifier() !== null && |
| 1713 node.receiver.asIdentifier().isThis() && | 1707 node.receiver.asIdentifier().isThis() && |
| 1714 node.selector.asIdentifier() !== null); | 1708 node.selector.asIdentifier() !== null); |
| 1715 } | 1709 } |
| 1716 } | 1710 } |
| OLD | NEW |