| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.parser; | 8 library engine.parser; |
| 9 | 9 |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 217 |
| 218 ASTNode visitAssertStatement(AssertStatement node) { | 218 ASTNode visitAssertStatement(AssertStatement node) { |
| 219 if (identical(_oldNode, node.condition)) { | 219 if (identical(_oldNode, node.condition)) { |
| 220 return _parser.parseExpression3(); | 220 return _parser.parseExpression3(); |
| 221 } | 221 } |
| 222 return notAChild(node); | 222 return notAChild(node); |
| 223 } | 223 } |
| 224 | 224 |
| 225 ASTNode visitAssignmentExpression(AssignmentExpression node) { | 225 ASTNode visitAssignmentExpression(AssignmentExpression node) { |
| 226 if (identical(_oldNode, node.leftHandSide)) { | 226 if (identical(_oldNode, node.leftHandSide)) { |
| 227 // TODO(brianwilkerson) If the assignment is part of a cascade section, th
en we don't have a |
| 228 // single parse method that will work. Otherwise, we can parse a condition
al expression, but |
| 229 // need to ensure that the resulting expression is assignable. |
| 230 // return parser.parseConditionalExpression(); |
| 227 throw new InsufficientContextException(); | 231 throw new InsufficientContextException(); |
| 228 } else if (identical(_oldNode, node.rightHandSide)) { | 232 } else if (identical(_oldNode, node.rightHandSide)) { |
| 229 if (isCascadeAllowed(node)) { | 233 if (isCascadeAllowed(node)) { |
| 230 return _parser.parseExpression3(); | 234 return _parser.parseExpression3(); |
| 231 } | 235 } |
| 232 return _parser.parseExpressionWithoutCascade(); | 236 return _parser.parseExpressionWithoutCascade(); |
| 233 } | 237 } |
| 234 return notAChild(node); | 238 return notAChild(node); |
| 235 } | 239 } |
| 236 | 240 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 throw new InsufficientContextException(); | 506 throw new InsufficientContextException(); |
| 503 } else if (identical(_oldNode, node.identifier)) { | 507 } else if (identical(_oldNode, node.identifier)) { |
| 504 return _parser.parseSimpleIdentifier(); | 508 return _parser.parseSimpleIdentifier(); |
| 505 } else if (identical(_oldNode, node.body)) { | 509 } else if (identical(_oldNode, node.body)) { |
| 506 return _parser.parseStatement2(); | 510 return _parser.parseStatement2(); |
| 507 } | 511 } |
| 508 return notAChild(node); | 512 return notAChild(node); |
| 509 } | 513 } |
| 510 | 514 |
| 511 ASTNode visitFormalParameterList(FormalParameterList node) { | 515 ASTNode visitFormalParameterList(FormalParameterList node) { |
| 516 // We don't know which kind of parameter to parse. |
| 512 throw new InsufficientContextException(); | 517 throw new InsufficientContextException(); |
| 513 } | 518 } |
| 514 | 519 |
| 515 ASTNode visitForStatement(ForStatement node) { | 520 ASTNode visitForStatement(ForStatement node) { |
| 516 if (identical(_oldNode, node.variables)) { | 521 if (identical(_oldNode, node.variables)) { |
| 517 throw new InsufficientContextException(); | 522 throw new InsufficientContextException(); |
| 518 } else if (identical(_oldNode, node.initialization)) { | 523 } else if (identical(_oldNode, node.initialization)) { |
| 519 throw new InsufficientContextException(); | 524 throw new InsufficientContextException(); |
| 520 } else if (identical(_oldNode, node.condition)) { | 525 } else if (identical(_oldNode, node.condition)) { |
| 521 return _parser.parseExpression3(); | 526 return _parser.parseExpression3(); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 } else if (node.metadata.contains(_oldNode)) { | 754 } else if (node.metadata.contains(_oldNode)) { |
| 750 return _parser.parseAnnotation(); | 755 return _parser.parseAnnotation(); |
| 751 } else if (identical(_oldNode, node.returnType)) { | 756 } else if (identical(_oldNode, node.returnType)) { |
| 752 throw new InsufficientContextException(); | 757 throw new InsufficientContextException(); |
| 753 } else if (identical(_oldNode, node.name)) { | 758 } else if (identical(_oldNode, node.name)) { |
| 754 if (node.operatorKeyword != null) { | 759 if (node.operatorKeyword != null) { |
| 755 throw new InsufficientContextException(); | 760 throw new InsufficientContextException(); |
| 756 } | 761 } |
| 757 return _parser.parseSimpleIdentifier(); | 762 return _parser.parseSimpleIdentifier(); |
| 758 } else if (identical(_oldNode, node.body)) { | 763 } else if (identical(_oldNode, node.body)) { |
| 764 //return parser.parseFunctionBody(); |
| 759 throw new InsufficientContextException(); | 765 throw new InsufficientContextException(); |
| 760 } | 766 } |
| 761 return notAChild(node); | 767 return notAChild(node); |
| 762 } | 768 } |
| 763 | 769 |
| 764 ASTNode visitMethodInvocation(MethodInvocation node) { | 770 ASTNode visitMethodInvocation(MethodInvocation node) { |
| 765 if (identical(_oldNode, node.target)) { | 771 if (identical(_oldNode, node.target)) { |
| 766 throw new IncrementalParseException(); | 772 throw new IncrementalParseException(); |
| 767 } else if (identical(_oldNode, node.methodName)) { | 773 } else if (identical(_oldNode, node.methodName)) { |
| 768 return _parser.parseSimpleIdentifier(); | 774 return _parser.parseSimpleIdentifier(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 } | 1075 } |
| 1070 | 1076 |
| 1071 /** | 1077 /** |
| 1072 * Return `true` if the given assignment expression can have a cascade express
ion on the | 1078 * Return `true` if the given assignment expression can have a cascade express
ion on the |
| 1073 * right-hand side. | 1079 * right-hand side. |
| 1074 * | 1080 * |
| 1075 * @param node the assignment expression being tested | 1081 * @param node the assignment expression being tested |
| 1076 * @return `true` if the right-hand side can be a cascade expression | 1082 * @return `true` if the right-hand side can be a cascade expression |
| 1077 */ | 1083 */ |
| 1078 bool isCascadeAllowed(AssignmentExpression node) { | 1084 bool isCascadeAllowed(AssignmentExpression node) { |
| 1085 // TODO(brianwilkerson) Implement this method. |
| 1079 throw new InsufficientContextException(); | 1086 throw new InsufficientContextException(); |
| 1080 } | 1087 } |
| 1081 | 1088 |
| 1082 /** | 1089 /** |
| 1083 * Return `true` if the given throw expression can have a cascade expression. | 1090 * Return `true` if the given throw expression can have a cascade expression. |
| 1084 * | 1091 * |
| 1085 * @param node the throw expression being tested | 1092 * @param node the throw expression being tested |
| 1086 * @return `true` if the expression can be a cascade expression | 1093 * @return `true` if the expression can be a cascade expression |
| 1087 */ | 1094 */ |
| 1088 bool isCascadeAllowed2(ThrowExpression node) { | 1095 bool isCascadeAllowed2(ThrowExpression node) { |
| 1096 // TODO(brianwilkerson) Implement this method. |
| 1089 throw new InsufficientContextException(); | 1097 throw new InsufficientContextException(); |
| 1090 } | 1098 } |
| 1091 | 1099 |
| 1092 /** | 1100 /** |
| 1093 * Throw an exception indicating that the visited node was not the parent of t
he node to be | 1101 * Throw an exception indicating that the visited node was not the parent of t
he node to be |
| 1094 * replaced. | 1102 * replaced. |
| 1095 * | 1103 * |
| 1096 * @param visitedNode the visited node that should have been the parent of the
node to be replaced | 1104 * @param visitedNode the visited node that should have been the parent of the
node to be replaced |
| 1097 */ | 1105 */ |
| 1098 ASTNode notAChild(ASTNode visitedNode) { | 1106 ASTNode notAChild(ASTNode visitedNode) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 * @param leftToken the token in the new token stream immediately to the left
of the range of | 1188 * @param leftToken the token in the new token stream immediately to the left
of the range of |
| 1181 * tokens that were inserted | 1189 * tokens that were inserted |
| 1182 * @param rightToken the token in the new token stream immediately to the righ
t of the range of | 1190 * @param rightToken the token in the new token stream immediately to the righ
t of the range of |
| 1183 * tokens that were inserted | 1191 * tokens that were inserted |
| 1184 * @param originalStart the offset in the original source of the first charact
er that was modified | 1192 * @param originalStart the offset in the original source of the first charact
er that was modified |
| 1185 * @param originalEnd the offset in the original source of the last character
that was modified | 1193 * @param originalEnd the offset in the original source of the last character
that was modified |
| 1186 */ | 1194 */ |
| 1187 ASTNode reparse(ASTNode originalStructure, Token leftToken, Token rightToken,
int originalStart, int originalEnd) { | 1195 ASTNode reparse(ASTNode originalStructure, Token leftToken, Token rightToken,
int originalStart, int originalEnd) { |
| 1188 ASTNode oldNode = null; | 1196 ASTNode oldNode = null; |
| 1189 ASTNode newNode = null; | 1197 ASTNode newNode = null; |
| 1198 // |
| 1199 // Find the first token that needs to be re-parsed. |
| 1200 // |
| 1190 Token firstToken = leftToken.next; | 1201 Token firstToken = leftToken.next; |
| 1191 if (identical(firstToken, rightToken)) { | 1202 if (identical(firstToken, rightToken)) { |
| 1203 // If there are no new tokens, then we need to include at least one copied
node in the range. |
| 1192 firstToken = leftToken; | 1204 firstToken = leftToken; |
| 1193 } | 1205 } |
| 1206 // |
| 1207 // Find the smallest AST node that encompasses the range of re-scanned token
s. |
| 1208 // |
| 1194 if (originalEnd < originalStart) { | 1209 if (originalEnd < originalStart) { |
| 1195 oldNode = new NodeLocator.con1(originalStart).searchWithin(originalStructu
re); | 1210 oldNode = new NodeLocator.con1(originalStart).searchWithin(originalStructu
re); |
| 1196 } else { | 1211 } else { |
| 1197 oldNode = new NodeLocator.con2(originalStart, originalEnd).searchWithin(or
iginalStructure); | 1212 oldNode = new NodeLocator.con2(originalStart, originalEnd).searchWithin(or
iginalStructure); |
| 1198 } | 1213 } |
| 1214 // |
| 1215 // Find the token at which parsing is to begin. |
| 1216 // |
| 1199 int originalOffset = oldNode.offset; | 1217 int originalOffset = oldNode.offset; |
| 1200 Token parseToken = findTokenAt(firstToken, originalOffset); | 1218 Token parseToken = findTokenAt(firstToken, originalOffset); |
| 1201 if (parseToken == null) { | 1219 if (parseToken == null) { |
| 1202 return null; | 1220 return null; |
| 1203 } | 1221 } |
| 1222 // |
| 1223 // Parse the appropriate AST structure starting at the appropriate place. |
| 1224 // |
| 1204 Parser parser = new Parser(_source, _errorListener); | 1225 Parser parser = new Parser(_source, _errorListener); |
| 1205 parser.currentToken = parseToken; | 1226 parser.currentToken = parseToken; |
| 1206 while (newNode == null) { | 1227 while (newNode == null) { |
| 1207 ASTNode parent = oldNode.parent; | 1228 ASTNode parent = oldNode.parent; |
| 1208 if (parent == null) { | 1229 if (parent == null) { |
| 1209 parseToken = findFirstToken(parseToken); | 1230 parseToken = findFirstToken(parseToken); |
| 1210 parser.currentToken = parseToken; | 1231 parser.currentToken = parseToken; |
| 1211 return parser.parseCompilationUnit2(); | 1232 return parser.parseCompilationUnit2(); |
| 1212 } | 1233 } |
| 1213 bool advanceToParent = false; | 1234 bool advanceToParent = false; |
| 1214 try { | 1235 try { |
| 1215 IncrementalParseDispatcher dispatcher = new IncrementalParseDispatcher(p
arser, oldNode); | 1236 IncrementalParseDispatcher dispatcher = new IncrementalParseDispatcher(p
arser, oldNode); |
| 1216 newNode = parent.accept(dispatcher); | 1237 newNode = parent.accept(dispatcher); |
| 1238 // |
| 1239 // Validate that the new node can replace the old node. |
| 1240 // |
| 1217 Token mappedToken = _tokenMap.get(oldNode.endToken.next); | 1241 Token mappedToken = _tokenMap.get(oldNode.endToken.next); |
| 1218 if (mappedToken == null || mappedToken.offset != newNode.endToken.next.o
ffset || newNode.offset != oldNode.offset) { | 1242 if (mappedToken == null || mappedToken.offset != newNode.endToken.next.o
ffset || newNode.offset != oldNode.offset) { |
| 1219 advanceToParent = true; | 1243 advanceToParent = true; |
| 1220 } | 1244 } |
| 1221 } on InsufficientContextException catch (exception) { | 1245 } on InsufficientContextException catch (exception) { |
| 1222 advanceToParent = true; | 1246 advanceToParent = true; |
| 1223 } on JavaException catch (exception) { | 1247 } on JavaException catch (exception) { |
| 1224 return null; | 1248 return null; |
| 1225 } | 1249 } |
| 1226 if (advanceToParent) { | 1250 if (advanceToParent) { |
| 1227 newNode = null; | 1251 newNode = null; |
| 1228 oldNode = parent; | 1252 oldNode = parent; |
| 1229 originalOffset = oldNode.offset; | 1253 originalOffset = oldNode.offset; |
| 1230 parseToken = findTokenAt(parseToken, originalOffset); | 1254 parseToken = findTokenAt(parseToken, originalOffset); |
| 1231 parser.currentToken = parseToken; | 1255 parser.currentToken = parseToken; |
| 1232 } | 1256 } |
| 1233 } | 1257 } |
| 1234 _updatedNode = newNode; | 1258 _updatedNode = newNode; |
| 1259 // |
| 1260 // Replace the old node with the new node in a copy of the original AST stru
cture. |
| 1261 // |
| 1235 if (identical(oldNode, originalStructure)) { | 1262 if (identical(oldNode, originalStructure)) { |
| 1263 // We ended up re-parsing the whole structure, so there's no need for a co
py. |
| 1236 ResolutionCopier.copyResolutionData(oldNode, newNode); | 1264 ResolutionCopier.copyResolutionData(oldNode, newNode); |
| 1237 return newNode; | 1265 return newNode; |
| 1238 } | 1266 } |
| 1239 ResolutionCopier.copyResolutionData(oldNode, newNode); | 1267 ResolutionCopier.copyResolutionData(oldNode, newNode); |
| 1240 IncrementalASTCloner cloner = new IncrementalASTCloner(oldNode, newNode, _to
kenMap); | 1268 IncrementalASTCloner cloner = new IncrementalASTCloner(oldNode, newNode, _to
kenMap); |
| 1241 return originalStructure.accept(cloner) as ASTNode; | 1269 return originalStructure.accept(cloner) as ASTNode; |
| 1242 } | 1270 } |
| 1243 | 1271 |
| 1244 /** | 1272 /** |
| 1245 * Return the first (non-EOF) token in the token stream containing the given t
oken. | 1273 * Return the first (non-EOF) token in the token stream containing the given t
oken. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1469 * namedArgument | 1497 * namedArgument |
| 1470 * | expression | 1498 * | expression |
| 1471 * | 1499 * |
| 1472 * namedArgument ::= | 1500 * namedArgument ::= |
| 1473 * label expression | 1501 * label expression |
| 1474 * </pre> | 1502 * </pre> |
| 1475 * | 1503 * |
| 1476 * @return the argument that was parsed | 1504 * @return the argument that was parsed |
| 1477 */ | 1505 */ |
| 1478 Expression parseArgument() { | 1506 Expression parseArgument() { |
| 1507 // |
| 1508 // Both namedArgument and expression can start with an identifier, but only
namedArgument can |
| 1509 // have an identifier followed by a colon. |
| 1510 // |
| 1479 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { | 1511 if (matchesIdentifier() && matches4(peek(), TokenType.COLON)) { |
| 1480 return new NamedExpression(parseLabel(), parseExpression3()); | 1512 return new NamedExpression(parseLabel(), parseExpression3()); |
| 1481 } else { | 1513 } else { |
| 1482 return parseExpression3(); | 1514 return parseExpression3(); |
| 1483 } | 1515 } |
| 1484 } | 1516 } |
| 1485 | 1517 |
| 1486 /** | 1518 /** |
| 1487 * Parse a list of arguments. | 1519 * Parse a list of arguments. |
| 1488 * | 1520 * |
| 1489 * <pre> | 1521 * <pre> |
| 1490 * arguments ::= | 1522 * arguments ::= |
| 1491 * '(' argumentList? ')' | 1523 * '(' argumentList? ')' |
| 1492 * | 1524 * |
| 1493 * argumentList ::= | 1525 * argumentList ::= |
| 1494 * namedArgument (',' namedArgument)* | 1526 * namedArgument (',' namedArgument)* |
| 1495 * | expressionList (',' namedArgument)* | 1527 * | expressionList (',' namedArgument)* |
| 1496 * </pre> | 1528 * </pre> |
| 1497 * | 1529 * |
| 1498 * @return the argument list that was parsed | 1530 * @return the argument list that was parsed |
| 1499 */ | 1531 */ |
| 1500 ArgumentList parseArgumentList() { | 1532 ArgumentList parseArgumentList() { |
| 1501 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); | 1533 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); |
| 1502 List<Expression> arguments = new List<Expression>(); | 1534 List<Expression> arguments = new List<Expression>(); |
| 1503 if (matches5(TokenType.CLOSE_PAREN)) { | 1535 if (matches5(TokenType.CLOSE_PAREN)) { |
| 1504 return new ArgumentList(leftParenthesis, arguments, andAdvance); | 1536 return new ArgumentList(leftParenthesis, arguments, andAdvance); |
| 1505 } | 1537 } |
| 1538 // |
| 1539 // Even though unnamed arguments must all appear before any named arguments,
we allow them to |
| 1540 // appear in any order so that we can recover faster. |
| 1541 // |
| 1506 Expression argument = parseArgument(); | 1542 Expression argument = parseArgument(); |
| 1507 arguments.add(argument); | 1543 arguments.add(argument); |
| 1508 bool foundNamedArgument = argument is NamedExpression; | 1544 bool foundNamedArgument = argument is NamedExpression; |
| 1509 bool generatedError = false; | 1545 bool generatedError = false; |
| 1510 while (optional(TokenType.COMMA)) { | 1546 while (optional(TokenType.COMMA)) { |
| 1511 argument = parseArgument(); | 1547 argument = parseArgument(); |
| 1512 arguments.add(argument); | 1548 arguments.add(argument); |
| 1513 if (foundNamedArgument) { | 1549 if (foundNamedArgument) { |
| 1514 if (!generatedError && argument is! NamedExpression) { | 1550 if (!generatedError && argument is! NamedExpression) { |
| 1551 // Report the error, once, but allow the arguments to be in any order
in the AST. |
| 1515 reportError11(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []); | 1552 reportError11(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, []); |
| 1516 generatedError = true; | 1553 generatedError = true; |
| 1517 } | 1554 } |
| 1518 } else if (argument is NamedExpression) { | 1555 } else if (argument is NamedExpression) { |
| 1519 foundNamedArgument = true; | 1556 foundNamedArgument = true; |
| 1520 } | 1557 } |
| 1521 } | 1558 } |
| 1559 // TODO(brianwilkerson) Recovery: Look at the left parenthesis to see whethe
r there is a |
| 1560 // matching right parenthesis. If there is, then we're more likely missing a
comma and should |
| 1561 // go back to parsing arguments. |
| 1522 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); | 1562 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); |
| 1523 return new ArgumentList(leftParenthesis, arguments, rightParenthesis); | 1563 return new ArgumentList(leftParenthesis, arguments, rightParenthesis); |
| 1524 } | 1564 } |
| 1525 | 1565 |
| 1526 /** | 1566 /** |
| 1527 * Parse a bitwise or expression. | 1567 * Parse a bitwise or expression. |
| 1528 * | 1568 * |
| 1529 * <pre> | 1569 * <pre> |
| 1530 * bitwiseOrExpression ::= | 1570 * bitwiseOrExpression ::= |
| 1531 * bitwiseXorExpression ('|' bitwiseXorExpression)* | 1571 * bitwiseXorExpression ('|' bitwiseXorExpression)* |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1561 Block parseBlock() { | 1601 Block parseBlock() { |
| 1562 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); | 1602 Token leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); |
| 1563 List<Statement> statements = new List<Statement>(); | 1603 List<Statement> statements = new List<Statement>(); |
| 1564 Token statementStart = _currentToken; | 1604 Token statementStart = _currentToken; |
| 1565 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET))
{ | 1605 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRACKET))
{ |
| 1566 Statement statement = parseStatement2(); | 1606 Statement statement = parseStatement2(); |
| 1567 if (statement != null) { | 1607 if (statement != null) { |
| 1568 statements.add(statement); | 1608 statements.add(statement); |
| 1569 } | 1609 } |
| 1570 if (identical(_currentToken, statementStart)) { | 1610 if (identical(_currentToken, statementStart)) { |
| 1611 // Ensure that we are making progress and report an error if we're not. |
| 1571 reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_current
Token.lexeme]); | 1612 reportError12(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [_current
Token.lexeme]); |
| 1572 advance(); | 1613 advance(); |
| 1573 } | 1614 } |
| 1574 statementStart = _currentToken; | 1615 statementStart = _currentToken; |
| 1575 } | 1616 } |
| 1576 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); | 1617 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); |
| 1577 return new Block(leftBracket, statements, rightBracket); | 1618 return new Block(leftBracket, statements, rightBracket); |
| 1578 } | 1619 } |
| 1579 | 1620 |
| 1580 /** | 1621 /** |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1604 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { | 1645 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { |
| 1605 validateModifiersForOperator(modifiers); | 1646 validateModifiersForOperator(modifiers); |
| 1606 return parseOperator(commentAndMetadata, modifiers.externalKeyword, retu
rnType); | 1647 return parseOperator(commentAndMetadata, modifiers.externalKeyword, retu
rnType); |
| 1607 } else if (matchesIdentifier() && matchesAny(peek(), [ | 1648 } else if (matchesIdentifier() && matchesAny(peek(), [ |
| 1608 TokenType.OPEN_PAREN, | 1649 TokenType.OPEN_PAREN, |
| 1609 TokenType.OPEN_CURLY_BRACKET, | 1650 TokenType.OPEN_CURLY_BRACKET, |
| 1610 TokenType.FUNCTION])) { | 1651 TokenType.FUNCTION])) { |
| 1611 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1652 validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1612 return parseMethodDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, modifiers.staticKeyword, returnType); | 1653 return parseMethodDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, modifiers.staticKeyword, returnType); |
| 1613 } else { | 1654 } else { |
| 1655 // |
| 1656 // We have found an error of some kind. Try to recover. |
| 1657 // |
| 1614 if (matchesIdentifier()) { | 1658 if (matchesIdentifier()) { |
| 1615 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMIC
OLON])) { | 1659 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMIC
OLON])) { |
| 1660 // |
| 1661 // We appear to have a variable declaration with a type of "void". |
| 1662 // |
| 1616 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); | 1663 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); |
| 1617 return parseInitializedIdentifierList(commentAndMetadata, modifiers.
staticKeyword, validateModifiersForField(modifiers), returnType); | 1664 return parseInitializedIdentifierList(commentAndMetadata, modifiers.
staticKeyword, validateModifiersForField(modifiers), returnType); |
| 1618 } | 1665 } |
| 1619 } | 1666 } |
| 1620 if (isOperator(_currentToken)) { | 1667 if (isOperator(_currentToken)) { |
| 1668 // |
| 1669 // We appear to have found an operator declaration without the 'operat
or' keyword. |
| 1670 // |
| 1621 validateModifiersForOperator(modifiers); | 1671 validateModifiersForOperator(modifiers); |
| 1622 return parseOperator(commentAndMetadata, modifiers.externalKeyword, re
turnType); | 1672 return parseOperator(commentAndMetadata, modifiers.externalKeyword, re
turnType); |
| 1623 } | 1673 } |
| 1624 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); | 1674 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); |
| 1625 return null; | 1675 return null; |
| 1626 } | 1676 } |
| 1627 } else if (matches(Keyword.GET) && matchesIdentifier2(peek())) { | 1677 } else if (matches(Keyword.GET) && matchesIdentifier2(peek())) { |
| 1628 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1678 validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1629 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, null); | 1679 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, null); |
| 1630 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) { | 1680 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) { |
| 1631 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1681 validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1632 return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, null); | 1682 return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, null); |
| 1633 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { | 1683 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { |
| 1634 validateModifiersForOperator(modifiers); | 1684 validateModifiersForOperator(modifiers); |
| 1635 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null); | 1685 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null); |
| 1636 } else if (!matchesIdentifier()) { | 1686 } else if (!matchesIdentifier()) { |
| 1637 if (isOperator(_currentToken)) { | 1687 if (isOperator(_currentToken)) { |
| 1688 // |
| 1689 // We appear to have found an operator declaration without the 'operator
' keyword. |
| 1690 // |
| 1638 validateModifiersForOperator(modifiers); | 1691 validateModifiersForOperator(modifiers); |
| 1639 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null
); | 1692 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null
); |
| 1640 } | 1693 } |
| 1641 reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); | 1694 reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); |
| 1642 return null; | 1695 return null; |
| 1643 } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)
) && matches4(peek2(3), TokenType.OPEN_PAREN)) { | 1696 } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)
) && matches4(peek2(3), TokenType.OPEN_PAREN)) { |
| 1644 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, val
idateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleId
entifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList()); | 1697 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, val
idateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleId
entifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList()); |
| 1645 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { | 1698 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { |
| 1646 SimpleIdentifier methodName = parseSimpleIdentifier(); | 1699 SimpleIdentifier methodName = parseSimpleIdentifier(); |
| 1647 FormalParameterList parameters = parseFormalParameterList(); | 1700 FormalParameterList parameters = parseFormalParameterList(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1662 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1715 validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1663 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, type); | 1716 return parseGetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, type); |
| 1664 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) { | 1717 } else if (matches(Keyword.SET) && matchesIdentifier2(peek())) { |
| 1665 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1718 validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1666 return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, type); | 1719 return parseSetter(commentAndMetadata, modifiers.externalKeyword, modifier
s.staticKeyword, type); |
| 1667 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { | 1720 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { |
| 1668 validateModifiersForOperator(modifiers); | 1721 validateModifiersForOperator(modifiers); |
| 1669 return parseOperator(commentAndMetadata, modifiers.externalKeyword, type); | 1722 return parseOperator(commentAndMetadata, modifiers.externalKeyword, type); |
| 1670 } else if (!matchesIdentifier()) { | 1723 } else if (!matchesIdentifier()) { |
| 1671 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { | 1724 if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { |
| 1725 // |
| 1726 // We appear to have found an incomplete declaration at the end of the c
lass. At this point |
| 1727 // it consists of a type name, so we'll treat it as a field declaration
with a missing |
| 1728 // field name and semicolon. |
| 1729 // |
| 1672 return parseInitializedIdentifierList(commentAndMetadata, modifiers.stat
icKeyword, validateModifiersForField(modifiers), type); | 1730 return parseInitializedIdentifierList(commentAndMetadata, modifiers.stat
icKeyword, validateModifiersForField(modifiers), type); |
| 1673 } | 1731 } |
| 1674 if (isOperator(_currentToken)) { | 1732 if (isOperator(_currentToken)) { |
| 1733 // |
| 1734 // We appear to have found an operator declaration without the 'operator
' keyword. |
| 1735 // |
| 1675 validateModifiersForOperator(modifiers); | 1736 validateModifiersForOperator(modifiers); |
| 1676 return parseOperator(commentAndMetadata, modifiers.externalKeyword, type
); | 1737 return parseOperator(commentAndMetadata, modifiers.externalKeyword, type
); |
| 1677 } | 1738 } |
| 1739 // |
| 1740 // We appear to have found an incomplete declaration before another declar
ation. |
| 1741 // At this point it consists of a type name, so we'll treat it as a field
declaration |
| 1742 // with a missing field name and semicolon. |
| 1743 // |
| 1678 reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); | 1744 reportError12(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); |
| 1679 try { | 1745 try { |
| 1680 lockErrorListener(); | 1746 lockErrorListener(); |
| 1681 return parseInitializedIdentifierList(commentAndMetadata, modifiers.stat
icKeyword, validateModifiersForField(modifiers), type); | 1747 return parseInitializedIdentifierList(commentAndMetadata, modifiers.stat
icKeyword, validateModifiersForField(modifiers), type); |
| 1682 } finally { | 1748 } finally { |
| 1683 unlockErrorListener(); | 1749 unlockErrorListener(); |
| 1684 } | 1750 } |
| 1685 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { | 1751 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { |
| 1686 SimpleIdentifier methodName = parseSimpleIdentifier(); | 1752 SimpleIdentifier methodName = parseSimpleIdentifier(); |
| 1687 FormalParameterList parameters = parseFormalParameterList(); | 1753 FormalParameterList parameters = parseFormalParameterList(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1717 * </pre> | 1783 * </pre> |
| 1718 * | 1784 * |
| 1719 * @return the compilation unit that was parsed | 1785 * @return the compilation unit that was parsed |
| 1720 */ | 1786 */ |
| 1721 CompilationUnit parseCompilationUnit2() { | 1787 CompilationUnit parseCompilationUnit2() { |
| 1722 Token firstToken = _currentToken; | 1788 Token firstToken = _currentToken; |
| 1723 ScriptTag scriptTag = null; | 1789 ScriptTag scriptTag = null; |
| 1724 if (matches5(TokenType.SCRIPT_TAG)) { | 1790 if (matches5(TokenType.SCRIPT_TAG)) { |
| 1725 scriptTag = new ScriptTag(andAdvance); | 1791 scriptTag = new ScriptTag(andAdvance); |
| 1726 } | 1792 } |
| 1793 // |
| 1794 // Even though all directives must appear before declarations and must occur
in a given order, |
| 1795 // we allow directives and declarations to occur in any order so that we can
recover better. |
| 1796 // |
| 1727 bool libraryDirectiveFound = false; | 1797 bool libraryDirectiveFound = false; |
| 1728 bool partOfDirectiveFound = false; | 1798 bool partOfDirectiveFound = false; |
| 1729 bool partDirectiveFound = false; | 1799 bool partDirectiveFound = false; |
| 1730 bool directiveFoundAfterDeclaration = false; | 1800 bool directiveFoundAfterDeclaration = false; |
| 1731 List<Directive> directives = new List<Directive>(); | 1801 List<Directive> directives = new List<Directive>(); |
| 1732 List<CompilationUnitMember> declarations = new List<CompilationUnitMember>()
; | 1802 List<CompilationUnitMember> declarations = new List<CompilationUnitMember>()
; |
| 1733 Token memberStart = _currentToken; | 1803 Token memberStart = _currentToken; |
| 1734 while (!matches5(TokenType.EOF)) { | 1804 while (!matches5(TokenType.EOF)) { |
| 1735 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 1805 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 1736 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword
.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !m
atches4(peek(), TokenType.LT) && !matches4(peek(), TokenType.OPEN_PAREN)) { | 1806 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword
.LIBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !m
atches4(peek(), TokenType.LT) && !matches4(peek(), TokenType.OPEN_PAREN)) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1848 * </pre> | 1918 * </pre> |
| 1849 * | 1919 * |
| 1850 * @return the expression that was parsed | 1920 * @return the expression that was parsed |
| 1851 */ | 1921 */ |
| 1852 Expression parseExpression3() { | 1922 Expression parseExpression3() { |
| 1853 if (matches(Keyword.THROW)) { | 1923 if (matches(Keyword.THROW)) { |
| 1854 return parseThrowExpression(); | 1924 return parseThrowExpression(); |
| 1855 } else if (matches(Keyword.RETHROW)) { | 1925 } else if (matches(Keyword.RETHROW)) { |
| 1856 return parseRethrowExpression(); | 1926 return parseRethrowExpression(); |
| 1857 } | 1927 } |
| 1928 // |
| 1929 // assignableExpression is a subset of conditionalExpression, so we can pars
e a conditional |
| 1930 // expression and then determine whether it is followed by an assignmentOper
ator, checking for |
| 1931 // conformance to the restricted grammar after making that determination. |
| 1932 // |
| 1858 Expression expression = parseConditionalExpression(); | 1933 Expression expression = parseConditionalExpression(); |
| 1859 TokenType tokenType = _currentToken.type; | 1934 TokenType tokenType = _currentToken.type; |
| 1860 if (identical(tokenType, TokenType.PERIOD_PERIOD)) { | 1935 if (identical(tokenType, TokenType.PERIOD_PERIOD)) { |
| 1861 List<Expression> cascadeSections = new List<Expression>(); | 1936 List<Expression> cascadeSections = new List<Expression>(); |
| 1862 while (identical(tokenType, TokenType.PERIOD_PERIOD)) { | 1937 while (identical(tokenType, TokenType.PERIOD_PERIOD)) { |
| 1863 Expression section = parseCascadeSection(); | 1938 Expression section = parseCascadeSection(); |
| 1864 if (section != null) { | 1939 if (section != null) { |
| 1865 cascadeSections.add(section); | 1940 cascadeSections.add(section); |
| 1866 } | 1941 } |
| 1867 tokenType = _currentToken.type; | 1942 tokenType = _currentToken.type; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1886 * </pre> | 1961 * </pre> |
| 1887 * | 1962 * |
| 1888 * @return the expression that was parsed | 1963 * @return the expression that was parsed |
| 1889 */ | 1964 */ |
| 1890 Expression parseExpressionWithoutCascade() { | 1965 Expression parseExpressionWithoutCascade() { |
| 1891 if (matches(Keyword.THROW)) { | 1966 if (matches(Keyword.THROW)) { |
| 1892 return parseThrowExpressionWithoutCascade(); | 1967 return parseThrowExpressionWithoutCascade(); |
| 1893 } else if (matches(Keyword.RETHROW)) { | 1968 } else if (matches(Keyword.RETHROW)) { |
| 1894 return parseRethrowExpression(); | 1969 return parseRethrowExpression(); |
| 1895 } | 1970 } |
| 1971 // |
| 1972 // assignableExpression is a subset of conditionalExpression, so we can pars
e a conditional |
| 1973 // expression and then determine whether it is followed by an assignmentOper
ator, checking for |
| 1974 // conformance to the restricted grammar after making that determination. |
| 1975 // |
| 1896 Expression expression = parseConditionalExpression(); | 1976 Expression expression = parseConditionalExpression(); |
| 1897 if (_currentToken.type.isAssignmentOperator) { | 1977 if (_currentToken.type.isAssignmentOperator) { |
| 1898 Token operator = andAdvance; | 1978 Token operator = andAdvance; |
| 1899 ensureAssignable(expression); | 1979 ensureAssignable(expression); |
| 1900 expression = new AssignmentExpression(expression, operator, parseExpressio
nWithoutCascade()); | 1980 expression = new AssignmentExpression(expression, operator, parseExpressio
nWithoutCascade()); |
| 1901 } | 1981 } |
| 1902 return expression; | 1982 return expression; |
| 1903 } | 1983 } |
| 1904 | 1984 |
| 1905 /** | 1985 /** |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1941 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}' | 2021 * '{' defaultNamedParameter (',' defaultNamedParameter)* '}' |
| 1942 * </pre> | 2022 * </pre> |
| 1943 * | 2023 * |
| 1944 * @return the formal parameters that were parsed | 2024 * @return the formal parameters that were parsed |
| 1945 */ | 2025 */ |
| 1946 FormalParameterList parseFormalParameterList() { | 2026 FormalParameterList parseFormalParameterList() { |
| 1947 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); | 2027 Token leftParenthesis = expect2(TokenType.OPEN_PAREN); |
| 1948 if (matches5(TokenType.CLOSE_PAREN)) { | 2028 if (matches5(TokenType.CLOSE_PAREN)) { |
| 1949 return new FormalParameterList(leftParenthesis, null, null, null, andAdvan
ce); | 2029 return new FormalParameterList(leftParenthesis, null, null, null, andAdvan
ce); |
| 1950 } | 2030 } |
| 2031 // |
| 2032 // Even though it is invalid to have default parameters outside of brackets,
required parameters |
| 2033 // inside of brackets, or multiple groups of default and named parameters, w
e allow all of these |
| 2034 // cases so that we can recover better. |
| 2035 // |
| 1951 List<FormalParameter> parameters = new List<FormalParameter>(); | 2036 List<FormalParameter> parameters = new List<FormalParameter>(); |
| 1952 List<FormalParameter> normalParameters = new List<FormalParameter>(); | 2037 List<FormalParameter> normalParameters = new List<FormalParameter>(); |
| 1953 List<FormalParameter> positionalParameters = new List<FormalParameter>(); | 2038 List<FormalParameter> positionalParameters = new List<FormalParameter>(); |
| 1954 List<FormalParameter> namedParameters = new List<FormalParameter>(); | 2039 List<FormalParameter> namedParameters = new List<FormalParameter>(); |
| 1955 List<FormalParameter> currentParameters = normalParameters; | 2040 List<FormalParameter> currentParameters = normalParameters; |
| 1956 Token leftSquareBracket = null; | 2041 Token leftSquareBracket = null; |
| 1957 Token rightSquareBracket = null; | 2042 Token rightSquareBracket = null; |
| 1958 Token leftCurlyBracket = null; | 2043 Token leftCurlyBracket = null; |
| 1959 Token rightCurlyBracket = null; | 2044 Token rightCurlyBracket = null; |
| 1960 ParameterKind kind = ParameterKind.REQUIRED; | 2045 ParameterKind kind = ParameterKind.REQUIRED; |
| 1961 bool firstParameter = true; | 2046 bool firstParameter = true; |
| 1962 bool reportedMuliplePositionalGroups = false; | 2047 bool reportedMuliplePositionalGroups = false; |
| 1963 bool reportedMulipleNamedGroups = false; | 2048 bool reportedMulipleNamedGroups = false; |
| 1964 bool reportedMixedGroups = false; | 2049 bool reportedMixedGroups = false; |
| 1965 bool wasOptionalParameter = false; | 2050 bool wasOptionalParameter = false; |
| 1966 Token initialToken = null; | 2051 Token initialToken = null; |
| 1967 do { | 2052 do { |
| 1968 if (firstParameter) { | 2053 if (firstParameter) { |
| 1969 firstParameter = false; | 2054 firstParameter = false; |
| 1970 } else if (!optional(TokenType.COMMA)) { | 2055 } else if (!optional(TokenType.COMMA)) { |
| 2056 // TODO(brianwilkerson) The token is wrong, we need to recover from this
case. |
| 1971 if (getEndToken(leftParenthesis) != null) { | 2057 if (getEndToken(leftParenthesis) != null) { |
| 1972 reportError11(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]
); | 2058 reportError11(ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]
); |
| 1973 } else { | 2059 } else { |
| 1974 reportError12(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentTok
en.previous, []); | 2060 reportError12(ParserErrorCode.MISSING_CLOSING_PARENTHESIS, _currentTok
en.previous, []); |
| 1975 break; | 2061 break; |
| 1976 } | 2062 } |
| 1977 } | 2063 } |
| 1978 initialToken = _currentToken; | 2064 initialToken = _currentToken; |
| 2065 // |
| 2066 // Handle the beginning of parameter groups. |
| 2067 // |
| 1979 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { | 2068 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { |
| 1980 wasOptionalParameter = true; | 2069 wasOptionalParameter = true; |
| 1981 if (leftSquareBracket != null && !reportedMuliplePositionalGroups) { | 2070 if (leftSquareBracket != null && !reportedMuliplePositionalGroups) { |
| 1982 reportError11(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []
); | 2071 reportError11(ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS, []
); |
| 1983 reportedMuliplePositionalGroups = true; | 2072 reportedMuliplePositionalGroups = true; |
| 1984 } | 2073 } |
| 1985 if (leftCurlyBracket != null && !reportedMixedGroups) { | 2074 if (leftCurlyBracket != null && !reportedMixedGroups) { |
| 1986 reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); | 2075 reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); |
| 1987 reportedMixedGroups = true; | 2076 reportedMixedGroups = true; |
| 1988 } | 2077 } |
| 1989 leftSquareBracket = andAdvance; | 2078 leftSquareBracket = andAdvance; |
| 1990 currentParameters = positionalParameters; | 2079 currentParameters = positionalParameters; |
| 1991 kind = ParameterKind.POSITIONAL; | 2080 kind = ParameterKind.POSITIONAL; |
| 1992 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { | 2081 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { |
| 1993 wasOptionalParameter = true; | 2082 wasOptionalParameter = true; |
| 1994 if (leftCurlyBracket != null && !reportedMulipleNamedGroups) { | 2083 if (leftCurlyBracket != null && !reportedMulipleNamedGroups) { |
| 1995 reportError11(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []); | 2084 reportError11(ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS, []); |
| 1996 reportedMulipleNamedGroups = true; | 2085 reportedMulipleNamedGroups = true; |
| 1997 } | 2086 } |
| 1998 if (leftSquareBracket != null && !reportedMixedGroups) { | 2087 if (leftSquareBracket != null && !reportedMixedGroups) { |
| 1999 reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); | 2088 reportError11(ParserErrorCode.MIXED_PARAMETER_GROUPS, []); |
| 2000 reportedMixedGroups = true; | 2089 reportedMixedGroups = true; |
| 2001 } | 2090 } |
| 2002 leftCurlyBracket = andAdvance; | 2091 leftCurlyBracket = andAdvance; |
| 2003 currentParameters = namedParameters; | 2092 currentParameters = namedParameters; |
| 2004 kind = ParameterKind.NAMED; | 2093 kind = ParameterKind.NAMED; |
| 2005 } | 2094 } |
| 2095 // |
| 2096 // Parse and record the parameter. |
| 2097 // |
| 2006 FormalParameter parameter = parseFormalParameter(kind); | 2098 FormalParameter parameter = parseFormalParameter(kind); |
| 2007 parameters.add(parameter); | 2099 parameters.add(parameter); |
| 2008 currentParameters.add(parameter); | 2100 currentParameters.add(parameter); |
| 2009 if (identical(kind, ParameterKind.REQUIRED) && wasOptionalParameter) { | 2101 if (identical(kind, ParameterKind.REQUIRED) && wasOptionalParameter) { |
| 2010 reportError10(ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, paramet
er, []); | 2102 reportError10(ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, paramet
er, []); |
| 2011 } | 2103 } |
| 2104 // |
| 2105 // Handle the end of parameter groups. |
| 2106 // |
| 2107 // TODO(brianwilkerson) Improve the detection and reporting of missing and
mismatched delimiters. |
| 2012 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { | 2108 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { |
| 2013 rightSquareBracket = andAdvance; | 2109 rightSquareBracket = andAdvance; |
| 2014 currentParameters = normalParameters; | 2110 currentParameters = normalParameters; |
| 2015 if (leftSquareBracket == null) { | 2111 if (leftSquareBracket == null) { |
| 2016 if (leftCurlyBracket != null) { | 2112 if (leftCurlyBracket != null) { |
| 2017 reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
["}"]); | 2113 reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
["}"]); |
| 2018 rightCurlyBracket = rightSquareBracket; | 2114 rightCurlyBracket = rightSquareBracket; |
| 2019 rightSquareBracket = null; | 2115 rightSquareBracket = null; |
| 2020 } else { | 2116 } else { |
| 2021 reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GR
OUP, ["["]); | 2117 reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GR
OUP, ["["]); |
| 2022 } | 2118 } |
| 2023 } | 2119 } |
| 2024 kind = ParameterKind.REQUIRED; | 2120 kind = ParameterKind.REQUIRED; |
| 2025 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { | 2121 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { |
| 2026 rightCurlyBracket = andAdvance; | 2122 rightCurlyBracket = andAdvance; |
| 2027 currentParameters = normalParameters; | 2123 currentParameters = normalParameters; |
| 2028 if (leftCurlyBracket == null) { | 2124 if (leftCurlyBracket == null) { |
| 2029 if (leftSquareBracket != null) { | 2125 if (leftSquareBracket != null) { |
| 2030 reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
["]"]); | 2126 reportError11(ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
["]"]); |
| 2031 rightSquareBracket = rightCurlyBracket; | 2127 rightSquareBracket = rightCurlyBracket; |
| 2032 rightCurlyBracket = null; | 2128 rightCurlyBracket = null; |
| 2033 } else { | 2129 } else { |
| 2034 reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GR
OUP, ["{"]); | 2130 reportError11(ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GR
OUP, ["{"]); |
| 2035 } | 2131 } |
| 2036 } | 2132 } |
| 2037 kind = ParameterKind.REQUIRED; | 2133 kind = ParameterKind.REQUIRED; |
| 2038 } | 2134 } |
| 2039 } while (!matches5(TokenType.CLOSE_PAREN) && initialToken != _currentToken); | 2135 } while (!matches5(TokenType.CLOSE_PAREN) && initialToken != _currentToken); |
| 2040 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); | 2136 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); |
| 2137 // |
| 2138 // Check that the groups were closed correctly. |
| 2139 // |
| 2041 if (leftSquareBracket != null && rightSquareBracket == null) { | 2140 if (leftSquareBracket != null && rightSquareBracket == null) { |
| 2042 reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"
]); | 2141 reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"
]); |
| 2043 } | 2142 } |
| 2044 if (leftCurlyBracket != null && rightCurlyBracket == null) { | 2143 if (leftCurlyBracket != null && rightCurlyBracket == null) { |
| 2045 reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"
]); | 2144 reportError11(ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"
]); |
| 2046 } | 2145 } |
| 2146 // |
| 2147 // Build the parameter list. |
| 2148 // |
| 2047 if (leftSquareBracket == null) { | 2149 if (leftSquareBracket == null) { |
| 2048 leftSquareBracket = leftCurlyBracket; | 2150 leftSquareBracket = leftCurlyBracket; |
| 2049 } | 2151 } |
| 2050 if (rightSquareBracket == null) { | 2152 if (rightSquareBracket == null) { |
| 2051 rightSquareBracket = rightCurlyBracket; | 2153 rightSquareBracket = rightCurlyBracket; |
| 2052 } | 2154 } |
| 2053 return new FormalParameterList(leftParenthesis, parameters, leftSquareBracke
t, rightSquareBracket, rightParenthesis); | 2155 return new FormalParameterList(leftParenthesis, parameters, leftSquareBracke
t, rightSquareBracket, rightParenthesis); |
| 2054 } | 2156 } |
| 2055 | 2157 |
| 2056 /** | 2158 /** |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2535 | 2637 |
| 2536 /** | 2638 /** |
| 2537 * Return `true` if the current token could be the start of a compilation unit
member. This | 2639 * Return `true` if the current token could be the start of a compilation unit
member. This |
| 2538 * method is used for recovery purposes to decide when to stop skipping tokens
after finding an | 2640 * method is used for recovery purposes to decide when to stop skipping tokens
after finding an |
| 2539 * error while parsing a compilation unit member. | 2641 * error while parsing a compilation unit member. |
| 2540 * | 2642 * |
| 2541 * @return `true` if the current token could be the start of a compilation uni
t member | 2643 * @return `true` if the current token could be the start of a compilation uni
t member |
| 2542 */ | 2644 */ |
| 2543 bool couldBeStartOfCompilationUnitMember() { | 2645 bool couldBeStartOfCompilationUnitMember() { |
| 2544 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L
IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat
ches4(peek(), TokenType.LT)) { | 2646 if ((matches(Keyword.IMPORT) || matches(Keyword.EXPORT) || matches(Keyword.L
IBRARY) || matches(Keyword.PART)) && !matches4(peek(), TokenType.PERIOD) && !mat
ches4(peek(), TokenType.LT)) { |
| 2647 // This looks like the start of a directive |
| 2545 return true; | 2648 return true; |
| 2546 } else if (matches(Keyword.CLASS)) { | 2649 } else if (matches(Keyword.CLASS)) { |
| 2650 // This looks like the start of a class definition |
| 2547 return true; | 2651 return true; |
| 2548 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) &
& !matches4(peek(), TokenType.LT)) { | 2652 } else if (matches(Keyword.TYPEDEF) && !matches4(peek(), TokenType.PERIOD) &
& !matches4(peek(), TokenType.LT)) { |
| 2653 // This looks like the start of a typedef |
| 2549 return true; | 2654 return true; |
| 2550 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor
d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat
or(peek()))) { | 2655 } else if (matches(Keyword.VOID) || ((matches(Keyword.GET) || matches(Keywor
d.SET)) && matchesIdentifier2(peek())) || (matches(Keyword.OPERATOR) && isOperat
or(peek()))) { |
| 2656 // This looks like the start of a function |
| 2551 return true; | 2657 return true; |
| 2552 } else if (matchesIdentifier()) { | 2658 } else if (matchesIdentifier()) { |
| 2553 if (matches4(peek(), TokenType.OPEN_PAREN)) { | 2659 if (matches4(peek(), TokenType.OPEN_PAREN)) { |
| 2660 // This looks like the start of a function |
| 2554 return true; | 2661 return true; |
| 2555 } | 2662 } |
| 2556 Token token = skipReturnType(_currentToken); | 2663 Token token = skipReturnType(_currentToken); |
| 2557 if (token == null) { | 2664 if (token == null) { |
| 2558 return false; | 2665 return false; |
| 2559 } | 2666 } |
| 2560 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA
TOR) && isOperator(peek())) || matchesIdentifier()) { | 2667 if (matches(Keyword.GET) || matches(Keyword.SET) || (matches(Keyword.OPERA
TOR) && isOperator(peek())) || matchesIdentifier()) { |
| 2561 return true; | 2668 return true; |
| 2562 } | 2669 } |
| 2563 } | 2670 } |
| 2564 return false; | 2671 return false; |
| 2565 } | 2672 } |
| 2566 | 2673 |
| 2567 /** | 2674 /** |
| 2568 * Create a synthetic identifier. | 2675 * Create a synthetic identifier. |
| 2569 * | 2676 * |
| 2570 * @return the synthetic identifier that was created | 2677 * @return the synthetic identifier that was created |
| 2571 */ | 2678 */ |
| 2572 SimpleIdentifier createSyntheticIdentifier() { | 2679 SimpleIdentifier createSyntheticIdentifier() { |
| 2573 Token syntheticToken; | 2680 Token syntheticToken; |
| 2574 if (identical(_currentToken.type, TokenType.KEYWORD)) { | 2681 if (identical(_currentToken.type, TokenType.KEYWORD)) { |
| 2682 // Consider current keyword token as an identifier. |
| 2683 // It is not always true, e.g. "^is T" where "^" is place the place for sy
nthetic identifier. |
| 2684 // By creating SyntheticStringToken we can distinguish a real identifier f
rom synthetic. |
| 2685 // In the code completion behavior will depend on a cursor position - befo
re or on "is". |
| 2575 syntheticToken = injectToken(new SyntheticStringToken(TokenType.IDENTIFIER
, _currentToken.lexeme, _currentToken.offset)); | 2686 syntheticToken = injectToken(new SyntheticStringToken(TokenType.IDENTIFIER
, _currentToken.lexeme, _currentToken.offset)); |
| 2576 } else { | 2687 } else { |
| 2577 syntheticToken = createSyntheticToken2(TokenType.IDENTIFIER); | 2688 syntheticToken = createSyntheticToken2(TokenType.IDENTIFIER); |
| 2578 } | 2689 } |
| 2579 return new SimpleIdentifier(syntheticToken); | 2690 return new SimpleIdentifier(syntheticToken); |
| 2580 } | 2691 } |
| 2581 | 2692 |
| 2582 /** | 2693 /** |
| 2583 * Create a synthetic string literal. | 2694 * Create a synthetic string literal. |
| 2584 * | 2695 * |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2626 * If the current token is a keyword matching the given string, return it afte
r advancing to the | 2737 * If the current token is a keyword matching the given string, return it afte
r advancing to the |
| 2627 * next token. Otherwise report an error and return the current token without
advancing. | 2738 * next token. Otherwise report an error and return the current token without
advancing. |
| 2628 * | 2739 * |
| 2629 * @param keyword the keyword that is expected | 2740 * @param keyword the keyword that is expected |
| 2630 * @return the token that matched the given type | 2741 * @return the token that matched the given type |
| 2631 */ | 2742 */ |
| 2632 Token expect(Keyword keyword) { | 2743 Token expect(Keyword keyword) { |
| 2633 if (matches(keyword)) { | 2744 if (matches(keyword)) { |
| 2634 return andAdvance; | 2745 return andAdvance; |
| 2635 } | 2746 } |
| 2747 // Remove uses of this method in favor of matches? |
| 2748 // Pass in the error code to use to report the error? |
| 2636 reportError11(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]); | 2749 reportError11(ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]); |
| 2637 return _currentToken; | 2750 return _currentToken; |
| 2638 } | 2751 } |
| 2639 | 2752 |
| 2640 /** | 2753 /** |
| 2641 * If the current token has the expected type, return it after advancing to th
e next token. | 2754 * If the current token has the expected type, return it after advancing to th
e next token. |
| 2642 * Otherwise report an error and return the current token without advancing. | 2755 * Otherwise report an error and return the current token without advancing. |
| 2643 * | 2756 * |
| 2644 * @param type the type of token that is expected | 2757 * @param type the type of token that is expected |
| 2645 * @return the token that matched the given type | 2758 * @return the token that matched the given type |
| 2646 */ | 2759 */ |
| 2647 Token expect2(TokenType type) { | 2760 Token expect2(TokenType type) { |
| 2648 if (matches5(type)) { | 2761 if (matches5(type)) { |
| 2649 return andAdvance; | 2762 return andAdvance; |
| 2650 } | 2763 } |
| 2764 // Remove uses of this method in favor of matches? |
| 2765 // Pass in the error code to use to report the error? |
| 2651 if (identical(type, TokenType.SEMICOLON)) { | 2766 if (identical(type, TokenType.SEMICOLON)) { |
| 2652 reportError12(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [typ
e.lexeme]); | 2767 reportError12(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [typ
e.lexeme]); |
| 2653 } else { | 2768 } else { |
| 2654 reportError11(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); | 2769 reportError11(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); |
| 2655 } | 2770 } |
| 2656 return _currentToken; | 2771 return _currentToken; |
| 2657 } | 2772 } |
| 2658 | 2773 |
| 2659 /** | 2774 /** |
| 2660 * Search the given list of ranges for a range that contains the given index.
Return the range | 2775 * Search the given list of ranges for a range that contains the given index.
Return the range |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2779 * Return `true` if the current token appears to be the beginning of a functio
n declaration. | 2894 * Return `true` if the current token appears to be the beginning of a functio
n declaration. |
| 2780 * | 2895 * |
| 2781 * @return `true` if the current token appears to be the beginning of a functi
on declaration | 2896 * @return `true` if the current token appears to be the beginning of a functi
on declaration |
| 2782 */ | 2897 */ |
| 2783 bool isFunctionDeclaration() { | 2898 bool isFunctionDeclaration() { |
| 2784 if (matches(Keyword.VOID)) { | 2899 if (matches(Keyword.VOID)) { |
| 2785 return true; | 2900 return true; |
| 2786 } | 2901 } |
| 2787 Token afterReturnType = skipTypeName(_currentToken); | 2902 Token afterReturnType = skipTypeName(_currentToken); |
| 2788 if (afterReturnType == null) { | 2903 if (afterReturnType == null) { |
| 2904 // There was no return type, but it is optional, so go back to where we st
arted. |
| 2789 afterReturnType = _currentToken; | 2905 afterReturnType = _currentToken; |
| 2790 } | 2906 } |
| 2791 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); | 2907 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); |
| 2792 if (afterIdentifier == null) { | 2908 if (afterIdentifier == null) { |
| 2909 // It's possible that we parsed the function name as if it were a type nam
e, so see whether |
| 2910 // it makes sense if we assume that there is no type. |
| 2793 afterIdentifier = skipSimpleIdentifier(_currentToken); | 2911 afterIdentifier = skipSimpleIdentifier(_currentToken); |
| 2794 } | 2912 } |
| 2795 if (afterIdentifier == null) { | 2913 if (afterIdentifier == null) { |
| 2796 return false; | 2914 return false; |
| 2797 } | 2915 } |
| 2798 if (isFunctionExpression(afterIdentifier)) { | 2916 if (isFunctionExpression(afterIdentifier)) { |
| 2799 return true; | 2917 return true; |
| 2800 } | 2918 } |
| 2919 // It's possible that we have found a getter. While this isn't valid at this
point we test for |
| 2920 // it in order to recover better. |
| 2801 if (matches(Keyword.GET)) { | 2921 if (matches(Keyword.GET)) { |
| 2802 Token afterName = skipSimpleIdentifier(_currentToken.next); | 2922 Token afterName = skipSimpleIdentifier(_currentToken.next); |
| 2803 if (afterName == null) { | 2923 if (afterName == null) { |
| 2804 return false; | 2924 return false; |
| 2805 } | 2925 } |
| 2806 return matches4(afterName, TokenType.FUNCTION) || matches4(afterName, Toke
nType.OPEN_CURLY_BRACKET); | 2926 return matches4(afterName, TokenType.FUNCTION) || matches4(afterName, Toke
nType.OPEN_CURLY_BRACKET); |
| 2807 } | 2927 } |
| 2808 return false; | 2928 return false; |
| 2809 } | 2929 } |
| 2810 | 2930 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2853 * | 2973 * |
| 2854 * initializedIdentifier ::= | 2974 * initializedIdentifier ::= |
| 2855 * identifier ('=' expression)? | 2975 * identifier ('=' expression)? |
| 2856 * </pre> | 2976 * </pre> |
| 2857 * | 2977 * |
| 2858 * @return `true` if the current token is the first token in an initialized va
riable | 2978 * @return `true` if the current token is the first token in an initialized va
riable |
| 2859 * declaration | 2979 * declaration |
| 2860 */ | 2980 */ |
| 2861 bool isInitializedVariableDeclaration() { | 2981 bool isInitializedVariableDeclaration() { |
| 2862 if (matches(Keyword.FINAL) || matches(Keyword.VAR)) { | 2982 if (matches(Keyword.FINAL) || matches(Keyword.VAR)) { |
| 2983 // An expression cannot start with a keyword other than 'const', 'rethrow'
, or 'throw'. |
| 2863 return true; | 2984 return true; |
| 2864 } | 2985 } |
| 2865 if (matches(Keyword.CONST)) { | 2986 if (matches(Keyword.CONST)) { |
| 2987 // Look to see whether we might be at the start of a list or map literal,
otherwise this |
| 2988 // should be the start of a variable declaration. |
| 2866 return !matchesAny(peek(), [ | 2989 return !matchesAny(peek(), [ |
| 2867 TokenType.LT, | 2990 TokenType.LT, |
| 2868 TokenType.OPEN_CURLY_BRACKET, | 2991 TokenType.OPEN_CURLY_BRACKET, |
| 2869 TokenType.OPEN_SQUARE_BRACKET, | 2992 TokenType.OPEN_SQUARE_BRACKET, |
| 2870 TokenType.INDEX]); | 2993 TokenType.INDEX]); |
| 2871 } | 2994 } |
| 2995 // We know that we have an identifier, and need to see whether it might be a
type name. |
| 2872 Token token = skipTypeName(_currentToken); | 2996 Token token = skipTypeName(_currentToken); |
| 2873 if (token == null) { | 2997 if (token == null) { |
| 2998 // There was no type name, so this can't be a declaration. |
| 2874 return false; | 2999 return false; |
| 2875 } | 3000 } |
| 2876 token = skipSimpleIdentifier(token); | 3001 token = skipSimpleIdentifier(token); |
| 2877 if (token == null) { | 3002 if (token == null) { |
| 2878 return false; | 3003 return false; |
| 2879 } | 3004 } |
| 2880 TokenType type = token.type; | 3005 TokenType type = token.type; |
| 2881 return identical(type, TokenType.EQ) || identical(type, TokenType.COMMA) ||
identical(type, TokenType.SEMICOLON) || matches3(token, Keyword.IN); | 3006 return identical(type, TokenType.EQ) || identical(type, TokenType.COMMA) ||
identical(type, TokenType.SEMICOLON) || matches3(token, Keyword.IN); |
| 2882 } | 3007 } |
| 2883 | 3008 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2913 return nextChar == 0x5B; | 3038 return nextChar == 0x5B; |
| 2914 } | 3039 } |
| 2915 | 3040 |
| 2916 /** | 3041 /** |
| 2917 * Return `true` if the given token appears to be the beginning of an operator
declaration. | 3042 * Return `true` if the given token appears to be the beginning of an operator
declaration. |
| 2918 * | 3043 * |
| 2919 * @param startToken the token that might be the start of an operator declarat
ion | 3044 * @param startToken the token that might be the start of an operator declarat
ion |
| 2920 * @return `true` if the given token appears to be the beginning of an operato
r declaration | 3045 * @return `true` if the given token appears to be the beginning of an operato
r declaration |
| 2921 */ | 3046 */ |
| 2922 bool isOperator(Token startToken) { | 3047 bool isOperator(Token startToken) { |
| 3048 // Accept any operator here, even if it is not user definable. |
| 2923 if (!startToken.isOperator) { | 3049 if (!startToken.isOperator) { |
| 2924 return false; | 3050 return false; |
| 2925 } | 3051 } |
| 3052 // Token "=" means that it is actually field initializer. |
| 2926 if (identical(startToken.type, TokenType.EQ)) { | 3053 if (identical(startToken.type, TokenType.EQ)) { |
| 2927 return false; | 3054 return false; |
| 2928 } | 3055 } |
| 3056 // Consume all operator tokens. |
| 2929 Token token = startToken.next; | 3057 Token token = startToken.next; |
| 2930 while (token.isOperator) { | 3058 while (token.isOperator) { |
| 2931 token = token.next; | 3059 token = token.next; |
| 2932 } | 3060 } |
| 3061 // Formal parameter list is expect now. |
| 2933 return matches4(token, TokenType.OPEN_PAREN); | 3062 return matches4(token, TokenType.OPEN_PAREN); |
| 2934 } | 3063 } |
| 2935 | 3064 |
| 2936 /** | 3065 /** |
| 2937 * Return `true` if the current token appears to be the beginning of a switch
member. | 3066 * Return `true` if the current token appears to be the beginning of a switch
member. |
| 2938 * | 3067 * |
| 2939 * @return `true` if the current token appears to be the beginning of a switch
member | 3068 * @return `true` if the current token appears to be the beginning of a switch
member |
| 2940 */ | 3069 */ |
| 2941 bool isSwitchMember() { | 3070 bool isSwitchMember() { |
| 2942 Token token = _currentToken; | 3071 Token token = _currentToken; |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3213 * </pre> | 3342 * </pre> |
| 3214 * | 3343 * |
| 3215 * @param primaryAllowed `true` if the expression is allowed to be a primary w
ithout any | 3344 * @param primaryAllowed `true` if the expression is allowed to be a primary w
ithout any |
| 3216 * assignable selector | 3345 * assignable selector |
| 3217 * @return the assignable expression that was parsed | 3346 * @return the assignable expression that was parsed |
| 3218 */ | 3347 */ |
| 3219 Expression parseAssignableExpression(bool primaryAllowed) { | 3348 Expression parseAssignableExpression(bool primaryAllowed) { |
| 3220 if (matches(Keyword.SUPER)) { | 3349 if (matches(Keyword.SUPER)) { |
| 3221 return parseAssignableSelector(new SuperExpression(andAdvance), false); | 3350 return parseAssignableSelector(new SuperExpression(andAdvance), false); |
| 3222 } | 3351 } |
| 3352 // |
| 3353 // A primary expression can start with an identifier. We resolve the ambigui
ty by determining |
| 3354 // whether the primary consists of anything other than an identifier and/or
is followed by an |
| 3355 // assignableSelector. |
| 3356 // |
| 3223 Expression expression = parsePrimaryExpression(); | 3357 Expression expression = parsePrimaryExpression(); |
| 3224 bool isOptional = primaryAllowed || expression is SimpleIdentifier; | 3358 bool isOptional = primaryAllowed || expression is SimpleIdentifier; |
| 3225 while (true) { | 3359 while (true) { |
| 3226 while (matches5(TokenType.OPEN_PAREN)) { | 3360 while (matches5(TokenType.OPEN_PAREN)) { |
| 3227 ArgumentList argumentList = parseArgumentList(); | 3361 ArgumentList argumentList = parseArgumentList(); |
| 3228 if (expression is SimpleIdentifier) { | 3362 if (expression is SimpleIdentifier) { |
| 3229 expression = new MethodInvocation(null, null, expression as SimpleIden
tifier, argumentList); | 3363 expression = new MethodInvocation(null, null, expression as SimpleIden
tifier, argumentList); |
| 3230 } else if (expression is PrefixedIdentifier) { | 3364 } else if (expression is PrefixedIdentifier) { |
| 3231 PrefixedIdentifier identifier = expression as PrefixedIdentifier; | 3365 PrefixedIdentifier identifier = expression as PrefixedIdentifier; |
| 3232 expression = new MethodInvocation(identifier.prefix, identifier.period
, identifier.identifier, argumentList); | 3366 expression = new MethodInvocation(identifier.prefix, identifier.period
, identifier.identifier, argumentList); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3270 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { | 3404 if (matches5(TokenType.OPEN_SQUARE_BRACKET)) { |
| 3271 Token leftBracket = andAdvance; | 3405 Token leftBracket = andAdvance; |
| 3272 Expression index = parseExpression3(); | 3406 Expression index = parseExpression3(); |
| 3273 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); | 3407 Token rightBracket = expect2(TokenType.CLOSE_SQUARE_BRACKET); |
| 3274 return new IndexExpression.forTarget(prefix, leftBracket, index, rightBrac
ket); | 3408 return new IndexExpression.forTarget(prefix, leftBracket, index, rightBrac
ket); |
| 3275 } else if (matches5(TokenType.PERIOD)) { | 3409 } else if (matches5(TokenType.PERIOD)) { |
| 3276 Token period = andAdvance; | 3410 Token period = andAdvance; |
| 3277 return new PropertyAccess(prefix, period, parseSimpleIdentifier()); | 3411 return new PropertyAccess(prefix, period, parseSimpleIdentifier()); |
| 3278 } else { | 3412 } else { |
| 3279 if (!optional) { | 3413 if (!optional) { |
| 3414 // Report the missing selector. |
| 3280 reportError11(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); | 3415 reportError11(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); |
| 3281 } | 3416 } |
| 3282 return prefix; | 3417 return prefix; |
| 3283 } | 3418 } |
| 3284 } | 3419 } |
| 3285 | 3420 |
| 3286 /** | 3421 /** |
| 3287 * Parse a bitwise and expression. | 3422 * Parse a bitwise and expression. |
| 3288 * | 3423 * |
| 3289 * <pre> | 3424 * <pre> |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3389 reportError12(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, [_current
Token.lexeme]); | 3524 reportError12(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, [_current
Token.lexeme]); |
| 3390 functionName = createSyntheticIdentifier(); | 3525 functionName = createSyntheticIdentifier(); |
| 3391 } | 3526 } |
| 3392 if (identical(_currentToken.type, TokenType.OPEN_PAREN)) { | 3527 if (identical(_currentToken.type, TokenType.OPEN_PAREN)) { |
| 3393 while (identical(_currentToken.type, TokenType.OPEN_PAREN)) { | 3528 while (identical(_currentToken.type, TokenType.OPEN_PAREN)) { |
| 3394 if (functionName != null) { | 3529 if (functionName != null) { |
| 3395 expression = new MethodInvocation(expression, period, functionName, pa
rseArgumentList()); | 3530 expression = new MethodInvocation(expression, period, functionName, pa
rseArgumentList()); |
| 3396 period = null; | 3531 period = null; |
| 3397 functionName = null; | 3532 functionName = null; |
| 3398 } else if (expression == null) { | 3533 } else if (expression == null) { |
| 3534 // It should not be possible to get here. |
| 3399 expression = new MethodInvocation(expression, period, createSyntheticI
dentifier(), parseArgumentList()); | 3535 expression = new MethodInvocation(expression, period, createSyntheticI
dentifier(), parseArgumentList()); |
| 3400 } else { | 3536 } else { |
| 3401 expression = new FunctionExpressionInvocation(expression, parseArgumen
tList()); | 3537 expression = new FunctionExpressionInvocation(expression, parseArgumen
tList()); |
| 3402 } | 3538 } |
| 3403 } | 3539 } |
| 3404 } else if (functionName != null) { | 3540 } else if (functionName != null) { |
| 3405 expression = new PropertyAccess(expression, period, functionName); | 3541 expression = new PropertyAccess(expression, period, functionName); |
| 3406 period = null; | 3542 period = null; |
| 3407 } | 3543 } |
| 3408 bool progress = true; | 3544 bool progress = true; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3456 } else if (matches4(next, TokenType.EQ)) { | 3592 } else if (matches4(next, TokenType.EQ)) { |
| 3457 return parseClassTypeAlias(commentAndMetadata, abstractKeyword, keyword)
; | 3593 return parseClassTypeAlias(commentAndMetadata, abstractKeyword, keyword)
; |
| 3458 } | 3594 } |
| 3459 } | 3595 } |
| 3460 SimpleIdentifier name = parseSimpleIdentifier(); | 3596 SimpleIdentifier name = parseSimpleIdentifier(); |
| 3461 String className = name.name; | 3597 String className = name.name; |
| 3462 TypeParameterList typeParameters = null; | 3598 TypeParameterList typeParameters = null; |
| 3463 if (matches5(TokenType.LT)) { | 3599 if (matches5(TokenType.LT)) { |
| 3464 typeParameters = parseTypeParameterList(); | 3600 typeParameters = parseTypeParameterList(); |
| 3465 } | 3601 } |
| 3602 // |
| 3603 // Parse the clauses. The parser accepts clauses in any order, but will gene
rate errors if they |
| 3604 // are not in the order required by the specification. |
| 3605 // |
| 3466 ExtendsClause extendsClause = null; | 3606 ExtendsClause extendsClause = null; |
| 3467 WithClause withClause = null; | 3607 WithClause withClause = null; |
| 3468 ImplementsClause implementsClause = null; | 3608 ImplementsClause implementsClause = null; |
| 3469 bool foundClause = true; | 3609 bool foundClause = true; |
| 3470 while (foundClause) { | 3610 while (foundClause) { |
| 3471 if (matches(Keyword.EXTENDS)) { | 3611 if (matches(Keyword.EXTENDS)) { |
| 3472 if (extendsClause == null) { | 3612 if (extendsClause == null) { |
| 3473 extendsClause = parseExtendsClause(); | 3613 extendsClause = parseExtendsClause(); |
| 3474 if (withClause != null) { | 3614 if (withClause != null) { |
| 3475 reportError12(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKe
yword, []); | 3615 reportError12(ParserErrorCode.WITH_BEFORE_EXTENDS, withClause.withKe
yword, []); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3497 reportError12(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsC
lause.keyword, []); | 3637 reportError12(ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, implementsC
lause.keyword, []); |
| 3498 parseImplementsClause(); | 3638 parseImplementsClause(); |
| 3499 } | 3639 } |
| 3500 } else { | 3640 } else { |
| 3501 foundClause = false; | 3641 foundClause = false; |
| 3502 } | 3642 } |
| 3503 } | 3643 } |
| 3504 if (withClause != null && extendsClause == null) { | 3644 if (withClause != null && extendsClause == null) { |
| 3505 reportError12(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword
, []); | 3645 reportError12(ParserErrorCode.WITH_WITHOUT_EXTENDS, withClause.withKeyword
, []); |
| 3506 } | 3646 } |
| 3647 // |
| 3648 // Look for and skip over the extra-lingual 'native' specification. |
| 3649 // |
| 3507 NativeClause nativeClause = null; | 3650 NativeClause nativeClause = null; |
| 3508 if (matches2(_NATIVE) && matches4(peek(), TokenType.STRING)) { | 3651 if (matches2(_NATIVE) && matches4(peek(), TokenType.STRING)) { |
| 3509 nativeClause = parseNativeClause(); | 3652 nativeClause = parseNativeClause(); |
| 3510 } | 3653 } |
| 3654 // |
| 3655 // Parse the body of the class. |
| 3656 // |
| 3511 Token leftBracket = null; | 3657 Token leftBracket = null; |
| 3512 List<ClassMember> members = null; | 3658 List<ClassMember> members = null; |
| 3513 Token rightBracket = null; | 3659 Token rightBracket = null; |
| 3514 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { | 3660 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { |
| 3515 leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); | 3661 leftBracket = expect2(TokenType.OPEN_CURLY_BRACKET); |
| 3516 members = parseClassMembers(className, getEndToken(leftBracket)); | 3662 members = parseClassMembers(className, getEndToken(leftBracket)); |
| 3517 rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); | 3663 rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); |
| 3518 } else { | 3664 } else { |
| 3519 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET); | 3665 leftBracket = createSyntheticToken2(TokenType.OPEN_CURLY_BRACKET); |
| 3520 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET); | 3666 rightBracket = createSyntheticToken2(TokenType.CLOSE_CURLY_BRACKET); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3670 * commentReference ::= | 3816 * commentReference ::= |
| 3671 * 'new'? prefixedIdentifier | 3817 * 'new'? prefixedIdentifier |
| 3672 * </pre> | 3818 * </pre> |
| 3673 * | 3819 * |
| 3674 * @param referenceSource the source occurring between the square brackets wit
hin a documentation | 3820 * @param referenceSource the source occurring between the square brackets wit
hin a documentation |
| 3675 * comment | 3821 * comment |
| 3676 * @param sourceOffset the offset of the first character of the reference sour
ce | 3822 * @param sourceOffset the offset of the first character of the reference sour
ce |
| 3677 * @return the comment reference that was parsed, or `null` if no reference co
uld be found | 3823 * @return the comment reference that was parsed, or `null` if no reference co
uld be found |
| 3678 */ | 3824 */ |
| 3679 CommentReference parseCommentReference(String referenceSource, int sourceOffse
t) { | 3825 CommentReference parseCommentReference(String referenceSource, int sourceOffse
t) { |
| 3826 // TODO(brianwilkerson) The errors are not getting the right offset/length a
nd are being duplicated. |
| 3680 if (referenceSource.length == 0) { | 3827 if (referenceSource.length == 0) { |
| 3681 return null; | 3828 return null; |
| 3682 } | 3829 } |
| 3683 try { | 3830 try { |
| 3684 BooleanErrorListener listener = new BooleanErrorListener(); | 3831 BooleanErrorListener listener = new BooleanErrorListener(); |
| 3685 Scanner scanner = new Scanner(null, new SubSequenceReader(new CharSequence
(referenceSource), sourceOffset), listener); | 3832 Scanner scanner = new Scanner(null, new SubSequenceReader(new CharSequence
(referenceSource), sourceOffset), listener); |
| 3686 scanner.setSourceStart(1, 1); | 3833 scanner.setSourceStart(1, 1); |
| 3687 Token firstToken = scanner.tokenize(); | 3834 Token firstToken = scanner.tokenize(); |
| 3688 if (listener.errorReported) { | 3835 if (listener.errorReported) { |
| 3689 return null; | 3836 return null; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3703 nextToken = thirdToken.next; | 3850 nextToken = thirdToken.next; |
| 3704 } else { | 3851 } else { |
| 3705 identifier = new SimpleIdentifier(firstToken); | 3852 identifier = new SimpleIdentifier(firstToken); |
| 3706 nextToken = firstToken.next; | 3853 nextToken = firstToken.next; |
| 3707 } | 3854 } |
| 3708 if (nextToken.type != TokenType.EOF) { | 3855 if (nextToken.type != TokenType.EOF) { |
| 3709 return null; | 3856 return null; |
| 3710 } | 3857 } |
| 3711 return new CommentReference(newKeyword, identifier); | 3858 return new CommentReference(newKeyword, identifier); |
| 3712 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw
ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword.
FALSE)) { | 3859 } else if (matches3(firstToken, Keyword.THIS) || matches3(firstToken, Keyw
ord.NULL) || matches3(firstToken, Keyword.TRUE) || matches3(firstToken, Keyword.
FALSE)) { |
| 3860 // TODO(brianwilkerson) If we want to support this we will need to exten
d the definition |
| 3861 // of CommentReference to take an expression rather than an identifier.
For now we just |
| 3862 // ignore it to reduce the number of errors produced, but that's probabl
y not a valid |
| 3863 // long term approach. |
| 3713 return null; | 3864 return null; |
| 3714 } | 3865 } |
| 3715 } on JavaException catch (exception) { | 3866 } on JavaException catch (exception) { |
| 3716 } | 3867 } |
| 3717 return null; | 3868 return null; |
| 3718 } | 3869 } |
| 3719 | 3870 |
| 3720 /** | 3871 /** |
| 3721 * Parse all of the comment references occurring in the given array of documen
tation comments. | 3872 * Parse all of the comment references occurring in the given array of documen
tation comments. |
| 3722 * | 3873 * |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3801 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { | 3952 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { |
| 3802 reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []); | 3953 reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []); |
| 3803 return convertToFunctionDeclaration(parseOperator(commentAndMetadata, mo
difiers.externalKeyword, returnType)); | 3954 return convertToFunctionDeclaration(parseOperator(commentAndMetadata, mo
difiers.externalKeyword, returnType)); |
| 3804 } else if (matchesIdentifier() && matchesAny(peek(), [ | 3955 } else if (matchesIdentifier() && matchesAny(peek(), [ |
| 3805 TokenType.OPEN_PAREN, | 3956 TokenType.OPEN_PAREN, |
| 3806 TokenType.OPEN_CURLY_BRACKET, | 3957 TokenType.OPEN_CURLY_BRACKET, |
| 3807 TokenType.FUNCTION])) { | 3958 TokenType.FUNCTION])) { |
| 3808 validateModifiersForTopLevelFunction(modifiers); | 3959 validateModifiersForTopLevelFunction(modifiers); |
| 3809 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKe
yword, returnType); | 3960 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKe
yword, returnType); |
| 3810 } else { | 3961 } else { |
| 3962 // |
| 3963 // We have found an error of some kind. Try to recover. |
| 3964 // |
| 3811 if (matchesIdentifier()) { | 3965 if (matchesIdentifier()) { |
| 3812 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMIC
OLON])) { | 3966 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEMIC
OLON])) { |
| 3967 // |
| 3968 // We appear to have a variable declaration with a type of "void". |
| 3969 // |
| 3813 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); | 3970 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); |
| 3814 return new TopLevelVariableDeclaration(commentAndMetadata.comment, c
ommentAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifier
sForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON)); | 3971 return new TopLevelVariableDeclaration(commentAndMetadata.comment, c
ommentAndMetadata.metadata, parseVariableDeclarationList2(null, validateModifier
sForTopLevelVariable(modifiers), null), expect2(TokenType.SEMICOLON)); |
| 3815 } | 3972 } |
| 3816 } | 3973 } |
| 3817 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); | 3974 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); |
| 3818 return null; | 3975 return null; |
| 3819 } | 3976 } |
| 3820 } else if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifi
er2(peek())) { | 3977 } else if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifi
er2(peek())) { |
| 3821 validateModifiersForTopLevelFunction(modifiers); | 3978 validateModifiersForTopLevelFunction(modifiers); |
| 3822 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, null); | 3979 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, null); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3838 TypeName returnType = parseReturnType(); | 3995 TypeName returnType = parseReturnType(); |
| 3839 if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(pee
k())) { | 3996 if ((matches(Keyword.GET) || matches(Keyword.SET)) && matchesIdentifier2(pee
k())) { |
| 3840 validateModifiersForTopLevelFunction(modifiers); | 3997 validateModifiersForTopLevelFunction(modifiers); |
| 3841 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, returnType); | 3998 return parseFunctionDeclaration(commentAndMetadata, modifiers.externalKeyw
ord, returnType); |
| 3842 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { | 3999 } else if (matches(Keyword.OPERATOR) && isOperator(peek())) { |
| 3843 reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []); | 4000 reportError12(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken, []); |
| 3844 return convertToFunctionDeclaration(parseOperator(commentAndMetadata, modi
fiers.externalKeyword, returnType)); | 4001 return convertToFunctionDeclaration(parseOperator(commentAndMetadata, modi
fiers.externalKeyword, returnType)); |
| 3845 } else if (matches5(TokenType.AT)) { | 4002 } else if (matches5(TokenType.AT)) { |
| 3846 return new TopLevelVariableDeclaration(commentAndMetadata.comment, comment
AndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersForTo
pLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON)); | 4003 return new TopLevelVariableDeclaration(commentAndMetadata.comment, comment
AndMetadata.metadata, parseVariableDeclarationList2(null, validateModifiersForTo
pLevelVariable(modifiers), returnType), expect2(TokenType.SEMICOLON)); |
| 3847 } else if (!matchesIdentifier()) { | 4004 } else if (!matchesIdentifier()) { |
| 4005 // TODO(brianwilkerson) Generalize this error. We could also be parsing a
top-level variable at this point. |
| 3848 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); | 4006 reportError12(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken, []); |
| 3849 Token semicolon; | 4007 Token semicolon; |
| 3850 if (matches5(TokenType.SEMICOLON)) { | 4008 if (matches5(TokenType.SEMICOLON)) { |
| 3851 semicolon = andAdvance; | 4009 semicolon = andAdvance; |
| 3852 } else { | 4010 } else { |
| 3853 semicolon = createSyntheticToken2(TokenType.SEMICOLON); | 4011 semicolon = createSyntheticToken2(TokenType.SEMICOLON); |
| 3854 } | 4012 } |
| 3855 List<VariableDeclaration> variables = new List<VariableDeclaration>(); | 4013 List<VariableDeclaration> variables = new List<VariableDeclaration>(); |
| 3856 variables.add(new VariableDeclaration(null, null, createSyntheticIdentifie
r(), null, null)); | 4014 variables.add(new VariableDeclaration(null, null, createSyntheticIdentifie
r(), null, null)); |
| 3857 return new TopLevelVariableDeclaration(commentAndMetadata.comment, comment
AndMetadata.metadata, new VariableDeclarationList(null, null, null, returnType,
variables), semicolon); | 4015 return new TopLevelVariableDeclaration(commentAndMetadata.comment, comment
AndMetadata.metadata, new VariableDeclarationList(null, null, null, returnType,
variables), semicolon); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4021 Directive parseDirective(CommentAndMetadata commentAndMetadata) { | 4179 Directive parseDirective(CommentAndMetadata commentAndMetadata) { |
| 4022 if (matches(Keyword.IMPORT)) { | 4180 if (matches(Keyword.IMPORT)) { |
| 4023 return parseImportDirective(commentAndMetadata); | 4181 return parseImportDirective(commentAndMetadata); |
| 4024 } else if (matches(Keyword.EXPORT)) { | 4182 } else if (matches(Keyword.EXPORT)) { |
| 4025 return parseExportDirective(commentAndMetadata); | 4183 return parseExportDirective(commentAndMetadata); |
| 4026 } else if (matches(Keyword.LIBRARY)) { | 4184 } else if (matches(Keyword.LIBRARY)) { |
| 4027 return parseLibraryDirective(commentAndMetadata); | 4185 return parseLibraryDirective(commentAndMetadata); |
| 4028 } else if (matches(Keyword.PART)) { | 4186 } else if (matches(Keyword.PART)) { |
| 4029 return parsePartDirective(commentAndMetadata); | 4187 return parsePartDirective(commentAndMetadata); |
| 4030 } else { | 4188 } else { |
| 4189 // Internal error: this method should not have been invoked if the current
token was something |
| 4190 // other than one of the above. |
| 4031 throw new IllegalStateException("parseDirective invoked in an invalid stat
e; currentToken = ${_currentToken}"); | 4191 throw new IllegalStateException("parseDirective invoked in an invalid stat
e; currentToken = ${_currentToken}"); |
| 4032 } | 4192 } |
| 4033 } | 4193 } |
| 4034 | 4194 |
| 4035 /** | 4195 /** |
| 4036 * Parse a documentation comment. | 4196 * Parse a documentation comment. |
| 4037 * | 4197 * |
| 4038 * <pre> | 4198 * <pre> |
| 4039 * documentationComment ::= | 4199 * documentationComment ::= |
| 4040 * multiLineComment? | 4200 * multiLineComment? |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4289 variableList = new VariableDeclarationList(commentAndMetadata.comment,
commentAndMetadata.metadata, null, null, variables); | 4449 variableList = new VariableDeclarationList(commentAndMetadata.comment,
commentAndMetadata.metadata, null, null, variables); |
| 4290 } else if (isInitializedVariableDeclaration()) { | 4450 } else if (isInitializedVariableDeclaration()) { |
| 4291 variableList = parseVariableDeclarationList(commentAndMetadata); | 4451 variableList = parseVariableDeclarationList(commentAndMetadata); |
| 4292 } else { | 4452 } else { |
| 4293 initialization = parseExpression3(); | 4453 initialization = parseExpression3(); |
| 4294 } | 4454 } |
| 4295 if (matches(Keyword.IN)) { | 4455 if (matches(Keyword.IN)) { |
| 4296 DeclaredIdentifier loopVariable = null; | 4456 DeclaredIdentifier loopVariable = null; |
| 4297 SimpleIdentifier identifier = null; | 4457 SimpleIdentifier identifier = null; |
| 4298 if (variableList == null) { | 4458 if (variableList == null) { |
| 4459 // We found: <expression> 'in' |
| 4299 reportError11(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []); | 4460 reportError11(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, []); |
| 4300 } else { | 4461 } else { |
| 4301 NodeList<VariableDeclaration> variables = variableList.variables; | 4462 NodeList<VariableDeclaration> variables = variableList.variables; |
| 4302 if (variables.length > 1) { | 4463 if (variables.length > 1) { |
| 4303 reportError11(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [var
iables.length.toString()]); | 4464 reportError11(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [var
iables.length.toString()]); |
| 4304 } | 4465 } |
| 4305 VariableDeclaration variable = variables[0]; | 4466 VariableDeclaration variable = variables[0]; |
| 4306 if (variable.initializer != null) { | 4467 if (variable.initializer != null) { |
| 4307 reportError11(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []
); | 4468 reportError11(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, []
); |
| 4308 } | 4469 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4392 } | 4553 } |
| 4393 return new BlockFunctionBody(parseBlock()); | 4554 return new BlockFunctionBody(parseBlock()); |
| 4394 } else if (matches2(_NATIVE)) { | 4555 } else if (matches2(_NATIVE)) { |
| 4395 Token nativeToken = andAdvance; | 4556 Token nativeToken = andAdvance; |
| 4396 StringLiteral stringLiteral = null; | 4557 StringLiteral stringLiteral = null; |
| 4397 if (matches5(TokenType.STRING)) { | 4558 if (matches5(TokenType.STRING)) { |
| 4398 stringLiteral = parseStringLiteral(); | 4559 stringLiteral = parseStringLiteral(); |
| 4399 } | 4560 } |
| 4400 return new NativeFunctionBody(nativeToken, stringLiteral, expect2(TokenT
ype.SEMICOLON)); | 4561 return new NativeFunctionBody(nativeToken, stringLiteral, expect2(TokenT
ype.SEMICOLON)); |
| 4401 } else { | 4562 } else { |
| 4563 // Invalid function body |
| 4402 reportError11(emptyErrorCode, []); | 4564 reportError11(emptyErrorCode, []); |
| 4403 return new EmptyFunctionBody(createSyntheticToken2(TokenType.SEMICOLON))
; | 4565 return new EmptyFunctionBody(createSyntheticToken2(TokenType.SEMICOLON))
; |
| 4404 } | 4566 } |
| 4405 } finally { | 4567 } finally { |
| 4406 _inLoop = wasInLoop; | 4568 _inLoop = wasInLoop; |
| 4407 _inSwitch = wasInSwitch; | 4569 _inSwitch = wasInSwitch; |
| 4408 } | 4570 } |
| 4409 } | 4571 } |
| 4410 | 4572 |
| 4411 /** | 4573 /** |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4445 } else if (matches5(TokenType.OPEN_PAREN)) { | 4607 } else if (matches5(TokenType.OPEN_PAREN)) { |
| 4446 reportError11(ParserErrorCode.GETTER_WITH_PARAMETERS, []); | 4608 reportError11(ParserErrorCode.GETTER_WITH_PARAMETERS, []); |
| 4447 parseFormalParameterList(); | 4609 parseFormalParameterList(); |
| 4448 } | 4610 } |
| 4449 FunctionBody body; | 4611 FunctionBody body; |
| 4450 if (externalKeyword == null) { | 4612 if (externalKeyword == null) { |
| 4451 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal
se); | 4613 body = parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, fal
se); |
| 4452 } else { | 4614 } else { |
| 4453 body = new EmptyFunctionBody(expect2(TokenType.SEMICOLON)); | 4615 body = new EmptyFunctionBody(expect2(TokenType.SEMICOLON)); |
| 4454 } | 4616 } |
| 4617 // if (!isStatement && matches(TokenType.SEMICOLON)) { |
| 4618 // // TODO(brianwilkerson) Improve this error message. |
| 4619 // reportError(ParserErrorCode.UNEXPECTED_TOKEN, currentToken.getLexeme
()); |
| 4620 // advance(); |
| 4621 // } |
| 4455 return new FunctionDeclaration(commentAndMetadata.comment, commentAndMetadat
a.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression(p
arameters, body)); | 4622 return new FunctionDeclaration(commentAndMetadata.comment, commentAndMetadat
a.metadata, externalKeyword, returnType, keyword, name, new FunctionExpression(p
arameters, body)); |
| 4456 } | 4623 } |
| 4457 | 4624 |
| 4458 /** | 4625 /** |
| 4459 * Parse a function declaration statement. | 4626 * Parse a function declaration statement. |
| 4460 * | 4627 * |
| 4461 * <pre> | 4628 * <pre> |
| 4462 * functionDeclarationStatement ::= | 4629 * functionDeclarationStatement ::= |
| 4463 * functionSignature functionBody | 4630 * functionSignature functionBody |
| 4464 * </pre> | 4631 * </pre> |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4522 if (matches5(TokenType.LT)) { | 4689 if (matches5(TokenType.LT)) { |
| 4523 typeParameters = parseTypeParameterList(); | 4690 typeParameters = parseTypeParameterList(); |
| 4524 } | 4691 } |
| 4525 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.EOF)) { | 4692 if (matches5(TokenType.SEMICOLON) || matches5(TokenType.EOF)) { |
| 4526 reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []); | 4693 reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []); |
| 4527 FormalParameterList parameters = new FormalParameterList(createSyntheticTo
ken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken2(TokenType.CL
OSE_PAREN)); | 4694 FormalParameterList parameters = new FormalParameterList(createSyntheticTo
ken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticToken2(TokenType.CL
OSE_PAREN)); |
| 4528 Token semicolon = expect2(TokenType.SEMICOLON); | 4695 Token semicolon = expect2(TokenType.SEMICOLON); |
| 4529 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadat
a.metadata, keyword, returnType, name, typeParameters, parameters, semicolon); | 4696 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadat
a.metadata, keyword, returnType, name, typeParameters, parameters, semicolon); |
| 4530 } else if (!matches5(TokenType.OPEN_PAREN)) { | 4697 } else if (!matches5(TokenType.OPEN_PAREN)) { |
| 4531 reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []); | 4698 reportError11(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, []); |
| 4699 // TODO(brianwilkerson) Recover from this error. At the very least we shou
ld skip to the start |
| 4700 // of the next valid compilation unit member, allowing for the possibility
of finding the |
| 4701 // typedef parameters before that point. |
| 4532 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadat
a.metadata, keyword, returnType, name, typeParameters, new FormalParameterList(c
reateSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticTok
en2(TokenType.CLOSE_PAREN)), createSyntheticToken2(TokenType.SEMICOLON)); | 4702 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadat
a.metadata, keyword, returnType, name, typeParameters, new FormalParameterList(c
reateSyntheticToken2(TokenType.OPEN_PAREN), null, null, null, createSyntheticTok
en2(TokenType.CLOSE_PAREN)), createSyntheticToken2(TokenType.SEMICOLON)); |
| 4533 } | 4703 } |
| 4534 FormalParameterList parameters = parseFormalParameterList(); | 4704 FormalParameterList parameters = parseFormalParameterList(); |
| 4535 validateFormalParameterList(parameters); | 4705 validateFormalParameterList(parameters); |
| 4536 Token semicolon = expect2(TokenType.SEMICOLON); | 4706 Token semicolon = expect2(TokenType.SEMICOLON); |
| 4537 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.
metadata, keyword, returnType, name, typeParameters, parameters, semicolon); | 4707 return new FunctionTypeAlias(commentAndMetadata.comment, commentAndMetadata.
metadata, keyword, returnType, name, typeParameters, parameters, semicolon); |
| 4538 } | 4708 } |
| 4539 | 4709 |
| 4540 /** | 4710 /** |
| 4541 * Parse a getter. | 4711 * Parse a getter. |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4714 * | 4884 * |
| 4715 * @param missingNameError the error code to be used if the library name is mi
ssing | 4885 * @param missingNameError the error code to be used if the library name is mi
ssing |
| 4716 * @param missingNameToken the token associated with the error produced if the
library name is | 4886 * @param missingNameToken the token associated with the error produced if the
library name is |
| 4717 * missing | 4887 * missing |
| 4718 * @return the library name that was parsed | 4888 * @return the library name that was parsed |
| 4719 */ | 4889 */ |
| 4720 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis
singNameToken) { | 4890 LibraryIdentifier parseLibraryName(ParserErrorCode missingNameError, Token mis
singNameToken) { |
| 4721 if (matchesIdentifier()) { | 4891 if (matchesIdentifier()) { |
| 4722 return parseLibraryIdentifier(); | 4892 return parseLibraryIdentifier(); |
| 4723 } else if (matches5(TokenType.STRING)) { | 4893 } else if (matches5(TokenType.STRING)) { |
| 4894 // TODO(brianwilkerson) Recovery: This should be extended to handle arbitr
ary tokens until we |
| 4895 // can find a token that can start a compilation unit member. |
| 4724 StringLiteral string = parseStringLiteral(); | 4896 StringLiteral string = parseStringLiteral(); |
| 4725 reportError10(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []); | 4897 reportError10(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string, []); |
| 4726 } else { | 4898 } else { |
| 4727 reportError12(missingNameError, missingNameToken, []); | 4899 reportError12(missingNameError, missingNameToken, []); |
| 4728 } | 4900 } |
| 4729 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); | 4901 List<SimpleIdentifier> components = new List<SimpleIdentifier>(); |
| 4730 components.add(createSyntheticIdentifier()); | 4902 components.add(createSyntheticIdentifier()); |
| 4731 return new LibraryIdentifier(components); | 4903 return new LibraryIdentifier(components); |
| 4732 } | 4904 } |
| 4733 | 4905 |
| 4734 /** | 4906 /** |
| 4735 * Parse a list literal. | 4907 * Parse a list literal. |
| 4736 * | 4908 * |
| 4737 * <pre> | 4909 * <pre> |
| 4738 * listLiteral ::= | 4910 * listLiteral ::= |
| 4739 * 'const'? typeArguments? '[' (expressionList ','?)? ']' | 4911 * 'const'? typeArguments? '[' (expressionList ','?)? ']' |
| 4740 * </pre> | 4912 * </pre> |
| 4741 * | 4913 * |
| 4742 * @param modifier the 'const' modifier appearing before the literal, or `null
` if there is | 4914 * @param modifier the 'const' modifier appearing before the literal, or `null
` if there is |
| 4743 * no modifier | 4915 * no modifier |
| 4744 * @param typeArguments the type arguments appearing before the literal, or `n
ull` if there | 4916 * @param typeArguments the type arguments appearing before the literal, or `n
ull` if there |
| 4745 * are no type arguments | 4917 * are no type arguments |
| 4746 * @return the list literal that was parsed | 4918 * @return the list literal that was parsed |
| 4747 */ | 4919 */ |
| 4748 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) { | 4920 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) { |
| 4921 // may be empty list literal |
| 4749 if (matches5(TokenType.INDEX)) { | 4922 if (matches5(TokenType.INDEX)) { |
| 4750 BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _cu
rrentToken.offset); | 4923 BeginToken leftBracket = new BeginToken(TokenType.OPEN_SQUARE_BRACKET, _cu
rrentToken.offset); |
| 4751 Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentTok
en.offset + 1); | 4924 Token rightBracket = new Token(TokenType.CLOSE_SQUARE_BRACKET, _currentTok
en.offset + 1); |
| 4752 leftBracket.endToken = rightBracket; | 4925 leftBracket.endToken = rightBracket; |
| 4753 rightBracket.setNext(_currentToken.next); | 4926 rightBracket.setNext(_currentToken.next); |
| 4754 leftBracket.setNext(rightBracket); | 4927 leftBracket.setNext(rightBracket); |
| 4755 _currentToken.previous.setNext(leftBracket); | 4928 _currentToken.previous.setNext(leftBracket); |
| 4756 _currentToken = _currentToken.next; | 4929 _currentToken = _currentToken.next; |
| 4757 return new ListLiteral(modifier, typeArguments, leftBracket, null, rightBr
acket); | 4930 return new ListLiteral(modifier, typeArguments, leftBracket, null, rightBr
acket); |
| 4758 } | 4931 } |
| 4932 // open |
| 4759 Token leftBracket = expect2(TokenType.OPEN_SQUARE_BRACKET); | 4933 Token leftBracket = expect2(TokenType.OPEN_SQUARE_BRACKET); |
| 4760 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { | 4934 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { |
| 4761 return new ListLiteral(modifier, typeArguments, leftBracket, null, andAdva
nce); | 4935 return new ListLiteral(modifier, typeArguments, leftBracket, null, andAdva
nce); |
| 4762 } | 4936 } |
| 4763 List<Expression> elements = new List<Expression>(); | 4937 List<Expression> elements = new List<Expression>(); |
| 4764 elements.add(parseExpression3()); | 4938 elements.add(parseExpression3()); |
| 4765 while (optional(TokenType.COMMA)) { | 4939 while (optional(TokenType.COMMA)) { |
| 4766 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { | 4940 if (matches5(TokenType.CLOSE_SQUARE_BRACKET)) { |
| 4767 return new ListLiteral(modifier, typeArguments, leftBracket, elements, a
ndAdvance); | 4941 return new ListLiteral(modifier, typeArguments, leftBracket, elements, a
ndAdvance); |
| 4768 } | 4942 } |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5050 * | tryStatement | 5224 * | tryStatement |
| 5051 * | whileStatement | 5225 * | whileStatement |
| 5052 * | variableDeclarationList ';' | 5226 * | variableDeclarationList ';' |
| 5053 * | expressionStatement | 5227 * | expressionStatement |
| 5054 * | functionSignature functionBody | 5228 * | functionSignature functionBody |
| 5055 * </pre> | 5229 * </pre> |
| 5056 * | 5230 * |
| 5057 * @return the non-labeled statement that was parsed | 5231 * @return the non-labeled statement that was parsed |
| 5058 */ | 5232 */ |
| 5059 Statement parseNonLabeledStatement() { | 5233 Statement parseNonLabeledStatement() { |
| 5234 // TODO(brianwilkerson) Pass the comment and metadata on where appropriate. |
| 5060 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 5235 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 5061 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { | 5236 if (matches5(TokenType.OPEN_CURLY_BRACKET)) { |
| 5062 if (matches4(peek(), TokenType.STRING)) { | 5237 if (matches4(peek(), TokenType.STRING)) { |
| 5063 Token afterString = skipStringLiteral(_currentToken.next); | 5238 Token afterString = skipStringLiteral(_currentToken.next); |
| 5064 if (afterString != null && identical(afterString.type, TokenType.COLON))
{ | 5239 if (afterString != null && identical(afterString.type, TokenType.COLON))
{ |
| 5065 return new ExpressionStatement(parseExpression3(), expect2(TokenType.S
EMICOLON)); | 5240 return new ExpressionStatement(parseExpression3(), expect2(TokenType.S
EMICOLON)); |
| 5066 } | 5241 } |
| 5067 } | 5242 } |
| 5068 return parseBlock(); | 5243 return parseBlock(); |
| 5069 } else if (matches5(TokenType.KEYWORD) && !(_currentToken as KeywordToken).k
eyword.isPseudoKeyword) { | 5244 } else if (matches5(TokenType.KEYWORD) && !(_currentToken as KeywordToken).k
eyword.isPseudoKeyword) { |
| 5070 Keyword keyword = (_currentToken as KeywordToken).keyword; | 5245 Keyword keyword = (_currentToken as KeywordToken).keyword; |
| 5246 // TODO(jwren) compute some metrics to figure out a better order for this
if-then sequence to optimize performance |
| 5071 if (identical(keyword, Keyword.ASSERT)) { | 5247 if (identical(keyword, Keyword.ASSERT)) { |
| 5072 return parseAssertStatement(); | 5248 return parseAssertStatement(); |
| 5073 } else if (identical(keyword, Keyword.BREAK)) { | 5249 } else if (identical(keyword, Keyword.BREAK)) { |
| 5074 return parseBreakStatement(); | 5250 return parseBreakStatement(); |
| 5075 } else if (identical(keyword, Keyword.CONTINUE)) { | 5251 } else if (identical(keyword, Keyword.CONTINUE)) { |
| 5076 return parseContinueStatement(); | 5252 return parseContinueStatement(); |
| 5077 } else if (identical(keyword, Keyword.DO)) { | 5253 } else if (identical(keyword, Keyword.DO)) { |
| 5078 return parseDoStatement(); | 5254 return parseDoStatement(); |
| 5079 } else if (identical(keyword, Keyword.FOR)) { | 5255 } else if (identical(keyword, Keyword.FOR)) { |
| 5080 return parseForStatement(); | 5256 return parseForStatement(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5095 } else if (identical(keyword, Keyword.VAR) || identical(keyword, Keyword.F
INAL)) { | 5271 } else if (identical(keyword, Keyword.VAR) || identical(keyword, Keyword.F
INAL)) { |
| 5096 return parseVariableDeclarationStatement(commentAndMetadata); | 5272 return parseVariableDeclarationStatement(commentAndMetadata); |
| 5097 } else if (identical(keyword, Keyword.VOID)) { | 5273 } else if (identical(keyword, Keyword.VOID)) { |
| 5098 TypeName returnType = parseReturnType(); | 5274 TypeName returnType = parseReturnType(); |
| 5099 if (matchesIdentifier() && matchesAny(peek(), [ | 5275 if (matchesIdentifier() && matchesAny(peek(), [ |
| 5100 TokenType.OPEN_PAREN, | 5276 TokenType.OPEN_PAREN, |
| 5101 TokenType.OPEN_CURLY_BRACKET, | 5277 TokenType.OPEN_CURLY_BRACKET, |
| 5102 TokenType.FUNCTION])) { | 5278 TokenType.FUNCTION])) { |
| 5103 return parseFunctionDeclarationStatement2(commentAndMetadata, returnTy
pe); | 5279 return parseFunctionDeclarationStatement2(commentAndMetadata, returnTy
pe); |
| 5104 } else { | 5280 } else { |
| 5281 // |
| 5282 // We have found an error of some kind. Try to recover. |
| 5283 // |
| 5105 if (matchesIdentifier()) { | 5284 if (matchesIdentifier()) { |
| 5106 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEM
ICOLON])) { | 5285 if (matchesAny(peek(), [TokenType.EQ, TokenType.COMMA, TokenType.SEM
ICOLON])) { |
| 5286 // |
| 5287 // We appear to have a variable declaration with a type of "void". |
| 5288 // |
| 5107 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); | 5289 reportError10(ParserErrorCode.VOID_VARIABLE, returnType, []); |
| 5108 return parseVariableDeclarationStatement(commentAndMetadata); | 5290 return parseVariableDeclarationStatement(commentAndMetadata); |
| 5109 } | 5291 } |
| 5110 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { | 5292 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { |
| 5293 // |
| 5294 // We appear to have found an incomplete statement at the end of a b
lock. Parse it as a |
| 5295 // variable declaration. |
| 5296 // |
| 5111 return parseVariableDeclarationStatement2(commentAndMetadata, null,
returnType); | 5297 return parseVariableDeclarationStatement2(commentAndMetadata, null,
returnType); |
| 5112 } | 5298 } |
| 5113 reportError11(ParserErrorCode.MISSING_STATEMENT, []); | 5299 reportError11(ParserErrorCode.MISSING_STATEMENT, []); |
| 5300 // TODO(brianwilkerson) Recover from this error. |
| 5114 return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON)); | 5301 return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON)); |
| 5115 } | 5302 } |
| 5116 } else if (identical(keyword, Keyword.CONST)) { | 5303 } else if (identical(keyword, Keyword.CONST)) { |
| 5117 if (matchesAny(peek(), [ | 5304 if (matchesAny(peek(), [ |
| 5118 TokenType.LT, | 5305 TokenType.LT, |
| 5119 TokenType.OPEN_CURLY_BRACKET, | 5306 TokenType.OPEN_CURLY_BRACKET, |
| 5120 TokenType.OPEN_SQUARE_BRACKET, | 5307 TokenType.OPEN_SQUARE_BRACKET, |
| 5121 TokenType.INDEX])) { | 5308 TokenType.INDEX])) { |
| 5122 return new ExpressionStatement(parseExpression3(), expect2(TokenType.S
EMICOLON)); | 5309 return new ExpressionStatement(parseExpression3(), expect2(TokenType.S
EMICOLON)); |
| 5123 } else if (matches4(peek(), TokenType.IDENTIFIER)) { | 5310 } else if (matches4(peek(), TokenType.IDENTIFIER)) { |
| 5124 Token afterType = skipTypeName(peek()); | 5311 Token afterType = skipTypeName(peek()); |
| 5125 if (afterType != null) { | 5312 if (afterType != null) { |
| 5126 if (matches4(afterType, TokenType.OPEN_PAREN) || (matches4(afterType
, TokenType.PERIOD) && matches4(afterType.next, TokenType.IDENTIFIER) && matches
4(afterType.next.next, TokenType.OPEN_PAREN))) { | 5313 if (matches4(afterType, TokenType.OPEN_PAREN) || (matches4(afterType
, TokenType.PERIOD) && matches4(afterType.next, TokenType.IDENTIFIER) && matches
4(afterType.next.next, TokenType.OPEN_PAREN))) { |
| 5127 return new ExpressionStatement(parseExpression3(), expect2(TokenTy
pe.SEMICOLON)); | 5314 return new ExpressionStatement(parseExpression3(), expect2(TokenTy
pe.SEMICOLON)); |
| 5128 } | 5315 } |
| 5129 } | 5316 } |
| 5130 } | 5317 } |
| 5131 return parseVariableDeclarationStatement(commentAndMetadata); | 5318 return parseVariableDeclarationStatement(commentAndMetadata); |
| 5132 } else if (identical(keyword, Keyword.NEW) || identical(keyword, Keyword.T
RUE) || identical(keyword, Keyword.FALSE) || identical(keyword, Keyword.NULL) ||
identical(keyword, Keyword.SUPER) || identical(keyword, Keyword.THIS)) { | 5319 } else if (identical(keyword, Keyword.NEW) || identical(keyword, Keyword.T
RUE) || identical(keyword, Keyword.FALSE) || identical(keyword, Keyword.NULL) ||
identical(keyword, Keyword.SUPER) || identical(keyword, Keyword.THIS)) { |
| 5133 return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEM
ICOLON)); | 5320 return new ExpressionStatement(parseExpression3(), expect2(TokenType.SEM
ICOLON)); |
| 5134 } else { | 5321 } else { |
| 5322 // |
| 5323 // We have found an error of some kind. Try to recover. |
| 5324 // |
| 5135 reportError11(ParserErrorCode.MISSING_STATEMENT, []); | 5325 reportError11(ParserErrorCode.MISSING_STATEMENT, []); |
| 5136 return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON)); | 5326 return new EmptyStatement(createSyntheticToken2(TokenType.SEMICOLON)); |
| 5137 } | 5327 } |
| 5138 } else if (matches5(TokenType.SEMICOLON)) { | 5328 } else if (matches5(TokenType.SEMICOLON)) { |
| 5139 return parseEmptyStatement(); | 5329 return parseEmptyStatement(); |
| 5140 } else if (isInitializedVariableDeclaration()) { | 5330 } else if (isInitializedVariableDeclaration()) { |
| 5141 return parseVariableDeclarationStatement(commentAndMetadata); | 5331 return parseVariableDeclarationStatement(commentAndMetadata); |
| 5142 } else if (isFunctionDeclaration()) { | 5332 } else if (isFunctionDeclaration()) { |
| 5143 return parseFunctionDeclarationStatement(); | 5333 return parseFunctionDeclarationStatement(); |
| 5144 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { | 5334 } else if (matches5(TokenType.CLOSE_CURLY_BRACKET)) { |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5343 } on FormatException catch (exception) { | 5533 } on FormatException catch (exception) { |
| 5344 } | 5534 } |
| 5345 return new IntegerLiteral(token, value); | 5535 return new IntegerLiteral(token, value); |
| 5346 } else if (matches5(TokenType.STRING)) { | 5536 } else if (matches5(TokenType.STRING)) { |
| 5347 return parseStringLiteral(); | 5537 return parseStringLiteral(); |
| 5348 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { | 5538 } else if (matches5(TokenType.OPEN_CURLY_BRACKET)) { |
| 5349 return parseMapLiteral(null, null); | 5539 return parseMapLiteral(null, null); |
| 5350 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND
EX)) { | 5540 } else if (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.IND
EX)) { |
| 5351 return parseListLiteral(null, null); | 5541 return parseListLiteral(null, null); |
| 5352 } else if (matchesIdentifier()) { | 5542 } else if (matchesIdentifier()) { |
| 5543 // TODO(brianwilkerson) The code below was an attempt to recover from an e
rror case, but it |
| 5544 // needs to be applied as a recovery only after we know that parsing it as
an identifier |
| 5545 // doesn't work. Leaving the code as a reminder of how to recover. |
| 5546 // if (isFunctionExpression(peek())) { |
| 5547 // // |
| 5548 // // Function expressions were allowed to have names at one point,
but this is now illegal. |
| 5549 // // |
| 5550 // reportError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, getAndAdv
ance()); |
| 5551 // return parseFunctionExpression(); |
| 5552 // } |
| 5353 return parsePrefixedIdentifier(); | 5553 return parsePrefixedIdentifier(); |
| 5354 } else if (matches(Keyword.NEW)) { | 5554 } else if (matches(Keyword.NEW)) { |
| 5355 return parseNewExpression(); | 5555 return parseNewExpression(); |
| 5356 } else if (matches(Keyword.CONST)) { | 5556 } else if (matches(Keyword.CONST)) { |
| 5357 return parseConstExpression(); | 5557 return parseConstExpression(); |
| 5358 } else if (matches5(TokenType.OPEN_PAREN)) { | 5558 } else if (matches5(TokenType.OPEN_PAREN)) { |
| 5359 if (isFunctionExpression(_currentToken)) { | 5559 if (isFunctionExpression(_currentToken)) { |
| 5360 return parseFunctionExpression(); | 5560 return parseFunctionExpression(); |
| 5361 } | 5561 } |
| 5362 Token leftParenthesis = andAdvance; | 5562 Token leftParenthesis = andAdvance; |
| 5363 Expression expression = parseExpression3(); | 5563 Expression expression = parseExpression3(); |
| 5364 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); | 5564 Token rightParenthesis = expect2(TokenType.CLOSE_PAREN); |
| 5365 return new ParenthesizedExpression(leftParenthesis, expression, rightParen
thesis); | 5565 return new ParenthesizedExpression(leftParenthesis, expression, rightParen
thesis); |
| 5366 } else if (matches5(TokenType.LT)) { | 5566 } else if (matches5(TokenType.LT)) { |
| 5367 return parseListOrMapLiteral(null); | 5567 return parseListOrMapLiteral(null); |
| 5368 } else if (matches5(TokenType.QUESTION)) { | 5568 } else if (matches5(TokenType.QUESTION)) { |
| 5369 return parseArgumentDefinitionTest(); | 5569 return parseArgumentDefinitionTest(); |
| 5370 } else if (matches(Keyword.VOID)) { | 5570 } else if (matches(Keyword.VOID)) { |
| 5571 // |
| 5572 // Recover from having a return type of "void" where a return type is not
expected. |
| 5573 // |
| 5574 // TODO(brianwilkerson) Improve this error message. |
| 5371 reportError11(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]); | 5575 reportError11(ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]); |
| 5372 advance(); | 5576 advance(); |
| 5373 return parsePrimaryExpression(); | 5577 return parsePrimaryExpression(); |
| 5374 } else if (matches5(TokenType.HASH)) { | 5578 } else if (matches5(TokenType.HASH)) { |
| 5375 return parseSymbolLiteral(); | 5579 return parseSymbolLiteral(); |
| 5376 } else { | 5580 } else { |
| 5377 reportError11(ParserErrorCode.MISSING_IDENTIFIER, []); | 5581 reportError11(ParserErrorCode.MISSING_IDENTIFIER, []); |
| 5378 return createSyntheticIdentifier(); | 5582 return createSyntheticIdentifier(); |
| 5379 } | 5583 } |
| 5380 } | 5584 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5655 reportError12(ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, ca
seKeyword, []); | 5859 reportError12(ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, ca
seKeyword, []); |
| 5656 } | 5860 } |
| 5657 } else if (matches(Keyword.DEFAULT)) { | 5861 } else if (matches(Keyword.DEFAULT)) { |
| 5658 if (defaultKeyword != null) { | 5862 if (defaultKeyword != null) { |
| 5659 reportError12(ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, pee
k(), []); | 5863 reportError12(ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, pee
k(), []); |
| 5660 } | 5864 } |
| 5661 defaultKeyword = andAdvance; | 5865 defaultKeyword = andAdvance; |
| 5662 Token colon = expect2(TokenType.COLON); | 5866 Token colon = expect2(TokenType.COLON); |
| 5663 members.add(new SwitchDefault(labels, defaultKeyword, colon, parseStat
ements2())); | 5867 members.add(new SwitchDefault(labels, defaultKeyword, colon, parseStat
ements2())); |
| 5664 } else { | 5868 } else { |
| 5869 // We need to advance, otherwise we could end up in an infinite loop,
but this could be a |
| 5870 // lot smarter about recovering from the error. |
| 5665 reportError11(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []); | 5871 reportError11(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT, []); |
| 5666 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRA
CKET) && !matches(Keyword.CASE) && !matches(Keyword.DEFAULT)) { | 5872 while (!matches5(TokenType.EOF) && !matches5(TokenType.CLOSE_CURLY_BRA
CKET) && !matches(Keyword.CASE) && !matches(Keyword.DEFAULT)) { |
| 5667 advance(); | 5873 advance(); |
| 5668 } | 5874 } |
| 5669 } | 5875 } |
| 5670 } | 5876 } |
| 5671 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); | 5877 Token rightBracket = expect2(TokenType.CLOSE_CURLY_BRACKET); |
| 5672 return new SwitchStatement(keyword, leftParenthesis, expression, rightPare
nthesis, leftBracket, members, rightBracket); | 5878 return new SwitchStatement(keyword, leftParenthesis, expression, rightPare
nthesis, leftBracket, members, rightBracket); |
| 5673 } finally { | 5879 } finally { |
| 5674 _inSwitch = wasInSwitch; | 5880 _inSwitch = wasInSwitch; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5871 * | incrementOperator assignableExpression | 6077 * | incrementOperator assignableExpression |
| 5872 * </pre> | 6078 * </pre> |
| 5873 * | 6079 * |
| 5874 * @return the unary expression that was parsed | 6080 * @return the unary expression that was parsed |
| 5875 */ | 6081 */ |
| 5876 Expression parseUnaryExpression() { | 6082 Expression parseUnaryExpression() { |
| 5877 if (matches5(TokenType.MINUS) || matches5(TokenType.BANG) || matches5(TokenT
ype.TILDE)) { | 6083 if (matches5(TokenType.MINUS) || matches5(TokenType.BANG) || matches5(TokenT
ype.TILDE)) { |
| 5878 Token operator = andAdvance; | 6084 Token operator = andAdvance; |
| 5879 if (matches(Keyword.SUPER)) { | 6085 if (matches(Keyword.SUPER)) { |
| 5880 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(),
TokenType.PERIOD)) { | 6086 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(),
TokenType.PERIOD)) { |
| 6087 // "prefixOperator unaryExpression" |
| 6088 // --> "prefixOperator postfixExpression" |
| 6089 // --> "prefixOperator primary selector*" |
| 6090 // --> "prefixOperator 'super' assignableSelector selector*" |
| 5881 return new PrefixExpression(operator, parseUnaryExpression()); | 6091 return new PrefixExpression(operator, parseUnaryExpression()); |
| 5882 } | 6092 } |
| 5883 return new PrefixExpression(operator, new SuperExpression(andAdvance)); | 6093 return new PrefixExpression(operator, new SuperExpression(andAdvance)); |
| 5884 } | 6094 } |
| 5885 return new PrefixExpression(operator, parseUnaryExpression()); | 6095 return new PrefixExpression(operator, parseUnaryExpression()); |
| 5886 } else if (_currentToken.type.isIncrementOperator) { | 6096 } else if (_currentToken.type.isIncrementOperator) { |
| 5887 Token operator = andAdvance; | 6097 Token operator = andAdvance; |
| 5888 if (matches(Keyword.SUPER)) { | 6098 if (matches(Keyword.SUPER)) { |
| 5889 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(),
TokenType.PERIOD)) { | 6099 if (matches4(peek(), TokenType.OPEN_SQUARE_BRACKET) || matches4(peek(),
TokenType.PERIOD)) { |
| 6100 // --> "prefixOperator 'super' assignableSelector selector*" |
| 5890 return new PrefixExpression(operator, parseUnaryExpression()); | 6101 return new PrefixExpression(operator, parseUnaryExpression()); |
| 5891 } | 6102 } |
| 6103 // |
| 6104 // Even though it is not valid to use an incrementing operator ('++' or
'--') before 'super', |
| 6105 // we can (and therefore must) interpret "--super" as semantically equiv
alent to "-(-super)". |
| 6106 // Unfortunately, we cannot do the same for "++super" because "+super" i
s also not valid. |
| 6107 // |
| 5892 if (identical(operator.type, TokenType.MINUS_MINUS)) { | 6108 if (identical(operator.type, TokenType.MINUS_MINUS)) { |
| 5893 int offset = operator.offset; | 6109 int offset = operator.offset; |
| 5894 Token firstOperator = new Token(TokenType.MINUS, offset); | 6110 Token firstOperator = new Token(TokenType.MINUS, offset); |
| 5895 Token secondOperator = new Token(TokenType.MINUS, offset + 1); | 6111 Token secondOperator = new Token(TokenType.MINUS, offset + 1); |
| 5896 secondOperator.setNext(_currentToken); | 6112 secondOperator.setNext(_currentToken); |
| 5897 firstOperator.setNext(secondOperator); | 6113 firstOperator.setNext(secondOperator); |
| 5898 operator.previous.setNext(firstOperator); | 6114 operator.previous.setNext(firstOperator); |
| 5899 return new PrefixExpression(firstOperator, new PrefixExpression(second
Operator, new SuperExpression(andAdvance))); | 6115 return new PrefixExpression(firstOperator, new PrefixExpression(second
Operator, new SuperExpression(andAdvance))); |
| 5900 } else { | 6116 } else { |
| 6117 // Invalid operator before 'super' |
| 5901 reportError11(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.le
xeme]); | 6118 reportError11(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.le
xeme]); |
| 5902 return new PrefixExpression(operator, new SuperExpression(andAdvance))
; | 6119 return new PrefixExpression(operator, new SuperExpression(andAdvance))
; |
| 5903 } | 6120 } |
| 5904 } | 6121 } |
| 5905 return new PrefixExpression(operator, parseAssignableExpression(false)); | 6122 return new PrefixExpression(operator, parseAssignableExpression(false)); |
| 5906 } else if (matches5(TokenType.PLUS)) { | 6123 } else if (matches5(TokenType.PLUS)) { |
| 5907 reportError11(ParserErrorCode.MISSING_IDENTIFIER, []); | 6124 reportError11(ParserErrorCode.MISSING_IDENTIFIER, []); |
| 5908 return createSyntheticIdentifier(); | 6125 return createSyntheticIdentifier(); |
| 5909 } | 6126 } |
| 5910 return parsePostfixExpression(); | 6127 return parsePostfixExpression(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5982 * <pre> | 6199 * <pre> |
| 5983 * variableDeclarationStatement ::= | 6200 * variableDeclarationStatement ::= |
| 5984 * variableDeclarationList ';' | 6201 * variableDeclarationList ';' |
| 5985 * </pre> | 6202 * </pre> |
| 5986 * | 6203 * |
| 5987 * @param commentAndMetadata the metadata to be associated with the variable d
eclaration | 6204 * @param commentAndMetadata the metadata to be associated with the variable d
eclaration |
| 5988 * statement, or `null` if there is no attempt at parsing the comment
and metadata | 6205 * statement, or `null` if there is no attempt at parsing the comment
and metadata |
| 5989 * @return the variable declaration statement that was parsed | 6206 * @return the variable declaration statement that was parsed |
| 5990 */ | 6207 */ |
| 5991 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad
ata commentAndMetadata) { | 6208 VariableDeclarationStatement parseVariableDeclarationStatement(CommentAndMetad
ata commentAndMetadata) { |
| 6209 // Token startToken = currentToken; |
| 5992 VariableDeclarationList variableList = parseVariableDeclarationList(commentA
ndMetadata); | 6210 VariableDeclarationList variableList = parseVariableDeclarationList(commentA
ndMetadata); |
| 6211 // if (!matches(TokenType.SEMICOLON)) { |
| 6212 // if (matches(startToken, Keyword.VAR) && isTypedIdentifier(startToken
.getNext())) { |
| 6213 // // TODO(brianwilkerson) This appears to be of the form "var type v
ariable". We should do |
| 6214 // // a better job of recovering in this case. |
| 6215 // } |
| 6216 // } |
| 5993 Token semicolon = expect2(TokenType.SEMICOLON); | 6217 Token semicolon = expect2(TokenType.SEMICOLON); |
| 5994 return new VariableDeclarationStatement(variableList, semicolon); | 6218 return new VariableDeclarationStatement(variableList, semicolon); |
| 5995 } | 6219 } |
| 5996 | 6220 |
| 5997 /** | 6221 /** |
| 5998 * Parse a variable declaration statement. | 6222 * Parse a variable declaration statement. |
| 5999 * | 6223 * |
| 6000 * <pre> | 6224 * <pre> |
| 6001 * variableDeclarationStatement ::= | 6225 * variableDeclarationStatement ::= |
| 6002 * variableDeclarationList ';' | 6226 * variableDeclarationList ';' |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6129 * </pre> | 6353 * </pre> |
| 6130 * | 6354 * |
| 6131 * @param startToken the token at which parsing is to begin | 6355 * @param startToken the token at which parsing is to begin |
| 6132 * @return the token following the type that was parsed | 6356 * @return the token following the type that was parsed |
| 6133 */ | 6357 */ |
| 6134 Token skipFinalConstVarOrType(Token startToken) { | 6358 Token skipFinalConstVarOrType(Token startToken) { |
| 6135 if (matches3(startToken, Keyword.FINAL) || matches3(startToken, Keyword.CONS
T)) { | 6359 if (matches3(startToken, Keyword.FINAL) || matches3(startToken, Keyword.CONS
T)) { |
| 6136 Token next = startToken.next; | 6360 Token next = startToken.next; |
| 6137 if (matchesIdentifier2(next)) { | 6361 if (matchesIdentifier2(next)) { |
| 6138 Token next2 = next.next; | 6362 Token next2 = next.next; |
| 6363 // "Type parameter" or "Type<" or "prefix.Type" |
| 6139 if (matchesIdentifier2(next2) || matches4(next2, TokenType.LT) || matche
s4(next2, TokenType.PERIOD)) { | 6364 if (matchesIdentifier2(next2) || matches4(next2, TokenType.LT) || matche
s4(next2, TokenType.PERIOD)) { |
| 6140 return skipTypeName(next); | 6365 return skipTypeName(next); |
| 6141 } | 6366 } |
| 6367 // "parameter" |
| 6142 return next; | 6368 return next; |
| 6143 } | 6369 } |
| 6144 } else if (matches3(startToken, Keyword.VAR)) { | 6370 } else if (matches3(startToken, Keyword.VAR)) { |
| 6145 return startToken.next; | 6371 return startToken.next; |
| 6146 } else if (matchesIdentifier2(startToken)) { | 6372 } else if (matchesIdentifier2(startToken)) { |
| 6147 Token next = startToken.next; | 6373 Token next = startToken.next; |
| 6148 if (matchesIdentifier2(next) || matches4(next, TokenType.LT) || matches3(n
ext, Keyword.THIS) || (matches4(next, TokenType.PERIOD) && matchesIdentifier2(ne
xt.next) && (matchesIdentifier2(next.next.next) || matches4(next.next.next, Toke
nType.LT) || matches3(next.next.next, Keyword.THIS)))) { | 6374 if (matchesIdentifier2(next) || matches4(next, TokenType.LT) || matches3(n
ext, Keyword.THIS) || (matches4(next, TokenType.PERIOD) && matchesIdentifier2(ne
xt.next) && (matchesIdentifier2(next.next.next) || matches4(next.next.next, Toke
nType.LT) || matches3(next.next.next, Keyword.THIS)))) { |
| 6149 return skipReturnType(startToken); | 6375 return skipReturnType(startToken); |
| 6150 } | 6376 } |
| 6151 } | 6377 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6190 * @return the token following the formal parameter list that was parsed | 6416 * @return the token following the formal parameter list that was parsed |
| 6191 */ | 6417 */ |
| 6192 Token skipFormalParameterList(Token startToken) { | 6418 Token skipFormalParameterList(Token startToken) { |
| 6193 if (!matches4(startToken, TokenType.OPEN_PAREN)) { | 6419 if (!matches4(startToken, TokenType.OPEN_PAREN)) { |
| 6194 return null; | 6420 return null; |
| 6195 } | 6421 } |
| 6196 Token next = startToken.next; | 6422 Token next = startToken.next; |
| 6197 if (matches4(next, TokenType.CLOSE_PAREN)) { | 6423 if (matches4(next, TokenType.CLOSE_PAREN)) { |
| 6198 return next.next; | 6424 return next.next; |
| 6199 } | 6425 } |
| 6426 // |
| 6427 // Look to see whether the token after the open parenthesis is something tha
t should only occur |
| 6428 // at the beginning of a parameter list. |
| 6429 // |
| 6200 if (matchesAny(next, [ | 6430 if (matchesAny(next, [ |
| 6201 TokenType.AT, | 6431 TokenType.AT, |
| 6202 TokenType.OPEN_SQUARE_BRACKET, | 6432 TokenType.OPEN_SQUARE_BRACKET, |
| 6203 TokenType.OPEN_CURLY_BRACKET]) || matches3(next, Keyword.VOID) || (match
esIdentifier2(next) && (matchesAny(next.next, [TokenType.COMMA, TokenType.CLOSE_
PAREN])))) { | 6433 TokenType.OPEN_CURLY_BRACKET]) || matches3(next, Keyword.VOID) || (match
esIdentifier2(next) && (matchesAny(next.next, [TokenType.COMMA, TokenType.CLOSE_
PAREN])))) { |
| 6204 return skipPastMatchingToken(startToken); | 6434 return skipPastMatchingToken(startToken); |
| 6205 } | 6435 } |
| 6436 // |
| 6437 // Look to see whether the first parameter is a function typed parameter wit
hout a return type. |
| 6438 // |
| 6206 if (matchesIdentifier2(next) && matches4(next.next, TokenType.OPEN_PAREN)) { | 6439 if (matchesIdentifier2(next) && matches4(next.next, TokenType.OPEN_PAREN)) { |
| 6207 Token afterParameters = skipFormalParameterList(next.next); | 6440 Token afterParameters = skipFormalParameterList(next.next); |
| 6208 if (afterParameters != null && (matchesAny(afterParameters, [TokenType.COM
MA, TokenType.CLOSE_PAREN]))) { | 6441 if (afterParameters != null && (matchesAny(afterParameters, [TokenType.COM
MA, TokenType.CLOSE_PAREN]))) { |
| 6209 return skipPastMatchingToken(startToken); | 6442 return skipPastMatchingToken(startToken); |
| 6210 } | 6443 } |
| 6211 } | 6444 } |
| 6445 // |
| 6446 // Look to see whether the first parameter has a type or is a function typed
parameter with a |
| 6447 // return type. |
| 6448 // |
| 6212 Token afterType = skipFinalConstVarOrType(next); | 6449 Token afterType = skipFinalConstVarOrType(next); |
| 6213 if (afterType == null) { | 6450 if (afterType == null) { |
| 6214 return null; | 6451 return null; |
| 6215 } | 6452 } |
| 6216 if (skipSimpleIdentifier(afterType) == null) { | 6453 if (skipSimpleIdentifier(afterType) == null) { |
| 6217 return null; | 6454 return null; |
| 6218 } | 6455 } |
| 6219 return skipPastMatchingToken(startToken); | 6456 return skipPastMatchingToken(startToken); |
| 6220 } | 6457 } |
| 6221 | 6458 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6321 * @param startToken the token at which parsing is to begin | 6558 * @param startToken the token at which parsing is to begin |
| 6322 * @return the string literal that was parsed | 6559 * @return the string literal that was parsed |
| 6323 */ | 6560 */ |
| 6324 Token skipStringInterpolation(Token startToken) { | 6561 Token skipStringInterpolation(Token startToken) { |
| 6325 Token token = startToken; | 6562 Token token = startToken; |
| 6326 TokenType type = token.type; | 6563 TokenType type = token.type; |
| 6327 while (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic
al(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) { | 6564 while (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION) || identic
al(type, TokenType.STRING_INTERPOLATION_IDENTIFIER)) { |
| 6328 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) { | 6565 if (identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) { |
| 6329 token = token.next; | 6566 token = token.next; |
| 6330 type = token.type; | 6567 type = token.type; |
| 6568 // |
| 6569 // Rather than verify that the following tokens represent a valid expres
sion, we simply skip |
| 6570 // tokens until we reach the end of the interpolation, being careful to
handle nested string |
| 6571 // literals. |
| 6572 // |
| 6331 int bracketNestingLevel = 1; | 6573 int bracketNestingLevel = 1; |
| 6332 while (bracketNestingLevel > 0) { | 6574 while (bracketNestingLevel > 0) { |
| 6333 if (identical(type, TokenType.EOF)) { | 6575 if (identical(type, TokenType.EOF)) { |
| 6334 return null; | 6576 return null; |
| 6335 } else if (identical(type, TokenType.OPEN_CURLY_BRACKET)) { | 6577 } else if (identical(type, TokenType.OPEN_CURLY_BRACKET)) { |
| 6336 bracketNestingLevel++; | 6578 bracketNestingLevel++; |
| 6337 } else if (identical(type, TokenType.CLOSE_CURLY_BRACKET)) { | 6579 } else if (identical(type, TokenType.CLOSE_CURLY_BRACKET)) { |
| 6338 bracketNestingLevel--; | 6580 bracketNestingLevel--; |
| 6339 } else if (identical(type, TokenType.STRING)) { | 6581 } else if (identical(type, TokenType.STRING)) { |
| 6340 token = skipStringLiteral(token); | 6582 token = skipStringLiteral(token); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6477 * '<' typeParameter (',' typeParameter)* '>' | 6719 * '<' typeParameter (',' typeParameter)* '>' |
| 6478 * </pre> | 6720 * </pre> |
| 6479 * | 6721 * |
| 6480 * @param startToken the token at which parsing is to begin | 6722 * @param startToken the token at which parsing is to begin |
| 6481 * @return the token following the type parameter list that was parsed | 6723 * @return the token following the type parameter list that was parsed |
| 6482 */ | 6724 */ |
| 6483 Token skipTypeParameterList(Token startToken) { | 6725 Token skipTypeParameterList(Token startToken) { |
| 6484 if (!matches4(startToken, TokenType.LT)) { | 6726 if (!matches4(startToken, TokenType.LT)) { |
| 6485 return null; | 6727 return null; |
| 6486 } | 6728 } |
| 6729 // |
| 6730 // We can't skip a type parameter because it can be preceeded by metadata, s
o we just assume |
| 6731 // that everything before the matching end token is valid. |
| 6732 // |
| 6487 int depth = 1; | 6733 int depth = 1; |
| 6488 Token next = startToken.next; | 6734 Token next = startToken.next; |
| 6489 while (depth > 0) { | 6735 while (depth > 0) { |
| 6490 if (matches4(next, TokenType.EOF)) { | 6736 if (matches4(next, TokenType.EOF)) { |
| 6491 return null; | 6737 return null; |
| 6492 } else if (matches4(next, TokenType.LT)) { | 6738 } else if (matches4(next, TokenType.LT)) { |
| 6493 depth++; | 6739 depth++; |
| 6494 } else if (matches4(next, TokenType.GT)) { | 6740 } else if (matches4(next, TokenType.GT)) { |
| 6495 depth--; | 6741 depth--; |
| 6496 } else if (matches4(next, TokenType.GT_EQ)) { | 6742 } else if (matches4(next, TokenType.GT_EQ)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 6525 * @param lexeme the string containing the character(s) to be translated | 6771 * @param lexeme the string containing the character(s) to be translated |
| 6526 * @param index the index of the character to be translated | 6772 * @param index the index of the character to be translated |
| 6527 * @return the index of the next character to be translated | 6773 * @return the index of the next character to be translated |
| 6528 */ | 6774 */ |
| 6529 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) { | 6775 int translateCharacter(JavaStringBuilder builder, String lexeme, int index) { |
| 6530 int currentChar = lexeme.codeUnitAt(index); | 6776 int currentChar = lexeme.codeUnitAt(index); |
| 6531 if (currentChar != 0x5C) { | 6777 if (currentChar != 0x5C) { |
| 6532 builder.appendChar(currentChar); | 6778 builder.appendChar(currentChar); |
| 6533 return index + 1; | 6779 return index + 1; |
| 6534 } | 6780 } |
| 6781 // |
| 6782 // We have found an escape sequence, so we parse the string to determine wha
t kind of escape |
| 6783 // sequence and what character to add to the builder. |
| 6784 // |
| 6535 int length = lexeme.length; | 6785 int length = lexeme.length; |
| 6536 int currentIndex = index + 1; | 6786 int currentIndex = index + 1; |
| 6537 if (currentIndex >= length) { | 6787 if (currentIndex >= length) { |
| 6788 // Illegal escape sequence: no char after escape |
| 6789 // This cannot actually happen because it would require the escape charact
er to be the last |
| 6790 // character in the string, but if it were it would escape the closing quo
te, leaving the |
| 6791 // string unclosed. |
| 6792 // reportError(ParserErrorCode.MISSING_CHAR_IN_ESCAPE_SEQUENCE); |
| 6538 return length; | 6793 return length; |
| 6539 } | 6794 } |
| 6540 currentChar = lexeme.codeUnitAt(currentIndex); | 6795 currentChar = lexeme.codeUnitAt(currentIndex); |
| 6541 if (currentChar == 0x6E) { | 6796 if (currentChar == 0x6E) { |
| 6542 builder.appendChar(0xA); | 6797 builder.appendChar(0xA); |
| 6543 } else if (currentChar == 0x72) { | 6798 } else if (currentChar == 0x72) { |
| 6544 builder.appendChar(0xD); | 6799 builder.appendChar(0xD); |
| 6545 } else if (currentChar == 0x66) { | 6800 } else if (currentChar == 0x66) { |
| 6546 builder.appendChar(0xC); | 6801 builder.appendChar(0xC); |
| 6547 } else if (currentChar == 0x62) { | 6802 } else if (currentChar == 0x62) { |
| 6548 builder.appendChar(0x8); | 6803 builder.appendChar(0x8); |
| 6549 } else if (currentChar == 0x74) { | 6804 } else if (currentChar == 0x74) { |
| 6550 builder.appendChar(0x9); | 6805 builder.appendChar(0x9); |
| 6551 } else if (currentChar == 0x76) { | 6806 } else if (currentChar == 0x76) { |
| 6552 builder.appendChar(0xB); | 6807 builder.appendChar(0xB); |
| 6553 } else if (currentChar == 0x78) { | 6808 } else if (currentChar == 0x78) { |
| 6554 if (currentIndex + 2 >= length) { | 6809 if (currentIndex + 2 >= length) { |
| 6810 // Illegal escape sequence: not enough hex digits |
| 6555 reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []); | 6811 reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []); |
| 6556 return length; | 6812 return length; |
| 6557 } | 6813 } |
| 6558 int firstDigit = lexeme.codeUnitAt(currentIndex + 1); | 6814 int firstDigit = lexeme.codeUnitAt(currentIndex + 1); |
| 6559 int secondDigit = lexeme.codeUnitAt(currentIndex + 2); | 6815 int secondDigit = lexeme.codeUnitAt(currentIndex + 2); |
| 6560 if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) { | 6816 if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit)) { |
| 6817 // Illegal escape sequence: invalid hex digit |
| 6561 reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []); | 6818 reportError11(ParserErrorCode.INVALID_HEX_ESCAPE, []); |
| 6562 } else { | 6819 } else { |
| 6563 builder.appendChar(((Character.digit(firstDigit, 16) << 4) + Character.d
igit(secondDigit, 16))); | 6820 builder.appendChar(((Character.digit(firstDigit, 16) << 4) + Character.d
igit(secondDigit, 16))); |
| 6564 } | 6821 } |
| 6565 return currentIndex + 3; | 6822 return currentIndex + 3; |
| 6566 } else if (currentChar == 0x75) { | 6823 } else if (currentChar == 0x75) { |
| 6567 currentIndex++; | 6824 currentIndex++; |
| 6568 if (currentIndex >= length) { | 6825 if (currentIndex >= length) { |
| 6826 // Illegal escape sequence: not enough hex digits |
| 6569 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6827 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6570 return length; | 6828 return length; |
| 6571 } | 6829 } |
| 6572 currentChar = lexeme.codeUnitAt(currentIndex); | 6830 currentChar = lexeme.codeUnitAt(currentIndex); |
| 6573 if (currentChar == 0x7B) { | 6831 if (currentChar == 0x7B) { |
| 6574 currentIndex++; | 6832 currentIndex++; |
| 6575 if (currentIndex >= length) { | 6833 if (currentIndex >= length) { |
| 6834 // Illegal escape sequence: incomplete escape |
| 6576 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6835 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6577 return length; | 6836 return length; |
| 6578 } | 6837 } |
| 6579 currentChar = lexeme.codeUnitAt(currentIndex); | 6838 currentChar = lexeme.codeUnitAt(currentIndex); |
| 6580 int digitCount = 0; | 6839 int digitCount = 0; |
| 6581 int value = 0; | 6840 int value = 0; |
| 6582 while (currentChar != 0x7D) { | 6841 while (currentChar != 0x7D) { |
| 6583 if (!isHexDigit(currentChar)) { | 6842 if (!isHexDigit(currentChar)) { |
| 6843 // Illegal escape sequence: invalid hex digit |
| 6584 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6844 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6585 currentIndex++; | 6845 currentIndex++; |
| 6586 while (currentIndex < length && lexeme.codeUnitAt(currentIndex) != 0
x7D) { | 6846 while (currentIndex < length && lexeme.codeUnitAt(currentIndex) != 0
x7D) { |
| 6587 currentIndex++; | 6847 currentIndex++; |
| 6588 } | 6848 } |
| 6589 return currentIndex + 1; | 6849 return currentIndex + 1; |
| 6590 } | 6850 } |
| 6591 digitCount++; | 6851 digitCount++; |
| 6592 value = (value << 4) + Character.digit(currentChar, 16); | 6852 value = (value << 4) + Character.digit(currentChar, 16); |
| 6593 currentIndex++; | 6853 currentIndex++; |
| 6594 if (currentIndex >= length) { | 6854 if (currentIndex >= length) { |
| 6855 // Illegal escape sequence: incomplete escape |
| 6595 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6856 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6596 return length; | 6857 return length; |
| 6597 } | 6858 } |
| 6598 currentChar = lexeme.codeUnitAt(currentIndex); | 6859 currentChar = lexeme.codeUnitAt(currentIndex); |
| 6599 } | 6860 } |
| 6600 if (digitCount < 1 || digitCount > 6) { | 6861 if (digitCount < 1 || digitCount > 6) { |
| 6862 // Illegal escape sequence: not enough or too many hex digits |
| 6601 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6863 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6602 } | 6864 } |
| 6603 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), va
lue, index, currentIndex); | 6865 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1), va
lue, index, currentIndex); |
| 6604 return currentIndex + 1; | 6866 return currentIndex + 1; |
| 6605 } else { | 6867 } else { |
| 6606 if (currentIndex + 3 >= length) { | 6868 if (currentIndex + 3 >= length) { |
| 6869 // Illegal escape sequence: not enough hex digits |
| 6607 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6870 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6608 return length; | 6871 return length; |
| 6609 } | 6872 } |
| 6610 int firstDigit = currentChar; | 6873 int firstDigit = currentChar; |
| 6611 int secondDigit = lexeme.codeUnitAt(currentIndex + 1); | 6874 int secondDigit = lexeme.codeUnitAt(currentIndex + 1); |
| 6612 int thirdDigit = lexeme.codeUnitAt(currentIndex + 2); | 6875 int thirdDigit = lexeme.codeUnitAt(currentIndex + 2); |
| 6613 int fourthDigit = lexeme.codeUnitAt(currentIndex + 3); | 6876 int fourthDigit = lexeme.codeUnitAt(currentIndex + 3); |
| 6614 if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(t
hirdDigit) || !isHexDigit(fourthDigit)) { | 6877 if (!isHexDigit(firstDigit) || !isHexDigit(secondDigit) || !isHexDigit(t
hirdDigit) || !isHexDigit(fourthDigit)) { |
| 6878 // Illegal escape sequence: invalid hex digits |
| 6615 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); | 6879 reportError11(ParserErrorCode.INVALID_UNICODE_ESCAPE, []); |
| 6616 } else { | 6880 } else { |
| 6617 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1),
(((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) <
< 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16)
, index, currentIndex + 3); | 6881 appendScalarValue(builder, lexeme.substring(index, currentIndex + 1),
(((((Character.digit(firstDigit, 16) << 4) + Character.digit(secondDigit, 16)) <
< 4) + Character.digit(thirdDigit, 16)) << 4) + Character.digit(fourthDigit, 16)
, index, currentIndex + 3); |
| 6618 } | 6882 } |
| 6619 return currentIndex + 4; | 6883 return currentIndex + 4; |
| 6620 } | 6884 } |
| 6621 } else { | 6885 } else { |
| 6622 builder.appendChar(currentChar); | 6886 builder.appendChar(currentChar); |
| 6623 } | 6887 } |
| 6624 return currentIndex + 1; | 6888 return currentIndex + 1; |
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8162 */ | 8426 */ |
| 8163 bool isEqual(ASTNode fromNode, ASTNode toNode) { | 8427 bool isEqual(ASTNode fromNode, ASTNode toNode) { |
| 8164 if (fromNode == null) { | 8428 if (fromNode == null) { |
| 8165 return toNode == null; | 8429 return toNode == null; |
| 8166 } else if (toNode == null) { | 8430 } else if (toNode == null) { |
| 8167 return false; | 8431 return false; |
| 8168 } else if (fromNode.runtimeType == toNode.runtimeType) { | 8432 } else if (fromNode.runtimeType == toNode.runtimeType) { |
| 8169 this._toNode = toNode; | 8433 this._toNode = toNode; |
| 8170 return fromNode.accept(this); | 8434 return fromNode.accept(this); |
| 8171 } | 8435 } |
| 8436 // |
| 8437 // Check for a simple transformation caused by entering a period. |
| 8438 // |
| 8172 if (toNode is PrefixedIdentifier) { | 8439 if (toNode is PrefixedIdentifier) { |
| 8173 SimpleIdentifier prefix = toNode.prefix; | 8440 SimpleIdentifier prefix = toNode.prefix; |
| 8174 if (fromNode.runtimeType == prefix.runtimeType) { | 8441 if (fromNode.runtimeType == prefix.runtimeType) { |
| 8175 this._toNode = prefix; | 8442 this._toNode = prefix; |
| 8176 return fromNode.accept(this); | 8443 return fromNode.accept(this); |
| 8177 } | 8444 } |
| 8178 } else if (toNode is PropertyAccess) { | 8445 } else if (toNode is PropertyAccess) { |
| 8179 Expression target = toNode.target; | 8446 Expression target = toNode.target; |
| 8180 if (fromNode.runtimeType == target.runtimeType) { | 8447 if (fromNode.runtimeType == target.runtimeType) { |
| 8181 this._toNode = target; | 8448 this._toNode = target; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8250 } | 8517 } |
| 8251 return true; | 8518 return true; |
| 8252 } | 8519 } |
| 8253 } | 8520 } |
| 8254 | 8521 |
| 8255 /** | 8522 /** |
| 8256 * Instances of the class {link ToFormattedSourceVisitor} write a source represe
ntation of a visited | 8523 * Instances of the class {link ToFormattedSourceVisitor} write a source represe
ntation of a visited |
| 8257 * AST node (and all of it's children) to a writer. | 8524 * AST node (and all of it's children) to a writer. |
| 8258 */ | 8525 */ |
| 8259 class ToFormattedSourceVisitor implements ASTVisitor<Object> { | 8526 class ToFormattedSourceVisitor implements ASTVisitor<Object> { |
| 8527 static String COMMENTS_KEY = "List of comments before statement"; |
| 8528 |
| 8260 /** | 8529 /** |
| 8261 * The writer to which the source is to be written. | 8530 * The writer to which the source is to be written. |
| 8262 */ | 8531 */ |
| 8263 PrintWriter _writer; | 8532 PrintWriter _writer; |
| 8264 | 8533 |
| 8265 int _indentLevel = 0; | 8534 int _indentLevel = 0; |
| 8266 | 8535 |
| 8267 String _indentString = ""; | 8536 String _indentString = ""; |
| 8268 | 8537 |
| 8269 /** | 8538 /** |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8441 } | 8710 } |
| 8442 return null; | 8711 return null; |
| 8443 } | 8712 } |
| 8444 | 8713 |
| 8445 Object visitCommentReference(CommentReference node) => null; | 8714 Object visitCommentReference(CommentReference node) => null; |
| 8446 | 8715 |
| 8447 Object visitCompilationUnit(CompilationUnit node) { | 8716 Object visitCompilationUnit(CompilationUnit node) { |
| 8448 ScriptTag scriptTag = node.scriptTag; | 8717 ScriptTag scriptTag = node.scriptTag; |
| 8449 NodeList<Directive> directives = node.directives; | 8718 NodeList<Directive> directives = node.directives; |
| 8450 visit(scriptTag); | 8719 visit(scriptTag); |
| 8720 // directives |
| 8451 String prefix = scriptTag == null ? "" : " "; | 8721 String prefix = scriptTag == null ? "" : " "; |
| 8452 visitList7(prefix, directives, "\n"); | 8722 visitList7(prefix, directives, "\n"); |
| 8453 nl(); | 8723 nl(); |
| 8724 // declarations |
| 8454 prefix = scriptTag == null && directives.isEmpty ? "" : "\n"; | 8725 prefix = scriptTag == null && directives.isEmpty ? "" : "\n"; |
| 8455 visitList7(prefix, node.declarations, "\n\n"); | 8726 visitList7(prefix, node.declarations, "\n\n"); |
| 8456 return null; | 8727 return null; |
| 8457 } | 8728 } |
| 8458 | 8729 |
| 8459 Object visitConditionalExpression(ConditionalExpression node) { | 8730 Object visitConditionalExpression(ConditionalExpression node) { |
| 8460 visit(node.condition); | 8731 visit(node.condition); |
| 8461 _writer.print(" ? "); | 8732 _writer.print(" ? "); |
| 8462 visit(node.thenExpression); | 8733 visit(node.thenExpression); |
| 8463 _writer.print(" : "); | 8734 _writer.print(" : "); |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9157 | 9428 |
| 9158 void nl() { | 9429 void nl() { |
| 9159 _writer.print("\n"); | 9430 _writer.print("\n"); |
| 9160 } | 9431 } |
| 9161 | 9432 |
| 9162 void nl2() { | 9433 void nl2() { |
| 9163 nl(); | 9434 nl(); |
| 9164 indent(); | 9435 indent(); |
| 9165 } | 9436 } |
| 9166 | 9437 |
| 9438 void printLeadingComments(Statement statement) { |
| 9439 List<String> comments = statement.getProperty(COMMENTS_KEY) as List<String>; |
| 9440 if (comments == null) { |
| 9441 return; |
| 9442 } |
| 9443 for (String comment in comments) { |
| 9444 _writer.print(comment); |
| 9445 _writer.print("\n"); |
| 9446 indent(); |
| 9447 } |
| 9448 } |
| 9449 |
| 9167 /** | 9450 /** |
| 9168 * Safely visit the given node. | 9451 * Safely visit the given node. |
| 9169 * | 9452 * |
| 9170 * @param node the node to be visited | 9453 * @param node the node to be visited |
| 9171 */ | 9454 */ |
| 9172 void visit(ASTNode node) { | 9455 void visit(ASTNode node) { |
| 9173 if (node != null) { | 9456 if (node != null) { |
| 9174 node.accept(this); | 9457 node.accept(this); |
| 9175 } | 9458 } |
| 9176 } | 9459 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9262 * | 9545 * |
| 9263 * @param prefix the prefix to be printed if the list is not empty | 9546 * @param prefix the prefix to be printed if the list is not empty |
| 9264 * @param nodes the nodes to be printed | 9547 * @param nodes the nodes to be printed |
| 9265 * @param separator the separator to be printed between adjacent nodes | 9548 * @param separator the separator to be printed between adjacent nodes |
| 9266 * @param suffix the suffix to be printed if the list is not empty | 9549 * @param suffix the suffix to be printed if the list is not empty |
| 9267 */ | 9550 */ |
| 9268 void visitList8(String prefix, NodeList<ASTNode> nodes, String separator, Stri
ng suffix) { | 9551 void visitList8(String prefix, NodeList<ASTNode> nodes, String separator, Stri
ng suffix) { |
| 9269 if (nodes != null) { | 9552 if (nodes != null) { |
| 9270 int size = nodes.length; | 9553 int size = nodes.length; |
| 9271 if (size != 0) { | 9554 if (size != 0) { |
| 9555 // prefix |
| 9272 _writer.print(prefix); | 9556 _writer.print(prefix); |
| 9273 if (prefix.endsWith("\n")) { | 9557 if (prefix.endsWith("\n")) { |
| 9274 indent(); | 9558 indent(); |
| 9275 } | 9559 } |
| 9560 // nodes |
| 9276 bool newLineSeparator = separator.endsWith("\n"); | 9561 bool newLineSeparator = separator.endsWith("\n"); |
| 9277 for (int i = 0; i < size; i++) { | 9562 for (int i = 0; i < size; i++) { |
| 9278 if (i > 0) { | 9563 if (i > 0) { |
| 9279 _writer.print(separator); | 9564 _writer.print(separator); |
| 9280 if (newLineSeparator) { | 9565 if (newLineSeparator) { |
| 9281 indent(); | 9566 indent(); |
| 9282 } | 9567 } |
| 9283 } | 9568 } |
| 9284 nodes[i].accept(this); | 9569 ASTNode node = nodes[i]; |
| 9570 if (node is Statement) { |
| 9571 printLeadingComments(node); |
| 9572 } |
| 9573 node.accept(this); |
| 9285 } | 9574 } |
| 9575 // suffix |
| 9286 _writer.print(suffix); | 9576 _writer.print(suffix); |
| 9287 } | 9577 } |
| 9288 } | 9578 } |
| 9289 } | 9579 } |
| 9290 | 9580 |
| 9291 /** | 9581 /** |
| 9292 * Print a list of tokens, separated by the given separator. | 9582 * Print a list of tokens, separated by the given separator. |
| 9293 * | 9583 * |
| 9294 * @param tokens the tokens to be printed | 9584 * @param tokens the tokens to be printed |
| 9295 * @param separator the separator to be printed between adjacent tokens | 9585 * @param separator the separator to be printed between adjacent tokens |
| 9296 */ | 9586 */ |
| 9297 void visitList9(List<Token> tokens, String separator) { | 9587 void visitList9(List<Token> tokens, String separator) { |
| 9298 int size = tokens.length; | 9588 int size = tokens.length; |
| 9299 for (int i = 0; i < size; i++) { | 9589 for (int i = 0; i < size; i++) { |
| 9300 if ("\n" == separator) { | 9590 if ("\n" == separator) { |
| 9301 _writer.print("\n"); | 9591 _writer.print("\n"); |
| 9302 indent(); | 9592 indent(); |
| 9303 } else if (i > 0) { | 9593 } else if (i > 0) { |
| 9304 _writer.print(separator); | 9594 _writer.print(separator); |
| 9305 } | 9595 } |
| 9306 _writer.print(tokens[i].lexeme); | 9596 _writer.print(tokens[i].lexeme); |
| 9307 } | 9597 } |
| 9308 } | 9598 } |
| 9309 } | 9599 } |
| OLD | NEW |