| 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.parser; | 5 library analyzer.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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 | 344 |
| 345 /** | 345 /** |
| 346 * Return `true` if the current token is the first token of a return type that | 346 * Return `true` if the current token is the first token of a return type that |
| 347 * is followed by an identifier, possibly followed by a list of type | 347 * is followed by an identifier, possibly followed by a list of type |
| 348 * parameters, followed by a left-parenthesis. This is used by | 348 * parameters, followed by a left-parenthesis. This is used by |
| 349 * [parseTypeAlias] to determine whether or not to parse a return type. | 349 * [parseTypeAlias] to determine whether or not to parse a return type. |
| 350 */ | 350 */ |
| 351 bool get hasReturnTypeInTypeAlias { | 351 bool get hasReturnTypeInTypeAlias { |
| 352 // TODO(brianwilkerson) This is too expensive as implemented and needs to be | 352 // TODO(brianwilkerson) This is too expensive as implemented and needs to be |
| 353 // re-implemented or removed. | 353 // re-implemented or removed. |
| 354 Token next = skipTypeAnnotation(_currentToken); | 354 Token next = skipReturnType(_currentToken); |
| 355 if (next == null) { | 355 if (next == null) { |
| 356 return false; | 356 return false; |
| 357 } | 357 } |
| 358 return _tokenMatchesIdentifier(next); | 358 return _tokenMatchesIdentifier(next); |
| 359 } | 359 } |
| 360 | 360 |
| 361 /** | 361 /** |
| 362 * Set whether the parser is to parse the async support. | 362 * Set whether the parser is to parse the async support. |
| 363 * | 363 * |
| 364 * Support for removing the 'async' library has been removed. | 364 * Support for removing the 'async' library has been removed. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 _currentToken = _currentToken.next; | 442 _currentToken = _currentToken.next; |
| 443 return token; | 443 return token; |
| 444 } | 444 } |
| 445 | 445 |
| 446 /** | 446 /** |
| 447 * Return `true` if the current token appears to be the beginning of a | 447 * Return `true` if the current token appears to be the beginning of a |
| 448 * function declaration. | 448 * function declaration. |
| 449 */ | 449 */ |
| 450 bool isFunctionDeclaration() { | 450 bool isFunctionDeclaration() { |
| 451 Keyword keyword = _currentToken.keyword; | 451 Keyword keyword = _currentToken.keyword; |
| 452 Token afterReturnType = skipTypeWithoutFunction(_currentToken); | 452 if (keyword == Keyword.VOID) { |
| 453 return true; |
| 454 } |
| 455 Token afterReturnType = skipTypeName(_currentToken); |
| 453 if (afterReturnType != null && | 456 if (afterReturnType != null && |
| 454 _tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) { | 457 _tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) { |
| 455 afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType); | 458 afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType); |
| 456 } | 459 } |
| 457 if (afterReturnType == null) { | 460 if (afterReturnType == null) { |
| 458 // There was no return type, but it is optional, so go back to where we | 461 // There was no return type, but it is optional, so go back to where we |
| 459 // started. | 462 // started. |
| 460 afterReturnType = _currentToken; | 463 afterReturnType = _currentToken; |
| 461 } | 464 } |
| 462 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); | 465 Token afterIdentifier = skipSimpleIdentifier(afterReturnType); |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 ])) { | 1321 ])) { |
| 1319 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1322 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1320 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, | 1323 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, |
| 1321 modifiers.externalKeyword, modifiers.staticKeyword, returnType); | 1324 modifiers.externalKeyword, modifiers.staticKeyword, returnType); |
| 1322 } else if (_matchesIdentifier() && | 1325 } else if (_matchesIdentifier() && |
| 1323 _peek().matchesAny(const <TokenType>[ | 1326 _peek().matchesAny(const <TokenType>[ |
| 1324 TokenType.EQ, | 1327 TokenType.EQ, |
| 1325 TokenType.COMMA, | 1328 TokenType.COMMA, |
| 1326 TokenType.SEMICOLON | 1329 TokenType.SEMICOLON |
| 1327 ])) { | 1330 ])) { |
| 1331 if (returnType is! GenericFunctionType) { |
| 1332 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 1333 } |
| 1328 return parseInitializedIdentifierList( | 1334 return parseInitializedIdentifierList( |
| 1329 commentAndMetadata, | 1335 commentAndMetadata, |
| 1330 modifiers.staticKeyword, | 1336 modifiers.staticKeyword, |
| 1331 modifiers.covariantKeyword, | 1337 modifiers.covariantKeyword, |
| 1332 _validateModifiersForField(modifiers), | 1338 _validateModifiersForField(modifiers), |
| 1333 returnType); | 1339 returnType); |
| 1334 } else { | 1340 } else { |
| 1335 // | 1341 // |
| 1336 // We have found an error of some kind. Try to recover. | 1342 // We have found an error of some kind. Try to recover. |
| 1337 // | 1343 // |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 ])) { | 2130 ])) { |
| 2125 _validateModifiersForTopLevelFunction(modifiers); | 2131 _validateModifiersForTopLevelFunction(modifiers); |
| 2126 return parseFunctionDeclaration( | 2132 return parseFunctionDeclaration( |
| 2127 commentAndMetadata, modifiers.externalKeyword, returnType); | 2133 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2128 } else if (_matchesIdentifier() && | 2134 } else if (_matchesIdentifier() && |
| 2129 next.matchesAny(const <TokenType>[ | 2135 next.matchesAny(const <TokenType>[ |
| 2130 TokenType.EQ, | 2136 TokenType.EQ, |
| 2131 TokenType.COMMA, | 2137 TokenType.COMMA, |
| 2132 TokenType.SEMICOLON | 2138 TokenType.SEMICOLON |
| 2133 ])) { | 2139 ])) { |
| 2140 if (returnType is! GenericFunctionType) { |
| 2141 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 2142 } |
| 2134 return astFactory.topLevelVariableDeclaration( | 2143 return astFactory.topLevelVariableDeclaration( |
| 2135 commentAndMetadata.comment, | 2144 commentAndMetadata.comment, |
| 2136 commentAndMetadata.metadata, | 2145 commentAndMetadata.metadata, |
| 2137 parseVariableDeclarationListAfterType(null, | 2146 parseVariableDeclarationListAfterType(null, |
| 2138 _validateModifiersForTopLevelVariable(modifiers), returnType), | 2147 _validateModifiersForTopLevelVariable(modifiers), returnType), |
| 2139 _expect(TokenType.SEMICOLON)); | 2148 _expect(TokenType.SEMICOLON)); |
| 2140 } else { | 2149 } else { |
| 2141 // | 2150 // |
| 2142 // We have found an error of some kind. Try to recover. | 2151 // We have found an error of some kind. Try to recover. |
| 2143 // | 2152 // |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2201 _reportErrorForCurrentToken( | 2210 _reportErrorForCurrentToken( |
| 2202 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); | 2211 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); |
| 2203 } | 2212 } |
| 2204 return astFactory.topLevelVariableDeclaration( | 2213 return astFactory.topLevelVariableDeclaration( |
| 2205 commentAndMetadata.comment, | 2214 commentAndMetadata.comment, |
| 2206 commentAndMetadata.metadata, | 2215 commentAndMetadata.metadata, |
| 2207 parseVariableDeclarationListAfterType( | 2216 parseVariableDeclarationListAfterType( |
| 2208 null, _validateModifiersForTopLevelVariable(modifiers), null), | 2217 null, _validateModifiersForTopLevelVariable(modifiers), null), |
| 2209 _expect(TokenType.SEMICOLON)); | 2218 _expect(TokenType.SEMICOLON)); |
| 2210 } | 2219 } |
| 2211 TypeAnnotation returnType = parseTypeAnnotation(false); | 2220 TypeAnnotation returnType = parseReturnType(false); |
| 2212 keyword = _currentToken.keyword; | 2221 keyword = _currentToken.keyword; |
| 2213 next = _peek(); | 2222 next = _peek(); |
| 2214 if ((keyword == Keyword.GET || keyword == Keyword.SET) && | 2223 if ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 2215 _tokenMatchesIdentifier(next)) { | 2224 _tokenMatchesIdentifier(next)) { |
| 2216 _validateModifiersForTopLevelFunction(modifiers); | 2225 _validateModifiersForTopLevelFunction(modifiers); |
| 2217 return parseFunctionDeclaration( | 2226 return parseFunctionDeclaration( |
| 2218 commentAndMetadata, modifiers.externalKeyword, returnType); | 2227 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2219 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { | 2228 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { |
| 2220 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); | 2229 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); |
| 2221 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( | 2230 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( |
| (...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2876 } | 2885 } |
| 2877 } else if (keyword == Keyword.VAR) { | 2886 } else if (keyword == Keyword.VAR) { |
| 2878 keywordToken = getAndAdvance(); | 2887 keywordToken = getAndAdvance(); |
| 2879 // Support `var/*=T*/ x;` | 2888 // Support `var/*=T*/ x;` |
| 2880 type = _parseOptionalTypeNameComment(); | 2889 type = _parseOptionalTypeNameComment(); |
| 2881 if (type != null) { | 2890 if (type != null) { |
| 2882 // Clear the keyword to prevent an error. | 2891 // Clear the keyword to prevent an error. |
| 2883 keywordToken = null; | 2892 keywordToken = null; |
| 2884 } | 2893 } |
| 2885 } else if (_isTypedIdentifier(_currentToken)) { | 2894 } else if (_isTypedIdentifier(_currentToken)) { |
| 2886 type = parseTypeAnnotation(false); | 2895 type = parseReturnType(false); |
| 2887 } else if (inFunctionType && _matchesIdentifier()) { | 2896 } else if (inFunctionType && _matchesIdentifier()) { |
| 2888 type = parseTypeAnnotation(false); | 2897 type = parseTypeAnnotation(false); |
| 2889 } else if (!optional) { | 2898 } else if (!optional) { |
| 2890 // If there is a valid type immediately following an unexpected token, | 2899 // If there is a valid type immediately following an unexpected token, |
| 2891 // then report and skip the unexpected token. | 2900 // then report and skip the unexpected token. |
| 2892 Token next = _peek(); | 2901 Token next = _peek(); |
| 2893 Keyword nextKeyword = next.keyword; | 2902 Keyword nextKeyword = next.keyword; |
| 2894 if (nextKeyword == Keyword.FINAL || | 2903 if (nextKeyword == Keyword.FINAL || |
| 2895 nextKeyword == Keyword.CONST || | 2904 nextKeyword == Keyword.CONST || |
| 2896 nextKeyword == Keyword.VAR || | 2905 nextKeyword == Keyword.VAR || |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3398 * Parse the portion of a generic function type following the [returnType]. | 3407 * Parse the portion of a generic function type following the [returnType]. |
| 3399 * | 3408 * |
| 3400 * functionType ::= | 3409 * functionType ::= |
| 3401 * returnType? 'Function' typeParameters? parameterTypeList | 3410 * returnType? 'Function' typeParameters? parameterTypeList |
| 3402 * parameterTypeList ::= | 3411 * parameterTypeList ::= |
| 3403 * '(' ')' | | 3412 * '(' ')' | |
| 3404 * | '(' normalParameterTypes ','? ')' | | 3413 * | '(' normalParameterTypes ','? ')' | |
| 3405 * | '(' normalParameterTypes ',' optionalParameterTypes ')' | | 3414 * | '(' normalParameterTypes ',' optionalParameterTypes ')' | |
| 3406 * | '(' optionalParameterTypes ')' | 3415 * | '(' optionalParameterTypes ')' |
| 3407 * normalParameterTypes ::= | 3416 * normalParameterTypes ::= |
| 3408 * normalParameterType (',' normalParameterType)* | 3417 * normalParameterType (',' normalParameterType)* |
| 3409 * normalParameterType ::= | 3418 * normalParameterType ::= |
| 3410 * type | typedIdentifier | 3419 * type | typedIdentifier |
| 3411 * optionalParameterTypes ::= | 3420 * optionalParameterTypes ::= |
| 3412 * optionalPositionalParameterTypes | namedParameterTypes | 3421 * optionalPositionalParameterTypes | namedParameterTypes |
| 3413 * optionalPositionalParameterTypes ::= | 3422 * optionalPositionalParameterTypes ::= |
| 3414 * '[' normalParameterTypes ','? ']' | 3423 * '[' normalParameterTypes ','? ']' |
| 3415 * namedParameterTypes ::= | 3424 * namedParameterTypes ::= |
| 3416 * '{' typedIdentifier (',' typedIdentifier)* ','? '}' | 3425 * '{' typedIdentifier (',' typedIdentifier)* ','? '}' |
| 3417 * typedIdentifier ::= | 3426 * typedIdentifier ::= |
| 3418 * type identifier | 3427 * type identifier |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4121 TokenType.LT | 4130 TokenType.LT |
| 4122 ])) { | 4131 ])) { |
| 4123 return _parseFunctionDeclarationStatementAfterReturnType( | 4132 return _parseFunctionDeclarationStatementAfterReturnType( |
| 4124 commentAndMetadata, returnType); | 4133 commentAndMetadata, returnType); |
| 4125 } else if (_matchesIdentifier() && | 4134 } else if (_matchesIdentifier() && |
| 4126 next.matchesAny(const <TokenType>[ | 4135 next.matchesAny(const <TokenType>[ |
| 4127 TokenType.EQ, | 4136 TokenType.EQ, |
| 4128 TokenType.COMMA, | 4137 TokenType.COMMA, |
| 4129 TokenType.SEMICOLON | 4138 TokenType.SEMICOLON |
| 4130 ])) { | 4139 ])) { |
| 4140 if (returnType is! GenericFunctionType) { |
| 4141 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 4142 } |
| 4131 return _parseVariableDeclarationStatementAfterType( | 4143 return _parseVariableDeclarationStatementAfterType( |
| 4132 commentAndMetadata, null, returnType); | 4144 commentAndMetadata, null, returnType); |
| 4133 } else { | 4145 } else { |
| 4134 // | 4146 // |
| 4135 // We have found an error of some kind. Try to recover. | 4147 // We have found an error of some kind. Try to recover. |
| 4136 // | 4148 // |
| 4137 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | 4149 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 4138 // | 4150 // |
| 4139 // We appear to have found an incomplete statement at the end of a | 4151 // We appear to have found an incomplete statement at the end of a |
| 4140 // block. Parse it as a variable declaration. | 4152 // block. Parse it as a variable declaration. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4198 TokenType.LT | 4210 TokenType.LT |
| 4199 ])) { | 4211 ])) { |
| 4200 return _parseFunctionDeclarationStatementAfterReturnType( | 4212 return _parseFunctionDeclarationStatementAfterReturnType( |
| 4201 commentAndMetadata, returnType); | 4213 commentAndMetadata, returnType); |
| 4202 } else if (_matchesIdentifier() && | 4214 } else if (_matchesIdentifier() && |
| 4203 next.matchesAny(const <TokenType>[ | 4215 next.matchesAny(const <TokenType>[ |
| 4204 TokenType.EQ, | 4216 TokenType.EQ, |
| 4205 TokenType.COMMA, | 4217 TokenType.COMMA, |
| 4206 TokenType.SEMICOLON | 4218 TokenType.SEMICOLON |
| 4207 ])) { | 4219 ])) { |
| 4220 if (returnType is! GenericFunctionType) { |
| 4221 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 4222 } |
| 4208 return _parseVariableDeclarationStatementAfterType( | 4223 return _parseVariableDeclarationStatementAfterType( |
| 4209 commentAndMetadata, null, returnType); | 4224 commentAndMetadata, null, returnType); |
| 4210 } else { | 4225 } else { |
| 4211 // | 4226 // |
| 4212 // We have found an error of some kind. Try to recover. | 4227 // We have found an error of some kind. Try to recover. |
| 4213 // | 4228 // |
| 4214 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | 4229 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 4215 // | 4230 // |
| 4216 // We appear to have found an incomplete statement at the end of a | 4231 // We appear to have found an incomplete statement at the end of a |
| 4217 // block. Parse it as a variable declaration. | 4232 // block. Parse it as a variable declaration. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4343 identifier: identifier, | 4358 identifier: identifier, |
| 4344 typeParameters: typeParameters, | 4359 typeParameters: typeParameters, |
| 4345 parameters: parameters); | 4360 parameters: parameters); |
| 4346 } | 4361 } |
| 4347 } else if (typeParameters != null) { | 4362 } else if (typeParameters != null) { |
| 4348 // TODO(brianwilkerson) Report an error. It looks like a function-typed | 4363 // TODO(brianwilkerson) Report an error. It looks like a function-typed |
| 4349 // parameter with no parameter list. | 4364 // parameter with no parameter list. |
| 4350 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.
endToken); | 4365 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.
endToken); |
| 4351 } | 4366 } |
| 4352 TypeAnnotation type = holder.type; | 4367 TypeAnnotation type = holder.type; |
| 4353 if (type != null && | 4368 if (type != null) { |
| 4354 holder.keyword != null && | 4369 if (type is TypeName && |
| 4355 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { | 4370 _tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) { |
| 4356 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); | 4371 _reportErrorForToken( |
| 4372 ParserErrorCode.VOID_PARAMETER, type.name.beginToken); |
| 4373 } else if (holder.keyword != null && |
| 4374 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { |
| 4375 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); |
| 4376 } |
| 4357 } | 4377 } |
| 4358 if (thisKeyword != null) { | 4378 if (thisKeyword != null) { |
| 4359 // TODO(brianwilkerson) If there are type parameters but no parameters, | 4379 // TODO(brianwilkerson) If there are type parameters but no parameters, |
| 4360 // should we create a synthetic empty parameter list here so we can | 4380 // should we create a synthetic empty parameter list here so we can |
| 4361 // capture the type parameters? | 4381 // capture the type parameters? |
| 4362 return astFactory.fieldFormalParameter2( | 4382 return astFactory.fieldFormalParameter2( |
| 4363 comment: commentAndMetadata.comment, | 4383 comment: commentAndMetadata.comment, |
| 4364 metadata: commentAndMetadata.metadata, | 4384 metadata: commentAndMetadata.metadata, |
| 4365 covariantKeyword: covariantKeyword, | 4385 covariantKeyword: covariantKeyword, |
| 4366 keyword: holder.keyword, | 4386 keyword: holder.keyword, |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4674 Expression expression = astFactory.superExpression(getAndAdvance()); | 4694 Expression expression = astFactory.superExpression(getAndAdvance()); |
| 4675 Token operator = getAndAdvance(); | 4695 Token operator = getAndAdvance(); |
| 4676 return astFactory.binaryExpression( | 4696 return astFactory.binaryExpression( |
| 4677 expression, operator, parseBitwiseOrExpression()); | 4697 expression, operator, parseBitwiseOrExpression()); |
| 4678 } | 4698 } |
| 4679 Expression expression = parseBitwiseOrExpression(); | 4699 Expression expression = parseBitwiseOrExpression(); |
| 4680 Keyword keyword = _currentToken.keyword; | 4700 Keyword keyword = _currentToken.keyword; |
| 4681 if (keyword == Keyword.AS) { | 4701 if (keyword == Keyword.AS) { |
| 4682 Token asOperator = getAndAdvance(); | 4702 Token asOperator = getAndAdvance(); |
| 4683 return astFactory.asExpression( | 4703 return astFactory.asExpression( |
| 4684 expression, asOperator, parseTypeNotVoid(true)); | 4704 expression, asOperator, parseTypeAnnotation(true)); |
| 4685 } else if (keyword == Keyword.IS) { | 4705 } else if (keyword == Keyword.IS) { |
| 4686 Token isOperator = getAndAdvance(); | 4706 Token isOperator = getAndAdvance(); |
| 4687 Token notOperator = null; | 4707 Token notOperator = null; |
| 4688 if (_matches(TokenType.BANG)) { | 4708 if (_matches(TokenType.BANG)) { |
| 4689 notOperator = getAndAdvance(); | 4709 notOperator = getAndAdvance(); |
| 4690 } | 4710 } |
| 4691 TypeAnnotation type = parseTypeNotVoid(true); | 4711 TypeAnnotation type = parseTypeAnnotation(true); |
| 4692 return astFactory.isExpression(expression, isOperator, notOperator, type); | 4712 return astFactory.isExpression(expression, isOperator, notOperator, type); |
| 4693 } else if (_currentToken.type.isRelationalOperator) { | 4713 } else if (_currentToken.type.isRelationalOperator) { |
| 4694 Token operator = getAndAdvance(); | 4714 Token operator = getAndAdvance(); |
| 4695 return astFactory.binaryExpression( | 4715 return astFactory.binaryExpression( |
| 4696 expression, operator, parseBitwiseOrExpression()); | 4716 expression, operator, parseBitwiseOrExpression()); |
| 4697 } | 4717 } |
| 4698 return expression; | 4718 return expression; |
| 4699 } | 4719 } |
| 4700 | 4720 |
| 4701 /** | 4721 /** |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4721 Token returnKeyword = getAndAdvance(); | 4741 Token returnKeyword = getAndAdvance(); |
| 4722 if (_matches(TokenType.SEMICOLON)) { | 4742 if (_matches(TokenType.SEMICOLON)) { |
| 4723 return astFactory.returnStatement(returnKeyword, null, getAndAdvance()); | 4743 return astFactory.returnStatement(returnKeyword, null, getAndAdvance()); |
| 4724 } | 4744 } |
| 4725 Expression expression = parseExpression2(); | 4745 Expression expression = parseExpression2(); |
| 4726 Token semicolon = _expect(TokenType.SEMICOLON); | 4746 Token semicolon = _expect(TokenType.SEMICOLON); |
| 4727 return astFactory.returnStatement(returnKeyword, expression, semicolon); | 4747 return astFactory.returnStatement(returnKeyword, expression, semicolon); |
| 4728 } | 4748 } |
| 4729 | 4749 |
| 4730 /** | 4750 /** |
| 4751 * Parse a return type. Return the return type that was parsed. |
| 4752 * |
| 4753 * returnType ::= |
| 4754 * 'void' |
| 4755 * | type |
| 4756 */ |
| 4757 TypeAnnotation parseReturnType(bool inExpression) { |
| 4758 if (_currentToken.keyword == Keyword.VOID) { |
| 4759 if (_atGenericFunctionTypeAfterReturnType(_peek())) { |
| 4760 return parseTypeAnnotation(false); |
| 4761 } else { |
| 4762 return astFactory.typeName( |
| 4763 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 4764 } |
| 4765 } else { |
| 4766 return parseTypeAnnotation(inExpression); |
| 4767 } |
| 4768 } |
| 4769 |
| 4770 /** |
| 4731 * Parse a setter. The [commentAndMetadata] is the documentation comment and | 4771 * Parse a setter. The [commentAndMetadata] is the documentation comment and |
| 4732 * metadata to be associated with the declaration. The [externalKeyword] is | 4772 * metadata to be associated with the declaration. The [externalKeyword] is |
| 4733 * the 'external' token. The [staticKeyword] is the static keyword, or `null` | 4773 * the 'external' token. The [staticKeyword] is the static keyword, or `null` |
| 4734 * if the setter is not static. The [returnType] is the return type that has | 4774 * if the setter is not static. The [returnType] is the return type that has |
| 4735 * already been parsed, or `null` if there was no return type. Return the | 4775 * already been parsed, or `null` if there was no return type. Return the |
| 4736 * setter that was parsed. | 4776 * setter that was parsed. |
| 4737 * | 4777 * |
| 4738 * This method assumes that the current token matches `Keyword.SET`. | 4778 * This method assumes that the current token matches `Keyword.SET`. |
| 4739 * | 4779 * |
| 4740 * setter ::= | 4780 * setter ::= |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5083 Statement parseTryStatement() { | 5123 Statement parseTryStatement() { |
| 5084 Token tryKeyword = getAndAdvance(); | 5124 Token tryKeyword = getAndAdvance(); |
| 5085 Block body = _parseBlockChecked(); | 5125 Block body = _parseBlockChecked(); |
| 5086 List<CatchClause> catchClauses = <CatchClause>[]; | 5126 List<CatchClause> catchClauses = <CatchClause>[]; |
| 5087 Block finallyClause = null; | 5127 Block finallyClause = null; |
| 5088 while (_matchesKeyword(Keyword.ON) || _matchesKeyword(Keyword.CATCH)) { | 5128 while (_matchesKeyword(Keyword.ON) || _matchesKeyword(Keyword.CATCH)) { |
| 5089 Token onKeyword = null; | 5129 Token onKeyword = null; |
| 5090 TypeName exceptionType = null; | 5130 TypeName exceptionType = null; |
| 5091 if (_matchesKeyword(Keyword.ON)) { | 5131 if (_matchesKeyword(Keyword.ON)) { |
| 5092 onKeyword = getAndAdvance(); | 5132 onKeyword = getAndAdvance(); |
| 5093 exceptionType = parseTypeNotVoid(false); | 5133 exceptionType = parseTypeAnnotation(false); |
| 5094 } | 5134 } |
| 5095 Token catchKeyword = null; | 5135 Token catchKeyword = null; |
| 5096 Token leftParenthesis = null; | 5136 Token leftParenthesis = null; |
| 5097 SimpleIdentifier exceptionParameter = null; | 5137 SimpleIdentifier exceptionParameter = null; |
| 5098 Token comma = null; | 5138 Token comma = null; |
| 5099 SimpleIdentifier stackTraceParameter = null; | 5139 SimpleIdentifier stackTraceParameter = null; |
| 5100 Token rightParenthesis = null; | 5140 Token rightParenthesis = null; |
| 5101 if (_matchesKeyword(Keyword.CATCH)) { | 5141 if (_matchesKeyword(Keyword.CATCH)) { |
| 5102 catchKeyword = getAndAdvance(); | 5142 catchKeyword = getAndAdvance(); |
| 5103 leftParenthesis = _expect(TokenType.OPEN_PAREN); | 5143 leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5174 * Parse a type. | 5214 * Parse a type. |
| 5175 * | 5215 * |
| 5176 * type ::= | 5216 * type ::= |
| 5177 * typeWithoutFunction | 5217 * typeWithoutFunction |
| 5178 * | functionType | 5218 * | functionType |
| 5179 */ | 5219 */ |
| 5180 TypeAnnotation parseTypeAnnotation(bool inExpression) { | 5220 TypeAnnotation parseTypeAnnotation(bool inExpression) { |
| 5181 TypeAnnotation type = null; | 5221 TypeAnnotation type = null; |
| 5182 if (_atGenericFunctionTypeAfterReturnType(_currentToken)) { | 5222 if (_atGenericFunctionTypeAfterReturnType(_currentToken)) { |
| 5183 // Generic function type with no return type. | 5223 // Generic function type with no return type. |
| 5184 type = parseGenericFunctionTypeAfterReturnType(null); | |
| 5185 } else { | |
| 5186 type = parseTypeWithoutFunction(inExpression); | |
| 5187 } | |
| 5188 while (_atGenericFunctionTypeAfterReturnType(_currentToken)) { | |
| 5189 type = parseGenericFunctionTypeAfterReturnType(type); | |
| 5190 } | |
| 5191 return type; | |
| 5192 } | |
| 5193 | |
| 5194 /** | |
| 5195 * Parse a type which is not `void`. | |
| 5196 * | |
| 5197 * typeNotVoid ::= | |
| 5198 * functionType | |
| 5199 * | typeNotVoidWithoutFunction | |
| 5200 */ | |
| 5201 TypeAnnotation parseTypeNotVoid(bool inExpression) { | |
| 5202 TypeAnnotation type = null; | |
| 5203 if (_atGenericFunctionTypeAfterReturnType(_currentToken)) { | |
| 5204 // Generic function type with no return type. | |
| 5205 type = parseGenericFunctionTypeAfterReturnType(null); | 5224 type = parseGenericFunctionTypeAfterReturnType(null); |
| 5206 } else if (_currentToken.keyword == Keyword.VOID && | 5225 } else if (_currentToken.keyword == Keyword.VOID && |
| 5207 _atGenericFunctionTypeAfterReturnType(_currentToken.next)) { | 5226 _atGenericFunctionTypeAfterReturnType(_currentToken.next)) { |
| 5208 type = astFactory.typeName( | 5227 type = astFactory.typeName( |
| 5209 astFactory.simpleIdentifier(getAndAdvance()), null); | 5228 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 5210 } else { | 5229 } else { |
| 5211 type = parseTypeName(inExpression); | 5230 type = parseTypeName(inExpression); |
| 5212 } | 5231 } |
| 5213 while (_atGenericFunctionTypeAfterReturnType(_currentToken)) { | 5232 while (_atGenericFunctionTypeAfterReturnType(_currentToken)) { |
| 5214 type = parseGenericFunctionTypeAfterReturnType(type); | 5233 type = parseGenericFunctionTypeAfterReturnType(type); |
| 5215 } | 5234 } |
| 5216 return type; | 5235 return type; |
| 5217 } | 5236 } |
| 5218 | 5237 |
| 5219 /** | 5238 /** |
| 5220 * Parse a type which is not a function type. | |
| 5221 * | |
| 5222 * typeWithoutFunction ::= | |
| 5223 * `void` | |
| 5224 * | typeNotVoidWithoutFunction | |
| 5225 */ | |
| 5226 TypeAnnotation parseTypeWithoutFunction(bool inExpression) { | |
| 5227 if (_currentToken.keyword == Keyword.VOID) { | |
| 5228 return astFactory.typeName( | |
| 5229 astFactory.simpleIdentifier(getAndAdvance()), null); | |
| 5230 } else { | |
| 5231 return parseTypeName(inExpression); | |
| 5232 } | |
| 5233 } | |
| 5234 | |
| 5235 /** | |
| 5236 * Parse a list of type arguments. Return the type argument list that was | 5239 * Parse a list of type arguments. Return the type argument list that was |
| 5237 * parsed. | 5240 * parsed. |
| 5238 * | 5241 * |
| 5239 * This method assumes that the current token matches `TokenType.LT`. | 5242 * This method assumes that the current token matches `TokenType.LT`. |
| 5240 * | 5243 * |
| 5241 * typeArguments ::= | 5244 * typeArguments ::= |
| 5242 * '<' typeList '>' | 5245 * '<' typeList '>' |
| 5243 * | 5246 * |
| 5244 * typeList ::= | 5247 * typeList ::= |
| 5245 * type (',' type)* | 5248 * type (',' type)* |
| 5246 */ | 5249 */ |
| 5247 TypeArgumentList parseTypeArgumentList() { | 5250 TypeArgumentList parseTypeArgumentList() { |
| 5248 Token leftBracket = getAndAdvance(); | 5251 Token leftBracket = getAndAdvance(); |
| 5249 List<TypeAnnotation> arguments = <TypeAnnotation>[ | 5252 List<TypeAnnotation> arguments = <TypeAnnotation>[ |
| 5250 parseTypeAnnotation(false) | 5253 parseTypeAnnotation(false) |
| 5251 ]; | 5254 ]; |
| 5252 while (_optional(TokenType.COMMA)) { | 5255 while (_optional(TokenType.COMMA)) { |
| 5253 arguments.add(parseTypeAnnotation(false)); | 5256 arguments.add(parseTypeAnnotation(false)); |
| 5254 } | 5257 } |
| 5255 Token rightBracket = _expectGt(); | 5258 Token rightBracket = _expectGt(); |
| 5256 return astFactory.typeArgumentList(leftBracket, arguments, rightBracket); | 5259 return astFactory.typeArgumentList(leftBracket, arguments, rightBracket); |
| 5257 } | 5260 } |
| 5258 | 5261 |
| 5259 /** | 5262 /** |
| 5260 * Parse a type which is not void and is not a function type. Return the type | 5263 * Parse a type name. Return the type name that was parsed. |
| 5261 * that was parsed. | |
| 5262 * | 5264 * |
| 5263 * typeNotVoidWithoutFunction ::= | 5265 * type ::= |
| 5264 * qualified typeArguments? | 5266 * qualified typeArguments? |
| 5265 */ | 5267 */ |
| 5266 // TODO(eernst): Rename this to `parseTypeNotVoidWithoutFunction`? | |
| 5267 // Apparently, it was named `parseTypeName` before type arguments existed. | |
| 5268 TypeName parseTypeName(bool inExpression) { | 5268 TypeName parseTypeName(bool inExpression) { |
| 5269 TypeName realType = _parseTypeName(inExpression); | 5269 TypeName realType = _parseTypeName(inExpression); |
| 5270 // If this is followed by a generic method type comment, allow the comment | 5270 // If this is followed by a generic method type comment, allow the comment |
| 5271 // type to replace the real type name. | 5271 // type to replace the real type name. |
| 5272 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to | 5272 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to |
| 5273 // only work inside generic methods? | 5273 // only work inside generic methods? |
| 5274 TypeName typeFromComment = _parseOptionalTypeNameComment(); | 5274 TypeName typeFromComment = _parseOptionalTypeNameComment(); |
| 5275 return typeFromComment ?? realType; | 5275 return typeFromComment ?? realType; |
| 5276 } | 5276 } |
| 5277 | 5277 |
| 5278 /** | 5278 /** |
| 5279 * Parse a type parameter. Return the type parameter that was parsed. | 5279 * Parse a type parameter. Return the type parameter that was parsed. |
| 5280 * | 5280 * |
| 5281 * typeParameter ::= | 5281 * typeParameter ::= |
| 5282 * metadata name ('extends' bound)? | 5282 * metadata name ('extends' bound)? |
| 5283 */ | 5283 */ |
| 5284 TypeParameter parseTypeParameter() { | 5284 TypeParameter parseTypeParameter() { |
| 5285 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 5285 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 5286 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 5286 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 5287 if (_matches(TokenType.QUESTION)) { | 5287 if (_matches(TokenType.QUESTION)) { |
| 5288 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); | 5288 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); |
| 5289 _advance(); | 5289 _advance(); |
| 5290 } | 5290 } |
| 5291 if (_matchesKeyword(Keyword.EXTENDS)) { | 5291 if (_matchesKeyword(Keyword.EXTENDS)) { |
| 5292 Token keyword = getAndAdvance(); | 5292 Token keyword = getAndAdvance(); |
| 5293 TypeAnnotation bound = parseTypeNotVoid(false); | 5293 TypeAnnotation bound = parseTypeAnnotation(false); |
| 5294 return astFactory.typeParameter(commentAndMetadata.comment, | 5294 return astFactory.typeParameter(commentAndMetadata.comment, |
| 5295 commentAndMetadata.metadata, name, keyword, bound); | 5295 commentAndMetadata.metadata, name, keyword, bound); |
| 5296 } | 5296 } |
| 5297 return astFactory.typeParameter(commentAndMetadata.comment, | 5297 return astFactory.typeParameter(commentAndMetadata.comment, |
| 5298 commentAndMetadata.metadata, name, null, null); | 5298 commentAndMetadata.metadata, name, null, null); |
| 5299 } | 5299 } |
| 5300 | 5300 |
| 5301 /** | 5301 /** |
| 5302 * Parse a list of type parameters. Return the list of type parameters that | 5302 * Parse a list of type parameters. Return the list of type parameters that |
| 5303 * were parsed. | 5303 * were parsed. |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5614 _tokenMatches(token, TokenType.COMMA)) { | 5614 _tokenMatches(token, TokenType.COMMA)) { |
| 5615 // If the `id.` is followed by something that cannot produce a valid | 5615 // If the `id.` is followed by something that cannot produce a valid |
| 5616 // structure then assume this is a prefixed identifier but missing the | 5616 // structure then assume this is a prefixed identifier but missing the |
| 5617 // trailing identifier | 5617 // trailing identifier |
| 5618 return token; | 5618 return token; |
| 5619 } | 5619 } |
| 5620 return null; | 5620 return null; |
| 5621 } | 5621 } |
| 5622 | 5622 |
| 5623 /** | 5623 /** |
| 5624 * Parse a return type, starting at the [startToken], without actually |
| 5625 * creating a return type or changing the current token. Return the token |
| 5626 * following the return type that was parsed, or `null` if the given token is |
| 5627 * not the first token in a valid return type. |
| 5628 * |
| 5629 * This method must be kept in sync with [parseReturnType]. |
| 5630 * |
| 5631 * returnType ::= |
| 5632 * 'void' |
| 5633 * | type |
| 5634 */ |
| 5635 Token skipReturnType(Token startToken) { |
| 5636 if (_tokenMatchesKeyword(startToken, Keyword.VOID)) { |
| 5637 if (_atGenericFunctionTypeAfterReturnType(_peek())) { |
| 5638 return skipTypeAnnotation(startToken); |
| 5639 } |
| 5640 return startToken.next; |
| 5641 } else { |
| 5642 return skipTypeAnnotation(startToken); |
| 5643 } |
| 5644 } |
| 5645 |
| 5646 /** |
| 5624 * Parse a simple identifier, starting at the [startToken], without actually | 5647 * Parse a simple identifier, starting at the [startToken], without actually |
| 5625 * creating a simple identifier or changing the current token. Return the | 5648 * creating a simple identifier or changing the current token. Return the |
| 5626 * token following the simple identifier that was parsed, or `null` if the | 5649 * token following the simple identifier that was parsed, or `null` if the |
| 5627 * given token is not the first token in a valid simple identifier. | 5650 * given token is not the first token in a valid simple identifier. |
| 5628 * | 5651 * |
| 5629 * This method must be kept in sync with [parseSimpleIdentifier]. | 5652 * This method must be kept in sync with [parseSimpleIdentifier]. |
| 5630 * | 5653 * |
| 5631 * identifier ::= | 5654 * identifier ::= |
| 5632 * IDENTIFIER | 5655 * IDENTIFIER |
| 5633 */ | 5656 */ |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5671 * Parse a type annotation, starting at the [startToken], without actually | 5694 * Parse a type annotation, starting at the [startToken], without actually |
| 5672 * creating a type annotation or changing the current token. Return the token | 5695 * creating a type annotation or changing the current token. Return the token |
| 5673 * following the type annotation that was parsed, or `null` if the given token | 5696 * following the type annotation that was parsed, or `null` if the given token |
| 5674 * is not the first token in a valid type annotation. | 5697 * is not the first token in a valid type annotation. |
| 5675 * | 5698 * |
| 5676 * This method must be kept in sync with [parseTypeAnnotation]. | 5699 * This method must be kept in sync with [parseTypeAnnotation]. |
| 5677 */ | 5700 */ |
| 5678 Token skipTypeAnnotation(Token startToken) { | 5701 Token skipTypeAnnotation(Token startToken) { |
| 5679 Token next = null; | 5702 Token next = null; |
| 5680 if (_atGenericFunctionTypeAfterReturnType(startToken)) { | 5703 if (_atGenericFunctionTypeAfterReturnType(startToken)) { |
| 5681 // Generic function type with no return type. | |
| 5682 next = skipGenericFunctionTypeAfterReturnType(startToken); | 5704 next = skipGenericFunctionTypeAfterReturnType(startToken); |
| 5705 } else if (startToken.keyword == Keyword.VOID && |
| 5706 _atGenericFunctionTypeAfterReturnType(startToken.next)) { |
| 5707 next = startToken.next; |
| 5683 } else { | 5708 } else { |
| 5684 next = skipTypeWithoutFunction(startToken); | 5709 next = skipTypeName(startToken); |
| 5685 } | 5710 } |
| 5686 while (next != null && _atGenericFunctionTypeAfterReturnType(next)) { | 5711 while (next != null && _atGenericFunctionTypeAfterReturnType(next)) { |
| 5687 next = skipGenericFunctionTypeAfterReturnType(next); | 5712 next = skipGenericFunctionTypeAfterReturnType(next); |
| 5688 } | 5713 } |
| 5689 return next; | 5714 return next; |
| 5690 } | 5715 } |
| 5691 | 5716 |
| 5692 /** | 5717 /** |
| 5693 * Parse a typeWithoutFunction, starting at the [startToken], without actually | |
| 5694 * creating a TypeAnnotation or changing the current token. Return the token | |
| 5695 * following the typeWithoutFunction that was parsed, or `null` if the given | |
| 5696 * token is not the first token in a valid typeWithoutFunction. | |
| 5697 * | |
| 5698 * This method must be kept in sync with [parseTypeWithoutFunction]. | |
| 5699 */ | |
| 5700 Token skipTypeWithoutFunction(Token startToken) { | |
| 5701 if (startToken.keyword == Keyword.VOID) { | |
| 5702 return startToken.next; | |
| 5703 } else { | |
| 5704 return skipTypeName(startToken); | |
| 5705 } | |
| 5706 } | |
| 5707 | |
| 5708 /** | |
| 5709 * Parse a list of type arguments, starting at the [startToken], without | 5718 * Parse a list of type arguments, starting at the [startToken], without |
| 5710 * actually creating a type argument list or changing the current token. | 5719 * actually creating a type argument list or changing the current token. |
| 5711 * Return the token following the type argument list that was parsed, or | 5720 * Return the token following the type argument list that was parsed, or |
| 5712 * `null` if the given token is not the first token in a valid type argument | 5721 * `null` if the given token is not the first token in a valid type argument |
| 5713 * list. | 5722 * list. |
| 5714 * | 5723 * |
| 5715 * This method must be kept in sync with [parseTypeArgumentList]. | 5724 * This method must be kept in sync with [parseTypeArgumentList]. |
| 5716 * | 5725 * |
| 5717 * typeArguments ::= | 5726 * typeArguments ::= |
| 5718 * '<' typeList '>' | 5727 * '<' typeList '>' |
| 5719 * | 5728 * |
| 5720 * typeList ::= | 5729 * typeList ::= |
| 5721 * type (',' type)* | 5730 * type (',' type)* |
| 5722 */ | 5731 */ |
| 5723 Token skipTypeArgumentList(Token startToken) { | 5732 Token skipTypeArgumentList(Token startToken) { |
| 5724 Token token = startToken; | 5733 Token token = startToken; |
| 5725 if (!_tokenMatches(token, TokenType.LT) && | 5734 if (!_tokenMatches(token, TokenType.LT) && |
| 5726 !_injectGenericCommentTypeList()) { | 5735 !_injectGenericCommentTypeList()) { |
| 5727 return null; | 5736 return null; |
| 5728 } | 5737 } |
| 5729 token = skipTypeAnnotation(token.next); | 5738 token = skipTypeName(token.next); |
| 5730 if (token == null) { | 5739 if (token == null) { |
| 5731 // If the start token '<' is followed by '>' | 5740 // If the start token '<' is followed by '>' |
| 5732 // then assume this should be type argument list but is missing a type | 5741 // then assume this should be type argument list but is missing a type |
| 5733 token = startToken.next; | 5742 token = startToken.next; |
| 5734 if (_tokenMatches(token, TokenType.GT)) { | 5743 if (_tokenMatches(token, TokenType.GT)) { |
| 5735 return token.next; | 5744 return token.next; |
| 5736 } | 5745 } |
| 5737 return null; | 5746 return null; |
| 5738 } | 5747 } |
| 5739 while (_tokenMatches(token, TokenType.COMMA)) { | 5748 while (_tokenMatches(token, TokenType.COMMA)) { |
| 5740 token = skipTypeAnnotation(token.next); | 5749 token = skipTypeName(token.next); |
| 5741 if (token == null) { | 5750 if (token == null) { |
| 5742 return null; | 5751 return null; |
| 5743 } | 5752 } |
| 5744 } | 5753 } |
| 5745 if (token.type == TokenType.GT) { | 5754 if (token.type == TokenType.GT) { |
| 5746 return token.next; | 5755 return token.next; |
| 5747 } else if (token.type == TokenType.GT_GT) { | 5756 } else if (token.type == TokenType.GT_GT) { |
| 5748 Token second = new Token(TokenType.GT, token.offset + 1); | 5757 Token second = new Token(TokenType.GT, token.offset + 1); |
| 5749 second.setNextWithoutSettingPrevious(token.next); | 5758 second.setNextWithoutSettingPrevious(token.next); |
| 5750 return second; | 5759 return second; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5917 ((keyword == Keyword.GET || keyword == Keyword.SET) && | 5926 ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 5918 _tokenMatchesIdentifier(next)) || | 5927 _tokenMatchesIdentifier(next)) || |
| 5919 (keyword == Keyword.OPERATOR && _isOperator(next))) { | 5928 (keyword == Keyword.OPERATOR && _isOperator(next))) { |
| 5920 // This looks like the start of a function | 5929 // This looks like the start of a function |
| 5921 return true; | 5930 return true; |
| 5922 } else if (_matchesIdentifier()) { | 5931 } else if (_matchesIdentifier()) { |
| 5923 if (nextType == TokenType.OPEN_PAREN) { | 5932 if (nextType == TokenType.OPEN_PAREN) { |
| 5924 // This looks like the start of a function | 5933 // This looks like the start of a function |
| 5925 return true; | 5934 return true; |
| 5926 } | 5935 } |
| 5927 Token token = skipTypeAnnotation(_currentToken); | 5936 Token token = skipReturnType(_currentToken); |
| 5928 if (token == null) { | 5937 if (token == null) { |
| 5929 return false; | 5938 return false; |
| 5930 } | 5939 } |
| 5931 // TODO(brianwilkerson) This looks wrong; should we be checking 'token'? | 5940 // TODO(brianwilkerson) This looks wrong; should we be checking 'token'? |
| 5932 if (keyword == Keyword.GET || | 5941 if (keyword == Keyword.GET || |
| 5933 keyword == Keyword.SET || | 5942 keyword == Keyword.SET || |
| 5934 (keyword == Keyword.OPERATOR && _isOperator(next)) || | 5943 (keyword == Keyword.OPERATOR && _isOperator(next)) || |
| 5935 _matchesIdentifier()) { | 5944 _matchesIdentifier()) { |
| 5936 return true; | 5945 return true; |
| 5937 } | 5946 } |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6305 bool _isPeekGenericTypeParametersAndOpenParen() { | 6314 bool _isPeekGenericTypeParametersAndOpenParen() { |
| 6306 Token token = _skipTypeParameterList(_peek()); | 6315 Token token = _skipTypeParameterList(_peek()); |
| 6307 return token != null && _tokenMatches(token, TokenType.OPEN_PAREN); | 6316 return token != null && _tokenMatches(token, TokenType.OPEN_PAREN); |
| 6308 } | 6317 } |
| 6309 | 6318 |
| 6310 /** | 6319 /** |
| 6311 * Return `true` if the [startToken] appears to be the first token of a type | 6320 * Return `true` if the [startToken] appears to be the first token of a type |
| 6312 * name that is followed by a variable or field formal parameter. | 6321 * name that is followed by a variable or field formal parameter. |
| 6313 */ | 6322 */ |
| 6314 bool _isTypedIdentifier(Token startToken) { | 6323 bool _isTypedIdentifier(Token startToken) { |
| 6315 Token token = skipTypeAnnotation(startToken); | 6324 Token token = skipReturnType(startToken); |
| 6316 if (token == null) { | 6325 if (token == null) { |
| 6317 return false; | 6326 return false; |
| 6318 } else if (_tokenMatchesIdentifier(token)) { | 6327 } else if (_tokenMatchesIdentifier(token)) { |
| 6319 return true; | 6328 return true; |
| 6320 } else if (_tokenMatchesKeyword(token, Keyword.THIS) && | 6329 } else if (_tokenMatchesKeyword(token, Keyword.THIS) && |
| 6321 _tokenMatches(token.next, TokenType.PERIOD) && | 6330 _tokenMatches(token.next, TokenType.PERIOD) && |
| 6322 _tokenMatchesIdentifier(token.next.next)) { | 6331 _tokenMatchesIdentifier(token.next.next)) { |
| 6323 return true; | 6332 return true; |
| 6333 } else if (_tokenMatchesKeyword(startToken, Keyword.VOID)) { |
| 6334 // The keyword 'void' isn't a valid identifier, so it should be assumed to |
| 6335 // be a type name. |
| 6336 return true; |
| 6324 } else if (startToken.next != token && | 6337 } else if (startToken.next != token && |
| 6325 !_tokenMatches(token, TokenType.OPEN_PAREN)) { | 6338 !_tokenMatches(token, TokenType.OPEN_PAREN)) { |
| 6326 // The type is more than a simple identifier, so it should be assumed to | 6339 // The type is more than a simple identifier, so it should be assumed to |
| 6327 // be a type name. | 6340 // be a type name. |
| 6328 return true; | 6341 return true; |
| 6329 } | 6342 } |
| 6330 return false; | 6343 return false; |
| 6331 } | 6344 } |
| 6332 | 6345 |
| 6333 /** | 6346 /** |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7003 * functionTypeAlias ::= | 7016 * functionTypeAlias ::= |
| 7004 * functionPrefix typeParameterList? formalParameterList ';' | 7017 * functionPrefix typeParameterList? formalParameterList ';' |
| 7005 * | 7018 * |
| 7006 * functionPrefix ::= | 7019 * functionPrefix ::= |
| 7007 * returnType? name | 7020 * returnType? name |
| 7008 */ | 7021 */ |
| 7009 FunctionTypeAlias _parseFunctionTypeAlias( | 7022 FunctionTypeAlias _parseFunctionTypeAlias( |
| 7010 CommentAndMetadata commentAndMetadata, Token keyword) { | 7023 CommentAndMetadata commentAndMetadata, Token keyword) { |
| 7011 TypeAnnotation returnType = null; | 7024 TypeAnnotation returnType = null; |
| 7012 if (hasReturnTypeInTypeAlias) { | 7025 if (hasReturnTypeInTypeAlias) { |
| 7013 returnType = parseTypeAnnotation(false); | 7026 returnType = parseReturnType(false); |
| 7014 } | 7027 } |
| 7015 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 7028 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 7016 TypeParameterList typeParameters = null; | 7029 TypeParameterList typeParameters = null; |
| 7017 if (_matches(TokenType.LT)) { | 7030 if (_matches(TokenType.LT)) { |
| 7018 typeParameters = parseTypeParameterList(); | 7031 typeParameters = parseTypeParameterList(); |
| 7019 } | 7032 } |
| 7020 TokenType type = _currentToken.type; | 7033 TokenType type = _currentToken.type; |
| 7021 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { | 7034 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { |
| 7022 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); | 7035 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); |
| 7023 FormalParameterList parameters = astFactory.formalParameterList( | 7036 FormalParameterList parameters = astFactory.formalParameterList( |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7318 (_tokenMatchesIdentifier(next) || | 7331 (_tokenMatchesIdentifier(next) || |
| 7319 _tokenMatches(next, TokenType.LT))) { | 7332 _tokenMatches(next, TokenType.LT))) { |
| 7320 Token afterTypeParameters = _skipTypeParameterList(next); | 7333 Token afterTypeParameters = _skipTypeParameterList(next); |
| 7321 if (afterTypeParameters != null && | 7334 if (afterTypeParameters != null && |
| 7322 _tokenMatches(afterTypeParameters, TokenType.OPEN_PAREN)) { | 7335 _tokenMatches(afterTypeParameters, TokenType.OPEN_PAREN)) { |
| 7323 // If the identifier is followed by type parameters and a parenthesis, | 7336 // If the identifier is followed by type parameters and a parenthesis, |
| 7324 // then the identifier is the name of a generic method, not a return | 7337 // then the identifier is the name of a generic method, not a return |
| 7325 // type. | 7338 // type. |
| 7326 return null; | 7339 return null; |
| 7327 } | 7340 } |
| 7328 return parseTypeAnnotation(false); | 7341 return parseReturnType(false); |
| 7329 } | 7342 } |
| 7330 Token next2 = next.next; | 7343 Token next2 = next.next; |
| 7331 Token next3 = next2.next; | 7344 Token next3 = next2.next; |
| 7332 if (_tokenMatches(next, TokenType.PERIOD) && | 7345 if (_tokenMatches(next, TokenType.PERIOD) && |
| 7333 _tokenMatchesIdentifier(next2) && | 7346 _tokenMatchesIdentifier(next2) && |
| 7334 (_tokenMatchesIdentifier(next3) || | 7347 (_tokenMatchesIdentifier(next3) || |
| 7335 _tokenMatches(next3, TokenType.LT))) { | 7348 _tokenMatches(next3, TokenType.LT))) { |
| 7336 return parseTypeAnnotation(false); | 7349 return parseReturnType(false); |
| 7337 } | 7350 } |
| 7338 } | 7351 } |
| 7339 return null; | 7352 return null; |
| 7340 } | 7353 } |
| 7341 | 7354 |
| 7342 /** | 7355 /** |
| 7343 * Parse a [TypeArgumentList] if present, otherwise return null. | 7356 * Parse a [TypeArgumentList] if present, otherwise return null. |
| 7344 * This also supports the comment form, if enabled: `/*<T>*/` | 7357 * This also supports the comment form, if enabled: `/*<T>*/` |
| 7345 */ | 7358 */ |
| 7346 TypeArgumentList _parseOptionalTypeArguments() { | 7359 TypeArgumentList _parseOptionalTypeArguments() { |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7871 } else if (_tokenMatchesIdentifier(startToken)) { | 7884 } else if (_tokenMatchesIdentifier(startToken)) { |
| 7872 Token next = startToken.next; | 7885 Token next = startToken.next; |
| 7873 if (_tokenMatchesIdentifier(next) || | 7886 if (_tokenMatchesIdentifier(next) || |
| 7874 _tokenMatches(next, TokenType.LT) || | 7887 _tokenMatches(next, TokenType.LT) || |
| 7875 _tokenMatchesKeyword(next, Keyword.THIS) || | 7888 _tokenMatchesKeyword(next, Keyword.THIS) || |
| 7876 (_tokenMatches(next, TokenType.PERIOD) && | 7889 (_tokenMatches(next, TokenType.PERIOD) && |
| 7877 _tokenMatchesIdentifier(next.next) && | 7890 _tokenMatchesIdentifier(next.next) && |
| 7878 (_tokenMatchesIdentifier(next.next.next) || | 7891 (_tokenMatchesIdentifier(next.next.next) || |
| 7879 _tokenMatches(next.next.next, TokenType.LT) || | 7892 _tokenMatches(next.next.next, TokenType.LT) || |
| 7880 _tokenMatchesKeyword(next.next.next, Keyword.THIS)))) { | 7893 _tokenMatchesKeyword(next.next.next, Keyword.THIS)))) { |
| 7881 return skipTypeAnnotation(startToken); | 7894 return skipReturnType(startToken); |
| 7882 } | 7895 } |
| 7883 } | 7896 } |
| 7884 return null; | 7897 return null; |
| 7885 } | 7898 } |
| 7886 | 7899 |
| 7887 /** | 7900 /** |
| 7888 * Parse a list of formal parameters, starting at the [startToken], without | 7901 * Parse a list of formal parameters, starting at the [startToken], without |
| 7889 * actually creating a formal parameter list or changing the current token. | 7902 * actually creating a formal parameter list or changing the current token. |
| 7890 * Return the token following the formal parameter list that was parsed, or | 7903 * Return the token following the formal parameter list that was parsed, or |
| 7891 * `null` if the given token is not the first token in a valid list of formal | 7904 * `null` if the given token is not the first token in a valid list of formal |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8648 } | 8661 } |
| 8649 } | 8662 } |
| 8650 } | 8663 } |
| 8651 | 8664 |
| 8652 /** | 8665 /** |
| 8653 * Instances of this class are thrown when the parser detects that AST has | 8666 * Instances of this class are thrown when the parser detects that AST has |
| 8654 * too many nested expressions to be parsed safely and avoid possibility of | 8667 * too many nested expressions to be parsed safely and avoid possibility of |
| 8655 * [StackOverflowError] in the parser or during later analysis. | 8668 * [StackOverflowError] in the parser or during later analysis. |
| 8656 */ | 8669 */ |
| 8657 class _TooDeepTreeError {} | 8670 class _TooDeepTreeError {} |
| OLD | NEW |