| 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 library analyzer.src.generated.parser; | 5 library analyzer.src.generated.parser; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 /** | 417 /** |
| 418 * Return `true` if the current token appears to be the beginning of a | 418 * Return `true` if the current token appears to be the beginning of a |
| 419 * function declaration. | 419 * function declaration. |
| 420 */ | 420 */ |
| 421 bool isFunctionDeclaration() { | 421 bool isFunctionDeclaration() { |
| 422 Keyword keyword = _currentToken.keyword; | 422 Keyword keyword = _currentToken.keyword; |
| 423 if (keyword == Keyword.VOID) { | 423 if (keyword == Keyword.VOID) { |
| 424 return true; | 424 return true; |
| 425 } | 425 } |
| 426 Token afterReturnType = skipTypeName(_currentToken); | 426 Token afterReturnType = skipTypeName(_currentToken); |
| 427 if (afterReturnType != null && |
| 428 _tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) { |
| 429 afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType); |
| 430 } |
| 427 if (afterReturnType == null) { | 431 if (afterReturnType == null) { |
| 428 // There was no return type, but it is optional, so go back to where we | 432 // There was no return type, but it is optional, so go back to where we |
| 429 // started. | 433 // started. |
| 430 afterReturnType = _currentToken; | 434 afterReturnType = _currentToken; |
| 431 } | 435 } |
| 432 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); | 436 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); |
| 433 if (afterIdentifier == null) { | 437 if (afterIdentifier == null) { |
| 434 // It's possible that we parsed the function name as if it were a type | 438 // It's possible that we parsed the function name as if it were a type |
| 435 // name, so see whether it makes sense if we assume that there is no type. | 439 // name, so see whether it makes sense if we assume that there is no type. |
| 436 afterIdentifier = skipSimpleIdentifier(_currentToken); | 440 afterIdentifier = skipSimpleIdentifier(_currentToken); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 // We know that we have an identifier, and need to see whether it might be | 535 // We know that we have an identifier, and need to see whether it might be |
| 532 // a type name. | 536 // a type name. |
| 533 if (_currentToken.type != TokenType.IDENTIFIER) { | 537 if (_currentToken.type != TokenType.IDENTIFIER) { |
| 534 allowAdditionalTokens = false; | 538 allowAdditionalTokens = false; |
| 535 } | 539 } |
| 536 Token token = skipTypeName(_currentToken); | 540 Token token = skipTypeName(_currentToken); |
| 537 if (token == null) { | 541 if (token == null) { |
| 538 // There was no type name, so this can't be a declaration. | 542 // There was no type name, so this can't be a declaration. |
| 539 return false; | 543 return false; |
| 540 } | 544 } |
| 545 if (_tokenMatchesKeyword(token, Keyword.FUNCTION)) { |
| 546 token = skipGenericFunctionTypeAfterReturnType(token); |
| 547 } |
| 541 if (token.type != TokenType.IDENTIFIER) { | 548 if (token.type != TokenType.IDENTIFIER) { |
| 542 allowAdditionalTokens = false; | 549 allowAdditionalTokens = false; |
| 543 } | 550 } |
| 544 token = skipSimpleIdentifier(token); | 551 token = skipSimpleIdentifier(token); |
| 545 if (token == null) { | 552 if (token == null) { |
| 546 return false; | 553 return false; |
| 547 } | 554 } |
| 548 TokenType type = token.type; | 555 TokenType type = token.type; |
| 549 // Usual cases in valid code: | 556 // Usual cases in valid code: |
| 550 // String v = ''; | 557 // String v = ''; |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 } else if (_matchesIdentifier() && | 1272 } else if (_matchesIdentifier() && |
| 1266 _peek().matchesAny(const <TokenType>[ | 1273 _peek().matchesAny(const <TokenType>[ |
| 1267 TokenType.OPEN_PAREN, | 1274 TokenType.OPEN_PAREN, |
| 1268 TokenType.OPEN_CURLY_BRACKET, | 1275 TokenType.OPEN_CURLY_BRACKET, |
| 1269 TokenType.FUNCTION, | 1276 TokenType.FUNCTION, |
| 1270 TokenType.LT | 1277 TokenType.LT |
| 1271 ])) { | 1278 ])) { |
| 1272 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1279 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1273 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, | 1280 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, |
| 1274 modifiers.externalKeyword, modifiers.staticKeyword, returnType); | 1281 modifiers.externalKeyword, modifiers.staticKeyword, returnType); |
| 1282 } else if (_matchesIdentifier() && |
| 1283 _peek().matchesAny(const <TokenType>[ |
| 1284 TokenType.EQ, |
| 1285 TokenType.COMMA, |
| 1286 TokenType.SEMICOLON |
| 1287 ])) { |
| 1288 if (returnType is! GenericFunctionType) { |
| 1289 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 1290 } |
| 1291 return parseInitializedIdentifierList( |
| 1292 commentAndMetadata, |
| 1293 modifiers.staticKeyword, |
| 1294 modifiers.covariantKeyword, |
| 1295 _validateModifiersForField(modifiers), |
| 1296 returnType); |
| 1275 } else { | 1297 } else { |
| 1276 // | 1298 // |
| 1277 // We have found an error of some kind. Try to recover. | 1299 // We have found an error of some kind. Try to recover. |
| 1278 // | 1300 // |
| 1279 if (_matchesIdentifier()) { | |
| 1280 if (_peek().matchesAny(const <TokenType>[ | |
| 1281 TokenType.EQ, | |
| 1282 TokenType.COMMA, | |
| 1283 TokenType.SEMICOLON | |
| 1284 ])) { | |
| 1285 // | |
| 1286 // We appear to have a variable declaration with a type of "void". | |
| 1287 // | |
| 1288 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); | |
| 1289 return parseInitializedIdentifierList( | |
| 1290 commentAndMetadata, | |
| 1291 modifiers.staticKeyword, | |
| 1292 modifiers.covariantKeyword, | |
| 1293 _validateModifiersForField(modifiers), | |
| 1294 returnType); | |
| 1295 } | |
| 1296 } | |
| 1297 if (_isOperator(_currentToken)) { | 1301 if (_isOperator(_currentToken)) { |
| 1298 // | 1302 // |
| 1299 // We appear to have found an operator declaration without the | 1303 // We appear to have found an operator declaration without the |
| 1300 // 'operator' keyword. | 1304 // 'operator' keyword. |
| 1301 // | 1305 // |
| 1302 _validateModifiersForOperator(modifiers); | 1306 _validateModifiersForOperator(modifiers); |
| 1303 return parseOperator( | 1307 return parseOperator( |
| 1304 commentAndMetadata, modifiers.externalKeyword, returnType); | 1308 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 1305 } | 1309 } |
| 1306 _reportErrorForToken( | 1310 _reportErrorForToken( |
| (...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 } else if (_matchesIdentifier() && | 2075 } else if (_matchesIdentifier() && |
| 2072 next.matchesAny(const <TokenType>[ | 2076 next.matchesAny(const <TokenType>[ |
| 2073 TokenType.OPEN_PAREN, | 2077 TokenType.OPEN_PAREN, |
| 2074 TokenType.OPEN_CURLY_BRACKET, | 2078 TokenType.OPEN_CURLY_BRACKET, |
| 2075 TokenType.FUNCTION, | 2079 TokenType.FUNCTION, |
| 2076 TokenType.LT | 2080 TokenType.LT |
| 2077 ])) { | 2081 ])) { |
| 2078 _validateModifiersForTopLevelFunction(modifiers); | 2082 _validateModifiersForTopLevelFunction(modifiers); |
| 2079 return parseFunctionDeclaration( | 2083 return parseFunctionDeclaration( |
| 2080 commentAndMetadata, modifiers.externalKeyword, returnType); | 2084 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2085 } else if (_matchesIdentifier() && |
| 2086 next.matchesAny(const <TokenType>[ |
| 2087 TokenType.EQ, |
| 2088 TokenType.COMMA, |
| 2089 TokenType.SEMICOLON |
| 2090 ])) { |
| 2091 if (returnType is! GenericFunctionType) { |
| 2092 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 2093 } |
| 2094 return astFactory.topLevelVariableDeclaration( |
| 2095 commentAndMetadata.comment, |
| 2096 commentAndMetadata.metadata, |
| 2097 parseVariableDeclarationListAfterType( |
| 2098 null, _validateModifiersForTopLevelVariable(modifiers), null), |
| 2099 _expect(TokenType.SEMICOLON)); |
| 2081 } else { | 2100 } else { |
| 2082 // | 2101 // |
| 2083 // We have found an error of some kind. Try to recover. | 2102 // We have found an error of some kind. Try to recover. |
| 2084 // | 2103 // |
| 2085 if (_matchesIdentifier()) { | |
| 2086 if (next.matchesAny(const <TokenType>[ | |
| 2087 TokenType.EQ, | |
| 2088 TokenType.COMMA, | |
| 2089 TokenType.SEMICOLON | |
| 2090 ])) { | |
| 2091 // | |
| 2092 // We appear to have a variable declaration with a type of "void". | |
| 2093 // | |
| 2094 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); | |
| 2095 return astFactory.topLevelVariableDeclaration( | |
| 2096 commentAndMetadata.comment, | |
| 2097 commentAndMetadata.metadata, | |
| 2098 parseVariableDeclarationListAfterType(null, | |
| 2099 _validateModifiersForTopLevelVariable(modifiers), null), | |
| 2100 _expect(TokenType.SEMICOLON)); | |
| 2101 } | |
| 2102 } | |
| 2103 _reportErrorForToken( | 2104 _reportErrorForToken( |
| 2104 ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); | 2105 ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); |
| 2105 return null; | 2106 return null; |
| 2106 } | 2107 } |
| 2107 } else if ((keyword == Keyword.GET || keyword == Keyword.SET) && | 2108 } else if ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 2108 _tokenMatchesIdentifier(next)) { | 2109 _tokenMatchesIdentifier(next)) { |
| 2109 _validateModifiersForTopLevelFunction(modifiers); | 2110 _validateModifiersForTopLevelFunction(modifiers); |
| 2110 return parseFunctionDeclaration( | 2111 return parseFunctionDeclaration( |
| 2111 commentAndMetadata, modifiers.externalKeyword, null); | 2112 commentAndMetadata, modifiers.externalKeyword, null); |
| 2112 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { | 2113 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { |
| (...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4131 Token next = _currentToken.next; | 4132 Token next = _currentToken.next; |
| 4132 if (_matchesIdentifier() && | 4133 if (_matchesIdentifier() && |
| 4133 next.matchesAny(const <TokenType>[ | 4134 next.matchesAny(const <TokenType>[ |
| 4134 TokenType.OPEN_PAREN, | 4135 TokenType.OPEN_PAREN, |
| 4135 TokenType.OPEN_CURLY_BRACKET, | 4136 TokenType.OPEN_CURLY_BRACKET, |
| 4136 TokenType.FUNCTION, | 4137 TokenType.FUNCTION, |
| 4137 TokenType.LT | 4138 TokenType.LT |
| 4138 ])) { | 4139 ])) { |
| 4139 return _parseFunctionDeclarationStatementAfterReturnType( | 4140 return _parseFunctionDeclarationStatementAfterReturnType( |
| 4140 commentAndMetadata, returnType); | 4141 commentAndMetadata, returnType); |
| 4142 } else if (_matchesIdentifier() && |
| 4143 next.matchesAny(const <TokenType>[ |
| 4144 TokenType.EQ, |
| 4145 TokenType.COMMA, |
| 4146 TokenType.SEMICOLON |
| 4147 ])) { |
| 4148 if (returnType is! GenericFunctionType) { |
| 4149 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 4150 } |
| 4151 return _parseVariableDeclarationStatementAfterType( |
| 4152 commentAndMetadata, null, returnType); |
| 4141 } else { | 4153 } else { |
| 4142 // | 4154 // |
| 4143 // We have found an error of some kind. Try to recover. | 4155 // We have found an error of some kind. Try to recover. |
| 4144 // | 4156 // |
| 4145 if (_matchesIdentifier()) { | 4157 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 4146 if (next.matchesAny(const <TokenType>[ | |
| 4147 TokenType.EQ, | |
| 4148 TokenType.COMMA, | |
| 4149 TokenType.SEMICOLON | |
| 4150 ])) { | |
| 4151 // | |
| 4152 // We appear to have a variable declaration with a type of "void". | |
| 4153 // | |
| 4154 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); | |
| 4155 return parseVariableDeclarationStatementAfterMetadata( | |
| 4156 commentAndMetadata); | |
| 4157 } | |
| 4158 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | |
| 4159 // | 4158 // |
| 4160 // We appear to have found an incomplete statement at the end of a | 4159 // We appear to have found an incomplete statement at the end of a |
| 4161 // block. Parse it as a variable declaration. | 4160 // block. Parse it as a variable declaration. |
| 4162 // | 4161 // |
| 4163 return _parseVariableDeclarationStatementAfterType( | 4162 return _parseVariableDeclarationStatementAfterType( |
| 4164 commentAndMetadata, null, returnType); | 4163 commentAndMetadata, null, returnType); |
| 4165 } | 4164 } |
| 4166 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); | 4165 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); |
| 4167 // TODO(brianwilkerson) Recover from this error. | 4166 // TODO(brianwilkerson) Recover from this error. |
| 4168 return astFactory | 4167 return astFactory |
| (...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5477 * actually creating a formal parameter list or changing the current token. | 5476 * actually creating a formal parameter list or changing the current token. |
| 5478 * Return the token following the parameter list that was parsed, or `null` | 5477 * Return the token following the parameter list that was parsed, or `null` |
| 5479 * if the given token is not the first token in a valid parameter list. | 5478 * if the given token is not the first token in a valid parameter list. |
| 5480 * | 5479 * |
| 5481 * This method must be kept in sync with [parseFormalParameterList]. | 5480 * This method must be kept in sync with [parseFormalParameterList]. |
| 5482 */ | 5481 */ |
| 5483 Token skipFormalParameterList(Token startToken) { | 5482 Token skipFormalParameterList(Token startToken) { |
| 5484 if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) { | 5483 if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) { |
| 5485 return null; | 5484 return null; |
| 5486 } | 5485 } |
| 5487 return (startToken as BeginToken).endToken; | 5486 return (startToken as BeginToken).endToken.next; |
| 5488 } | 5487 } |
| 5489 | 5488 |
| 5490 /** | 5489 /** |
| 5491 * Parse the portion of a generic function type after the return type, | 5490 * Parse the portion of a generic function type after the return type, |
| 5492 * starting at the [startToken], without actually creating a generic function | 5491 * starting at the [startToken], without actually creating a generic function |
| 5493 * type or changing the current token. Return the token following the generic | 5492 * type or changing the current token. Return the token following the generic |
| 5494 * function type that was parsed, or `null` if the given token is not the | 5493 * function type that was parsed, or `null` if the given token is not the |
| 5495 * first token in a valid generic function type. | 5494 * first token in a valid generic function type. |
| 5496 * | 5495 * |
| 5497 * This method must be kept in sync with | 5496 * This method must be kept in sync with |
| (...skipping 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7590 * metadata to be associated with the variable declaration statement, or | 7589 * metadata to be associated with the variable declaration statement, or |
| 7591 * `null` if there is no attempt at parsing the comment and metadata. The | 7590 * `null` if there is no attempt at parsing the comment and metadata. The |
| 7592 * [keyword] is the token representing the 'final', 'const' or 'var' keyword, | 7591 * [keyword] is the token representing the 'final', 'const' or 'var' keyword, |
| 7593 * or `null` if there is no keyword. The [type] is the type of the variables | 7592 * or `null` if there is no keyword. The [type] is the type of the variables |
| 7594 * in the list. Return the variable declaration statement that was parsed. | 7593 * in the list. Return the variable declaration statement that was parsed. |
| 7595 * | 7594 * |
| 7596 * variableDeclarationStatement ::= | 7595 * variableDeclarationStatement ::= |
| 7597 * variableDeclarationList ';' | 7596 * variableDeclarationList ';' |
| 7598 */ | 7597 */ |
| 7599 VariableDeclarationStatement _parseVariableDeclarationStatementAfterType( | 7598 VariableDeclarationStatement _parseVariableDeclarationStatementAfterType( |
| 7600 CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) { | 7599 CommentAndMetadata commentAndMetadata, |
| 7600 Token keyword, |
| 7601 TypeAnnotation type) { |
| 7601 VariableDeclarationList variableList = | 7602 VariableDeclarationList variableList = |
| 7602 parseVariableDeclarationListAfterType( | 7603 parseVariableDeclarationListAfterType( |
| 7603 commentAndMetadata, keyword, type); | 7604 commentAndMetadata, keyword, type); |
| 7604 Token semicolon = _expect(TokenType.SEMICOLON); | 7605 Token semicolon = _expect(TokenType.SEMICOLON); |
| 7605 return astFactory.variableDeclarationStatement(variableList, semicolon); | 7606 return astFactory.variableDeclarationStatement(variableList, semicolon); |
| 7606 } | 7607 } |
| 7607 | 7608 |
| 7608 /** | 7609 /** |
| 7609 * Return the token that is immediately after the current token. This is | 7610 * Return the token that is immediately after the current token. This is |
| 7610 * equivalent to [_peekAt](1). | 7611 * equivalent to [_peekAt](1). |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8557 } | 8558 } |
| 8558 if (modifiers.finalKeyword != null) { | 8559 if (modifiers.finalKeyword != null) { |
| 8559 _reportErrorForToken( | 8560 _reportErrorForToken( |
| 8560 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); | 8561 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); |
| 8561 } | 8562 } |
| 8562 if (modifiers.varKeyword != null) { | 8563 if (modifiers.varKeyword != null) { |
| 8563 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); | 8564 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); |
| 8564 } | 8565 } |
| 8565 } | 8566 } |
| 8566 } | 8567 } |
| OLD | NEW |