| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 /** | 55 /** |
| 56 * A simple data-holder for a method that needs to return multiple values. | 56 * A simple data-holder for a method that needs to return multiple values. |
| 57 */ | 57 */ |
| 58 class FinalConstVarOrType { | 58 class FinalConstVarOrType { |
| 59 /** | 59 /** |
| 60 * The 'final', 'const' or 'var' keyword, or `null` if none was given. | 60 * The 'final', 'const' or 'var' keyword, or `null` if none was given. |
| 61 */ | 61 */ |
| 62 final Token keyword; | 62 final Token keyword; |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * The type, of `null` if no type was specified. | 65 * The type, or `null` if no type was specified. |
| 66 */ | 66 */ |
| 67 final TypeName type; | 67 final TypeAnnotation type; |
| 68 | 68 |
| 69 /** | 69 /** |
| 70 * Initialize a newly created holder with the given [keyword] and [type]. | 70 * Initialize a newly created holder with the given [keyword] and [type]. |
| 71 */ | 71 */ |
| 72 FinalConstVarOrType(this.keyword, this.type); | 72 FinalConstVarOrType(this.keyword, this.type); |
| 73 } | 73 } |
| 74 | 74 |
| 75 /** | 75 /** |
| 76 * A simple data-holder for a method that needs to return multiple values. | 76 * A simple data-holder for a method that needs to return multiple values. |
| 77 */ | 77 */ |
| (...skipping 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1428 // function type alias that was parsed. | 1428 // function type alias that was parsed. |
| 1429 _parseFunctionTypeAlias(commentAndMetadata, getAndAdvance()); | 1429 _parseFunctionTypeAlias(commentAndMetadata, getAndAdvance()); |
| 1430 return null; | 1430 return null; |
| 1431 } else { | 1431 } else { |
| 1432 Token token = _skipTypeParameterList(_peek()); | 1432 Token token = _skipTypeParameterList(_peek()); |
| 1433 if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) { | 1433 if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) { |
| 1434 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, | 1434 return _parseMethodDeclarationAfterReturnType(commentAndMetadata, |
| 1435 modifiers.externalKeyword, modifiers.staticKeyword, null); | 1435 modifiers.externalKeyword, modifiers.staticKeyword, null); |
| 1436 } | 1436 } |
| 1437 } | 1437 } |
| 1438 TypeName type = _parseTypeNameAfterIdentifier(); | 1438 TypeAnnotation type = _parseTypeAnnotationAfterIdentifier(); |
| 1439 keyword = _currentToken.keyword; | 1439 keyword = _currentToken.keyword; |
| 1440 next = _peek(); | 1440 next = _peek(); |
| 1441 isFollowedByIdentifier = _tokenMatchesIdentifier(next); | 1441 isFollowedByIdentifier = _tokenMatchesIdentifier(next); |
| 1442 if (keyword == Keyword.GET && isFollowedByIdentifier) { | 1442 if (keyword == Keyword.GET && isFollowedByIdentifier) { |
| 1443 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1443 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1444 return parseGetter(commentAndMetadata, modifiers.externalKeyword, | 1444 return parseGetter(commentAndMetadata, modifiers.externalKeyword, |
| 1445 modifiers.staticKeyword, type); | 1445 modifiers.staticKeyword, type); |
| 1446 } else if (keyword == Keyword.SET && isFollowedByIdentifier) { | 1446 } else if (keyword == Keyword.SET && isFollowedByIdentifier) { |
| 1447 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1447 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1448 return parseSetter(commentAndMetadata, modifiers.externalKeyword, | 1448 return parseSetter(commentAndMetadata, modifiers.externalKeyword, |
| (...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2102 _reportErrorForCurrentToken( | 2102 _reportErrorForCurrentToken( |
| 2103 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); | 2103 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); |
| 2104 } | 2104 } |
| 2105 return astFactory.topLevelVariableDeclaration( | 2105 return astFactory.topLevelVariableDeclaration( |
| 2106 commentAndMetadata.comment, | 2106 commentAndMetadata.comment, |
| 2107 commentAndMetadata.metadata, | 2107 commentAndMetadata.metadata, |
| 2108 parseVariableDeclarationListAfterType( | 2108 parseVariableDeclarationListAfterType( |
| 2109 null, _validateModifiersForTopLevelVariable(modifiers), null), | 2109 null, _validateModifiersForTopLevelVariable(modifiers), null), |
| 2110 _expect(TokenType.SEMICOLON)); | 2110 _expect(TokenType.SEMICOLON)); |
| 2111 } | 2111 } |
| 2112 TypeName returnType = parseReturnType(); | 2112 TypeAnnotation returnType = parseReturnType(false); |
| 2113 keyword = _currentToken.keyword; | 2113 keyword = _currentToken.keyword; |
| 2114 next = _peek(); | 2114 next = _peek(); |
| 2115 if ((keyword == Keyword.GET || keyword == Keyword.SET) && | 2115 if ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 2116 _tokenMatchesIdentifier(next)) { | 2116 _tokenMatchesIdentifier(next)) { |
| 2117 _validateModifiersForTopLevelFunction(modifiers); | 2117 _validateModifiersForTopLevelFunction(modifiers); |
| 2118 return parseFunctionDeclaration( | 2118 return parseFunctionDeclaration( |
| 2119 commentAndMetadata, modifiers.externalKeyword, returnType); | 2119 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2120 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { | 2120 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { |
| 2121 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); | 2121 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); |
| 2122 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( | 2122 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2750 * | 2750 * |
| 2751 * finalConstVarOrType ::= | 2751 * finalConstVarOrType ::= |
| 2752 * 'final' type? | 2752 * 'final' type? |
| 2753 * | 'const' type? | 2753 * | 'const' type? |
| 2754 * | 'var' | 2754 * | 'var' |
| 2755 * | type | 2755 * | type |
| 2756 */ | 2756 */ |
| 2757 FinalConstVarOrType parseFinalConstVarOrType(bool optional, | 2757 FinalConstVarOrType parseFinalConstVarOrType(bool optional, |
| 2758 {bool inFunctionType: false}) { | 2758 {bool inFunctionType: false}) { |
| 2759 Token keywordToken = null; | 2759 Token keywordToken = null; |
| 2760 TypeName type = null; | 2760 TypeAnnotation type = null; |
| 2761 Keyword keyword = _currentToken.keyword; | 2761 Keyword keyword = _currentToken.keyword; |
| 2762 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { | 2762 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { |
| 2763 keywordToken = getAndAdvance(); | 2763 keywordToken = getAndAdvance(); |
| 2764 if (_isTypedIdentifier(_currentToken)) { | 2764 if (_isTypedIdentifier(_currentToken)) { |
| 2765 type = parseTypeName(false); | 2765 type = parseTypeAnnotation(false); |
| 2766 } else { | 2766 } else { |
| 2767 // Support `final/*=T*/ x;` | 2767 // Support `final/*=T*/ x;` |
| 2768 type = _parseOptionalTypeNameComment(); | 2768 type = _parseOptionalTypeNameComment(); |
| 2769 } | 2769 } |
| 2770 } else if (keyword == Keyword.VAR) { | 2770 } else if (keyword == Keyword.VAR) { |
| 2771 keywordToken = getAndAdvance(); | 2771 keywordToken = getAndAdvance(); |
| 2772 // Support `var/*=T*/ x;` | 2772 // Support `var/*=T*/ x;` |
| 2773 type = _parseOptionalTypeNameComment(); | 2773 type = _parseOptionalTypeNameComment(); |
| 2774 if (type != null) { | 2774 if (type != null) { |
| 2775 // Clear the keyword to prevent an error. | 2775 // Clear the keyword to prevent an error. |
| 2776 keywordToken = null; | 2776 keywordToken = null; |
| 2777 } | 2777 } |
| 2778 } else if (_isTypedIdentifier(_currentToken)) { | 2778 } else if (_isTypedIdentifier(_currentToken)) { |
| 2779 type = parseReturnType(); | 2779 type = parseReturnType(false); |
| 2780 } else if (inFunctionType && _matchesIdentifier()) { | 2780 } else if (inFunctionType && _matchesIdentifier()) { |
| 2781 type = parseTypeAnnotation(); | 2781 type = parseTypeAnnotation(false); |
| 2782 } else if (!optional) { | 2782 } else if (!optional) { |
| 2783 _reportErrorForCurrentToken( | 2783 _reportErrorForCurrentToken( |
| 2784 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); | 2784 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); |
| 2785 } else { | 2785 } else { |
| 2786 // Support parameters such as `(/*=K*/ key, /*=V*/ value)` | 2786 // Support parameters such as `(/*=K*/ key, /*=V*/ value)` |
| 2787 // This is not supported if the type is required. | 2787 // This is not supported if the type is required. |
| 2788 type = _parseOptionalTypeNameComment(); | 2788 type = _parseOptionalTypeNameComment(); |
| 2789 } | 2789 } |
| 2790 return new FinalConstVarOrType(keywordToken, type); | 2790 return new FinalConstVarOrType(keywordToken, type); |
| 2791 } | 2791 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2960 _reportErrorForCurrentToken( | 2960 _reportErrorForCurrentToken( |
| 2961 ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, | 2961 ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, |
| 2962 [variables.length.toString()]); | 2962 [variables.length.toString()]); |
| 2963 } | 2963 } |
| 2964 VariableDeclaration variable = variables[0]; | 2964 VariableDeclaration variable = variables[0]; |
| 2965 if (variable.initializer != null) { | 2965 if (variable.initializer != null) { |
| 2966 _reportErrorForCurrentToken( | 2966 _reportErrorForCurrentToken( |
| 2967 ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH); | 2967 ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH); |
| 2968 } | 2968 } |
| 2969 Token keyword = variableList.keyword; | 2969 Token keyword = variableList.keyword; |
| 2970 TypeName type = variableList.type; | 2970 TypeAnnotation type = variableList.type; |
| 2971 if (keyword != null || type != null) { | 2971 if (keyword != null || type != null) { |
| 2972 loopVariable = astFactory.declaredIdentifier( | 2972 loopVariable = astFactory.declaredIdentifier( |
| 2973 commentAndMetadata.comment, | 2973 commentAndMetadata.comment, |
| 2974 commentAndMetadata.metadata, | 2974 commentAndMetadata.metadata, |
| 2975 keyword, | 2975 keyword, |
| 2976 type, | 2976 type, |
| 2977 astFactory.simpleIdentifier(variable.name.token, | 2977 astFactory.simpleIdentifier(variable.name.token, |
| 2978 isDeclaration: true)); | 2978 isDeclaration: true)); |
| 2979 } else { | 2979 } else { |
| 2980 if (commentAndMetadata.hasMetadata) { | 2980 if (commentAndMetadata.hasMetadata) { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 * being parsed as a statement. Return the function declaration that was | 3172 * being parsed as a statement. Return the function declaration that was |
| 3173 * parsed. | 3173 * parsed. |
| 3174 * | 3174 * |
| 3175 * functionDeclaration ::= | 3175 * functionDeclaration ::= |
| 3176 * functionSignature functionBody | 3176 * functionSignature functionBody |
| 3177 * | returnType? getOrSet identifier formalParameterList functionBody | 3177 * | returnType? getOrSet identifier formalParameterList functionBody |
| 3178 */ | 3178 */ |
| 3179 FunctionDeclaration parseFunctionDeclaration( | 3179 FunctionDeclaration parseFunctionDeclaration( |
| 3180 CommentAndMetadata commentAndMetadata, | 3180 CommentAndMetadata commentAndMetadata, |
| 3181 Token externalKeyword, | 3181 Token externalKeyword, |
| 3182 TypeName returnType) { | 3182 TypeAnnotation returnType) { |
| 3183 Token keywordToken = null; | 3183 Token keywordToken = null; |
| 3184 bool isGetter = false; | 3184 bool isGetter = false; |
| 3185 Keyword keyword = _currentToken.keyword; | 3185 Keyword keyword = _currentToken.keyword; |
| 3186 SimpleIdentifier name = null; | 3186 SimpleIdentifier name = null; |
| 3187 if (keyword == Keyword.GET) { | 3187 if (keyword == Keyword.GET) { |
| 3188 keywordToken = getAndAdvance(); | 3188 keywordToken = getAndAdvance(); |
| 3189 isGetter = true; | 3189 isGetter = true; |
| 3190 } else if (keyword == Keyword.SET) { | 3190 } else if (keyword == Keyword.SET) { |
| 3191 keywordToken = getAndAdvance(); | 3191 keywordToken = getAndAdvance(); |
| 3192 } | 3192 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3321 * 'typedef' identifier typeParameterList? '=' functionType ';' | 3321 * 'typedef' identifier typeParameterList? '=' functionType ';' |
| 3322 */ | 3322 */ |
| 3323 GenericTypeAlias parseGenericTypeAlias( | 3323 GenericTypeAlias parseGenericTypeAlias( |
| 3324 CommentAndMetadata commentAndMetadata, Token keyword) { | 3324 CommentAndMetadata commentAndMetadata, Token keyword) { |
| 3325 Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true); | 3325 Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true); |
| 3326 TypeParameterList typeParameters = null; | 3326 TypeParameterList typeParameters = null; |
| 3327 if (_matches(TokenType.LT)) { | 3327 if (_matches(TokenType.LT)) { |
| 3328 typeParameters = parseTypeParameterList(); | 3328 typeParameters = parseTypeParameterList(); |
| 3329 } | 3329 } |
| 3330 Token equals = _expect(TokenType.EQ); | 3330 Token equals = _expect(TokenType.EQ); |
| 3331 TypeAnnotation functionType = parseTypeAnnotation(); | 3331 TypeAnnotation functionType = parseTypeAnnotation(false); |
| 3332 Token semicolon = _expect(TokenType.SEMICOLON); | 3332 Token semicolon = _expect(TokenType.SEMICOLON); |
| 3333 if (functionType is! GenericFunctionType) { | 3333 if (functionType is! GenericFunctionType) { |
| 3334 // TODO(brianwilkerson) Generate an error and recover (better than this). | 3334 // TODO(brianwilkerson) Generate an error and recover (better than this). |
| 3335 return astFactory.genericTypeAlias( | 3335 return astFactory.genericTypeAlias( |
| 3336 commentAndMetadata.comment, | 3336 commentAndMetadata.comment, |
| 3337 commentAndMetadata.metadata, | 3337 commentAndMetadata.metadata, |
| 3338 keyword, | 3338 keyword, |
| 3339 name, | 3339 name, |
| 3340 typeParameters, | 3340 typeParameters, |
| 3341 equals, | 3341 equals, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3363 * | 3363 * |
| 3364 * This method assumes that the current token matches `Keyword.GET`. | 3364 * This method assumes that the current token matches `Keyword.GET`. |
| 3365 * | 3365 * |
| 3366 * getter ::= | 3366 * getter ::= |
| 3367 * getterSignature functionBody? | 3367 * getterSignature functionBody? |
| 3368 * | 3368 * |
| 3369 * getterSignature ::= | 3369 * getterSignature ::= |
| 3370 * 'external'? 'static'? returnType? 'get' identifier | 3370 * 'external'? 'static'? returnType? 'get' identifier |
| 3371 */ | 3371 */ |
| 3372 MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata, | 3372 MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata, |
| 3373 Token externalKeyword, Token staticKeyword, TypeName returnType) { | 3373 Token externalKeyword, Token staticKeyword, TypeAnnotation returnType) { |
| 3374 Token propertyKeyword = getAndAdvance(); | 3374 Token propertyKeyword = getAndAdvance(); |
| 3375 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 3375 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 3376 if (_matches(TokenType.OPEN_PAREN) && | 3376 if (_matches(TokenType.OPEN_PAREN) && |
| 3377 _tokenMatches(_peek(), TokenType.CLOSE_PAREN)) { | 3377 _tokenMatches(_peek(), TokenType.CLOSE_PAREN)) { |
| 3378 _reportErrorForCurrentToken(ParserErrorCode.GETTER_WITH_PARAMETERS); | 3378 _reportErrorForCurrentToken(ParserErrorCode.GETTER_WITH_PARAMETERS); |
| 3379 _advance(); | 3379 _advance(); |
| 3380 _advance(); | 3380 _advance(); |
| 3381 } | 3381 } |
| 3382 FunctionBody body = parseFunctionBody( | 3382 FunctionBody body = parseFunctionBody( |
| 3383 externalKeyword != null || staticKeyword == null, | 3383 externalKeyword != null || staticKeyword == null, |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3547 * initializedIdentifierList ::= | 3547 * initializedIdentifierList ::= |
| 3548 * initializedIdentifier (',' initializedIdentifier)* | 3548 * initializedIdentifier (',' initializedIdentifier)* |
| 3549 * | 3549 * |
| 3550 * initializedIdentifier ::= | 3550 * initializedIdentifier ::= |
| 3551 * identifier ('=' expression)? | 3551 * identifier ('=' expression)? |
| 3552 */ | 3552 */ |
| 3553 FieldDeclaration parseInitializedIdentifierList( | 3553 FieldDeclaration parseInitializedIdentifierList( |
| 3554 CommentAndMetadata commentAndMetadata, | 3554 CommentAndMetadata commentAndMetadata, |
| 3555 Token staticKeyword, | 3555 Token staticKeyword, |
| 3556 Token keyword, | 3556 Token keyword, |
| 3557 TypeName type) { | 3557 TypeAnnotation type) { |
| 3558 VariableDeclarationList fieldList = | 3558 VariableDeclarationList fieldList = |
| 3559 parseVariableDeclarationListAfterType(null, keyword, type); | 3559 parseVariableDeclarationListAfterType(null, keyword, type); |
| 3560 return astFactory.fieldDeclaration( | 3560 return astFactory.fieldDeclaration( |
| 3561 commentAndMetadata.comment, | 3561 commentAndMetadata.comment, |
| 3562 commentAndMetadata.metadata, | 3562 commentAndMetadata.metadata, |
| 3563 staticKeyword, | 3563 staticKeyword, |
| 3564 fieldList, | 3564 fieldList, |
| 3565 _expect(TokenType.SEMICOLON)); | 3565 _expect(TokenType.SEMICOLON)); |
| 3566 } | 3566 } |
| 3567 | 3567 |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4148 period, | 4148 period, |
| 4149 identifier, | 4149 identifier, |
| 4150 typeParameters, | 4150 typeParameters, |
| 4151 parameters); | 4151 parameters); |
| 4152 } | 4152 } |
| 4153 } else if (typeParameters != null) { | 4153 } else if (typeParameters != null) { |
| 4154 // TODO(brianwilkerson) Report an error. It looks like a function-typed | 4154 // TODO(brianwilkerson) Report an error. It looks like a function-typed |
| 4155 // parameter with no parameter list. | 4155 // parameter with no parameter list. |
| 4156 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.
endToken); | 4156 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.
endToken); |
| 4157 } | 4157 } |
| 4158 TypeName type = holder.type; | 4158 TypeAnnotation type = holder.type; |
| 4159 if (type != null) { | 4159 if (type != null) { |
| 4160 if (_tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) { | 4160 if (type is TypeName && |
| 4161 _tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) { |
| 4161 _reportErrorForToken( | 4162 _reportErrorForToken( |
| 4162 ParserErrorCode.VOID_PARAMETER, type.name.beginToken); | 4163 ParserErrorCode.VOID_PARAMETER, type.name.beginToken); |
| 4163 } else if (holder.keyword != null && | 4164 } else if (holder.keyword != null && |
| 4164 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { | 4165 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { |
| 4165 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); | 4166 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); |
| 4166 } | 4167 } |
| 4167 } | 4168 } |
| 4168 if (thisKeyword != null) { | 4169 if (thisKeyword != null) { |
| 4169 // TODO(brianwilkerson) If there are type parameters but no parameters, | 4170 // TODO(brianwilkerson) If there are type parameters but no parameters, |
| 4170 // should we create a synthetic empty parameter list here so we can | 4171 // should we create a synthetic empty parameter list here so we can |
| 4171 // capture the type parameters? | 4172 // capture the type parameters? |
| 4172 return astFactory.fieldFormalParameter( | 4173 return astFactory.fieldFormalParameter( |
| 4173 commentAndMetadata.comment, | 4174 commentAndMetadata.comment, |
| 4174 commentAndMetadata.metadata, | 4175 commentAndMetadata.metadata, |
| 4175 holder.keyword, | 4176 holder.keyword, |
| 4176 holder.type, | 4177 type, |
| 4177 thisKeyword, | 4178 thisKeyword, |
| 4178 period, | 4179 period, |
| 4179 identifier, | 4180 identifier, |
| 4180 null, | 4181 null, |
| 4181 null); | 4182 null); |
| 4182 } | 4183 } |
| 4183 return astFactory.simpleFormalParameter( | 4184 return astFactory.simpleFormalParameter( |
| 4184 commentAndMetadata.comment, | 4185 commentAndMetadata.comment, |
| 4185 commentAndMetadata.metadata, | 4186 commentAndMetadata.metadata, |
| 4186 holder.keyword, | 4187 holder.keyword, |
| 4187 holder.type, | 4188 type, |
| 4188 astFactory.simpleIdentifier(identifier.token, isDeclaration: true)); | 4189 astFactory.simpleIdentifier(identifier.token, isDeclaration: true)); |
| 4189 } | 4190 } |
| 4190 | 4191 |
| 4191 /** | 4192 /** |
| 4192 * Parse an operator declaration. The [commentAndMetadata] is the | 4193 * Parse an operator declaration. The [commentAndMetadata] is the |
| 4193 * documentation comment and metadata to be associated with the declaration. | 4194 * documentation comment and metadata to be associated with the declaration. |
| 4194 * The [externalKeyword] is the 'external' token. The [returnType] is the | 4195 * The [externalKeyword] is the 'external' token. The [returnType] is the |
| 4195 * return type that has already been parsed, or `null` if there was no return | 4196 * return type that has already been parsed, or `null` if there was no return |
| 4196 * type. Return the operator declaration that was parsed. | 4197 * type. Return the operator declaration that was parsed. |
| 4197 * | 4198 * |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4483 Expression expression = astFactory.superExpression(getAndAdvance()); | 4484 Expression expression = astFactory.superExpression(getAndAdvance()); |
| 4484 Token operator = getAndAdvance(); | 4485 Token operator = getAndAdvance(); |
| 4485 return astFactory.binaryExpression( | 4486 return astFactory.binaryExpression( |
| 4486 expression, operator, parseBitwiseOrExpression()); | 4487 expression, operator, parseBitwiseOrExpression()); |
| 4487 } | 4488 } |
| 4488 Expression expression = parseBitwiseOrExpression(); | 4489 Expression expression = parseBitwiseOrExpression(); |
| 4489 Keyword keyword = _currentToken.keyword; | 4490 Keyword keyword = _currentToken.keyword; |
| 4490 if (keyword == Keyword.AS) { | 4491 if (keyword == Keyword.AS) { |
| 4491 Token asOperator = getAndAdvance(); | 4492 Token asOperator = getAndAdvance(); |
| 4492 return astFactory.asExpression( | 4493 return astFactory.asExpression( |
| 4493 expression, asOperator, parseTypeName(true)); | 4494 expression, asOperator, parseTypeAnnotation(true)); |
| 4494 } else if (keyword == Keyword.IS) { | 4495 } else if (keyword == Keyword.IS) { |
| 4495 Token isOperator = getAndAdvance(); | 4496 Token isOperator = getAndAdvance(); |
| 4496 Token notOperator = null; | 4497 Token notOperator = null; |
| 4497 if (_matches(TokenType.BANG)) { | 4498 if (_matches(TokenType.BANG)) { |
| 4498 notOperator = getAndAdvance(); | 4499 notOperator = getAndAdvance(); |
| 4499 } | 4500 } |
| 4500 return astFactory.isExpression( | 4501 TypeAnnotation type = parseTypeAnnotation(true); |
| 4501 expression, isOperator, notOperator, parseTypeName(true)); | 4502 return astFactory.isExpression(expression, isOperator, notOperator, type); |
| 4502 } else if (_currentToken.type.isRelationalOperator) { | 4503 } else if (_currentToken.type.isRelationalOperator) { |
| 4503 Token operator = getAndAdvance(); | 4504 Token operator = getAndAdvance(); |
| 4504 return astFactory.binaryExpression( | 4505 return astFactory.binaryExpression( |
| 4505 expression, operator, parseBitwiseOrExpression()); | 4506 expression, operator, parseBitwiseOrExpression()); |
| 4506 } | 4507 } |
| 4507 return expression; | 4508 return expression; |
| 4508 } | 4509 } |
| 4509 | 4510 |
| 4510 /** | 4511 /** |
| 4511 * Parse a rethrow expression. Return the rethrow expression that was parsed. | 4512 * Parse a rethrow expression. Return the rethrow expression that was parsed. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4536 return astFactory.returnStatement(returnKeyword, expression, semicolon); | 4537 return astFactory.returnStatement(returnKeyword, expression, semicolon); |
| 4537 } | 4538 } |
| 4538 | 4539 |
| 4539 /** | 4540 /** |
| 4540 * Parse a return type. Return the return type that was parsed. | 4541 * Parse a return type. Return the return type that was parsed. |
| 4541 * | 4542 * |
| 4542 * returnType ::= | 4543 * returnType ::= |
| 4543 * 'void' | 4544 * 'void' |
| 4544 * | type | 4545 * | type |
| 4545 */ | 4546 */ |
| 4546 TypeName parseReturnType() { | 4547 TypeAnnotation parseReturnType(bool inExpression) { |
| 4547 if (_currentToken.keyword == Keyword.VOID) { | 4548 if (_currentToken.keyword == Keyword.VOID) { |
| 4548 return astFactory.typeName( | 4549 return astFactory.typeName( |
| 4549 astFactory.simpleIdentifier(getAndAdvance()), null); | 4550 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 4550 } else { | 4551 } else { |
| 4551 return parseTypeName(false); | 4552 return parseTypeAnnotation(inExpression); |
| 4552 } | 4553 } |
| 4553 } | 4554 } |
| 4554 | 4555 |
| 4555 /** | 4556 /** |
| 4556 * Parse a setter. The [commentAndMetadata] is the documentation comment and | 4557 * Parse a setter. The [commentAndMetadata] is the documentation comment and |
| 4557 * metadata to be associated with the declaration. The [externalKeyword] is | 4558 * metadata to be associated with the declaration. The [externalKeyword] is |
| 4558 * the 'external' token. The [staticKeyword] is the static keyword, or `null` | 4559 * the 'external' token. The [staticKeyword] is the static keyword, or `null` |
| 4559 * if the setter is not static. The [returnType] is the return type that has | 4560 * if the setter is not static. The [returnType] is the return type that has |
| 4560 * already been parsed, or `null` if there was no return type. Return the | 4561 * already been parsed, or `null` if there was no return type. Return the |
| 4561 * setter that was parsed. | 4562 * setter that was parsed. |
| 4562 * | 4563 * |
| 4563 * This method assumes that the current token matches `Keyword.SET`. | 4564 * This method assumes that the current token matches `Keyword.SET`. |
| 4564 * | 4565 * |
| 4565 * setter ::= | 4566 * setter ::= |
| 4566 * setterSignature functionBody? | 4567 * setterSignature functionBody? |
| 4567 * | 4568 * |
| 4568 * setterSignature ::= | 4569 * setterSignature ::= |
| 4569 * 'external'? 'static'? returnType? 'set' identifier formalParameterL
ist | 4570 * 'external'? 'static'? returnType? 'set' identifier formalParameterL
ist |
| 4570 */ | 4571 */ |
| 4571 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, | 4572 MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata, |
| 4572 Token externalKeyword, Token staticKeyword, TypeName returnType) { | 4573 Token externalKeyword, Token staticKeyword, TypeAnnotation returnType) { |
| 4573 Token propertyKeyword = getAndAdvance(); | 4574 Token propertyKeyword = getAndAdvance(); |
| 4574 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 4575 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 4575 FormalParameterList parameters = parseFormalParameterList(); | 4576 FormalParameterList parameters = parseFormalParameterList(); |
| 4576 _validateFormalParameterList(parameters); | 4577 _validateFormalParameterList(parameters); |
| 4577 FunctionBody body = parseFunctionBody( | 4578 FunctionBody body = parseFunctionBody( |
| 4578 externalKeyword != null || staticKeyword == null, | 4579 externalKeyword != null || staticKeyword == null, |
| 4579 ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, | 4580 ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, |
| 4580 false); | 4581 false); |
| 4581 if (externalKeyword != null && body is! EmptyFunctionBody) { | 4582 if (externalKeyword != null && body is! EmptyFunctionBody) { |
| 4582 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY); | 4583 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY); |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4897 Statement parseTryStatement() { | 4898 Statement parseTryStatement() { |
| 4898 Token tryKeyword = getAndAdvance(); | 4899 Token tryKeyword = getAndAdvance(); |
| 4899 Block body = _parseBlockChecked(); | 4900 Block body = _parseBlockChecked(); |
| 4900 List<CatchClause> catchClauses = <CatchClause>[]; | 4901 List<CatchClause> catchClauses = <CatchClause>[]; |
| 4901 Block finallyClause = null; | 4902 Block finallyClause = null; |
| 4902 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { | 4903 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { |
| 4903 Token onKeyword = null; | 4904 Token onKeyword = null; |
| 4904 TypeName exceptionType = null; | 4905 TypeName exceptionType = null; |
| 4905 if (_matchesString(_ON)) { | 4906 if (_matchesString(_ON)) { |
| 4906 onKeyword = getAndAdvance(); | 4907 onKeyword = getAndAdvance(); |
| 4907 exceptionType = parseTypeName(false); | 4908 exceptionType = parseTypeAnnotation(false); |
| 4908 } | 4909 } |
| 4909 Token catchKeyword = null; | 4910 Token catchKeyword = null; |
| 4910 Token leftParenthesis = null; | 4911 Token leftParenthesis = null; |
| 4911 SimpleIdentifier exceptionParameter = null; | 4912 SimpleIdentifier exceptionParameter = null; |
| 4912 Token comma = null; | 4913 Token comma = null; |
| 4913 SimpleIdentifier stackTraceParameter = null; | 4914 SimpleIdentifier stackTraceParameter = null; |
| 4914 Token rightParenthesis = null; | 4915 Token rightParenthesis = null; |
| 4915 if (_matchesKeyword(Keyword.CATCH)) { | 4916 if (_matchesKeyword(Keyword.CATCH)) { |
| 4916 catchKeyword = getAndAdvance(); | 4917 catchKeyword = getAndAdvance(); |
| 4917 leftParenthesis = _expect(TokenType.OPEN_PAREN); | 4918 leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4984 return _parseFunctionTypeAlias(commentAndMetadata, keyword); | 4985 return _parseFunctionTypeAlias(commentAndMetadata, keyword); |
| 4985 } | 4986 } |
| 4986 | 4987 |
| 4987 /** | 4988 /** |
| 4988 * Parse a type. | 4989 * Parse a type. |
| 4989 * | 4990 * |
| 4990 * type ::= | 4991 * type ::= |
| 4991 * typeWithoutFunction | 4992 * typeWithoutFunction |
| 4992 * | functionType | 4993 * | functionType |
| 4993 */ | 4994 */ |
| 4994 TypeAnnotation parseTypeAnnotation() { | 4995 TypeAnnotation parseTypeAnnotation(bool inExpression) { |
| 4995 if (_matchesString('Function')) { | 4996 TypeAnnotation type = null; |
| 4997 if (_atGenericFunctionTypeAfterReturnType(_currentToken)) { |
| 4996 // Generic function type with no return type. | 4998 // Generic function type with no return type. |
| 4997 return parseGenericFunctionTypeAfterReturnType(null); | 4999 type = parseGenericFunctionTypeAfterReturnType(null); |
| 5000 } else if (_currentToken.keyword == Keyword.VOID && |
| 5001 _atGenericFunctionTypeAfterReturnType(_currentToken.next)) { |
| 5002 type = astFactory.typeName( |
| 5003 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 5004 } else { |
| 5005 type = parseTypeName(inExpression); |
| 4998 } | 5006 } |
| 4999 TypeAnnotation type = parseReturnType(); | 5007 while (_atGenericFunctionTypeAfterReturnType(_currentToken)) { |
| 5000 while (_matchesString('Function')) { | |
| 5001 type = parseGenericFunctionTypeAfterReturnType(type); | 5008 type = parseGenericFunctionTypeAfterReturnType(type); |
| 5002 } | 5009 } |
| 5003 return type; | 5010 return type; |
| 5004 } | 5011 } |
| 5005 | 5012 |
| 5006 /** | 5013 /** |
| 5007 * Parse a list of type arguments. Return the type argument list that was | 5014 * Parse a list of type arguments. Return the type argument list that was |
| 5008 * parsed. | 5015 * parsed. |
| 5009 * | 5016 * |
| 5010 * This method assumes that the current token matches `TokenType.LT`. | 5017 * This method assumes that the current token matches `TokenType.LT`. |
| 5011 * | 5018 * |
| 5012 * typeArguments ::= | 5019 * typeArguments ::= |
| 5013 * '<' typeList '>' | 5020 * '<' typeList '>' |
| 5014 * | 5021 * |
| 5015 * typeList ::= | 5022 * typeList ::= |
| 5016 * type (',' type)* | 5023 * type (',' type)* |
| 5017 */ | 5024 */ |
| 5018 TypeArgumentList parseTypeArgumentList() { | 5025 TypeArgumentList parseTypeArgumentList() { |
| 5019 Token leftBracket = getAndAdvance(); | 5026 Token leftBracket = getAndAdvance(); |
| 5020 List<TypeName> arguments = <TypeName>[parseTypeName(false)]; | 5027 List<TypeAnnotation> arguments = <TypeAnnotation>[ |
| 5028 parseTypeAnnotation(false) |
| 5029 ]; |
| 5021 while (_optional(TokenType.COMMA)) { | 5030 while (_optional(TokenType.COMMA)) { |
| 5022 arguments.add(parseTypeName(false)); | 5031 arguments.add(parseTypeAnnotation(false)); |
| 5023 } | 5032 } |
| 5024 Token rightBracket = _expectGt(); | 5033 Token rightBracket = _expectGt(); |
| 5025 return astFactory.typeArgumentList(leftBracket, arguments, rightBracket); | 5034 return astFactory.typeArgumentList(leftBracket, arguments, rightBracket); |
| 5026 } | 5035 } |
| 5027 | 5036 |
| 5028 /** | 5037 /** |
| 5029 * Parse a type name. Return the type name that was parsed. | 5038 * Parse a type name. Return the type name that was parsed. |
| 5030 * | 5039 * |
| 5031 * type ::= | 5040 * type ::= |
| 5032 * qualified typeArguments? | 5041 * qualified typeArguments? |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5049 */ | 5058 */ |
| 5050 TypeParameter parseTypeParameter() { | 5059 TypeParameter parseTypeParameter() { |
| 5051 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 5060 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 5052 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 5061 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 5053 if (_matches(TokenType.QUESTION)) { | 5062 if (_matches(TokenType.QUESTION)) { |
| 5054 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); | 5063 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); |
| 5055 _advance(); | 5064 _advance(); |
| 5056 } | 5065 } |
| 5057 if (_matchesKeyword(Keyword.EXTENDS)) { | 5066 if (_matchesKeyword(Keyword.EXTENDS)) { |
| 5058 Token keyword = getAndAdvance(); | 5067 Token keyword = getAndAdvance(); |
| 5059 TypeName bound = parseTypeName(false); | 5068 TypeAnnotation bound = parseTypeAnnotation(false); |
| 5060 return astFactory.typeParameter(commentAndMetadata.comment, | 5069 return astFactory.typeParameter(commentAndMetadata.comment, |
| 5061 commentAndMetadata.metadata, name, keyword, bound); | 5070 commentAndMetadata.metadata, name, keyword, bound); |
| 5062 } | 5071 } |
| 5063 return astFactory.typeParameter(commentAndMetadata.comment, | 5072 return astFactory.typeParameter(commentAndMetadata.comment, |
| 5064 commentAndMetadata.metadata, name, null, null); | 5073 commentAndMetadata.metadata, name, null, null); |
| 5065 } | 5074 } |
| 5066 | 5075 |
| 5067 /** | 5076 /** |
| 5068 * Parse a list of type parameters. Return the list of type parameters that | 5077 * Parse a list of type parameters. Return the list of type parameters that |
| 5069 * were parsed. | 5078 * were parsed. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5207 * to be associated with the variable declaration list, or `null` if there is | 5216 * to be associated with the variable declaration list, or `null` if there is |
| 5208 * no attempt at parsing the comment and metadata. The [keyword] is the token | 5217 * no attempt at parsing the comment and metadata. The [keyword] is the token |
| 5209 * representing the 'final', 'const' or 'var' keyword, or `null` if there is | 5218 * representing the 'final', 'const' or 'var' keyword, or `null` if there is |
| 5210 * no keyword. The [type] is the type of the variables in the list. Return the | 5219 * no keyword. The [type] is the type of the variables in the list. Return the |
| 5211 * variable declaration list that was parsed. | 5220 * variable declaration list that was parsed. |
| 5212 * | 5221 * |
| 5213 * variableDeclarationList ::= | 5222 * variableDeclarationList ::= |
| 5214 * finalConstVarOrType variableDeclaration (',' variableDeclaration)* | 5223 * finalConstVarOrType variableDeclaration (',' variableDeclaration)* |
| 5215 */ | 5224 */ |
| 5216 VariableDeclarationList parseVariableDeclarationListAfterType( | 5225 VariableDeclarationList parseVariableDeclarationListAfterType( |
| 5217 CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) { | 5226 CommentAndMetadata commentAndMetadata, |
| 5227 Token keyword, |
| 5228 TypeAnnotation type) { |
| 5218 if (type != null && | 5229 if (type != null && |
| 5219 keyword != null && | 5230 keyword != null && |
| 5220 _tokenMatchesKeyword(keyword, Keyword.VAR)) { | 5231 _tokenMatchesKeyword(keyword, Keyword.VAR)) { |
| 5221 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, keyword); | 5232 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, keyword); |
| 5222 } | 5233 } |
| 5223 List<VariableDeclaration> variables = <VariableDeclaration>[ | 5234 List<VariableDeclaration> variables = <VariableDeclaration>[ |
| 5224 parseVariableDeclaration() | 5235 parseVariableDeclaration() |
| 5225 ]; | 5236 ]; |
| 5226 while (_optional(TokenType.COMMA)) { | 5237 while (_optional(TokenType.COMMA)) { |
| 5227 variables.add(parseVariableDeclaration()); | 5238 variables.add(parseVariableDeclaration()); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5310 Token star = null; | 5321 Token star = null; |
| 5311 if (_matches(TokenType.STAR)) { | 5322 if (_matches(TokenType.STAR)) { |
| 5312 star = getAndAdvance(); | 5323 star = getAndAdvance(); |
| 5313 } | 5324 } |
| 5314 Expression expression = parseExpression2(); | 5325 Expression expression = parseExpression2(); |
| 5315 Token semicolon = _expect(TokenType.SEMICOLON); | 5326 Token semicolon = _expect(TokenType.SEMICOLON); |
| 5316 return astFactory.yieldStatement(yieldToken, star, expression, semicolon); | 5327 return astFactory.yieldStatement(yieldToken, star, expression, semicolon); |
| 5317 } | 5328 } |
| 5318 | 5329 |
| 5319 /** | 5330 /** |
| 5331 * Parse a formal parameter list, starting at the [startToken], without |
| 5332 * actually creating a formal parameter list or changing the current token. |
| 5333 * Return the token following the parameter list that was parsed, or `null` |
| 5334 * if the given token is not the first token in a valid parameter list. |
| 5335 * |
| 5336 * This method must be kept in sync with [parseFormalParameterList]. |
| 5337 */ |
| 5338 Token skipFormalParameterList(Token startToken) { |
| 5339 if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) { |
| 5340 return null; |
| 5341 } |
| 5342 return (startToken as BeginToken).endToken; |
| 5343 } |
| 5344 |
| 5345 /** |
| 5346 * Parse the portion of a generic function type after the return type, |
| 5347 * starting at the [startToken], without actually creating a generic function |
| 5348 * type or changing the current token. Return the token following the generic |
| 5349 * function type that was parsed, or `null` if the given token is not the |
| 5350 * first token in a valid generic function type. |
| 5351 * |
| 5352 * This method must be kept in sync with |
| 5353 * [parseGenericFunctionTypeAfterReturnType]. |
| 5354 */ |
| 5355 Token skipGenericFunctionTypeAfterReturnType(Token startToken) { |
| 5356 Token next = startToken.next; // Skip 'Function' |
| 5357 if (_tokenMatches(next, TokenType.LT)) { |
| 5358 next = skipTypeParameterList(next); |
| 5359 } |
| 5360 return skipFormalParameterList(next); |
| 5361 } |
| 5362 |
| 5363 /** |
| 5320 * Parse a prefixed identifier, starting at the [startToken], without actually | 5364 * Parse a prefixed identifier, starting at the [startToken], without actually |
| 5321 * creating a prefixed identifier or changing the current token. Return the | 5365 * creating a prefixed identifier or changing the current token. Return the |
| 5322 * token following the prefixed identifier that was parsed, or `null` if the | 5366 * token following the prefixed identifier that was parsed, or `null` if the |
| 5323 * given token is not the first token in a valid prefixed identifier. | 5367 * given token is not the first token in a valid prefixed identifier. |
| 5324 * | 5368 * |
| 5325 * This method must be kept in sync with [parsePrefixedIdentifier]. | 5369 * This method must be kept in sync with [parsePrefixedIdentifier]. |
| 5326 * | 5370 * |
| 5327 * prefixedIdentifier ::= | 5371 * prefixedIdentifier ::= |
| 5328 * identifier ('.' identifier)? | 5372 * identifier ('.' identifier)? |
| 5329 */ | 5373 */ |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5357 * This method must be kept in sync with [parseReturnType]. | 5401 * This method must be kept in sync with [parseReturnType]. |
| 5358 * | 5402 * |
| 5359 * returnType ::= | 5403 * returnType ::= |
| 5360 * 'void' | 5404 * 'void' |
| 5361 * | type | 5405 * | type |
| 5362 */ | 5406 */ |
| 5363 Token skipReturnType(Token startToken) { | 5407 Token skipReturnType(Token startToken) { |
| 5364 if (_tokenMatchesKeyword(startToken, Keyword.VOID)) { | 5408 if (_tokenMatchesKeyword(startToken, Keyword.VOID)) { |
| 5365 return startToken.next; | 5409 return startToken.next; |
| 5366 } else { | 5410 } else { |
| 5367 return skipTypeName(startToken); | 5411 return skipTypeAnnotation(startToken); |
| 5368 } | 5412 } |
| 5369 } | 5413 } |
| 5370 | 5414 |
| 5371 /** | 5415 /** |
| 5372 * Parse a simple identifier, starting at the [startToken], without actually | 5416 * Parse a simple identifier, starting at the [startToken], without actually |
| 5373 * creating a simple identifier or changing the current token. Return the | 5417 * creating a simple identifier or changing the current token. Return the |
| 5374 * token following the simple identifier that was parsed, or `null` if the | 5418 * token following the simple identifier that was parsed, or `null` if the |
| 5375 * given token is not the first token in a valid simple identifier. | 5419 * given token is not the first token in a valid simple identifier. |
| 5376 * | 5420 * |
| 5377 * This method must be kept in sync with [parseSimpleIdentifier]. | 5421 * This method must be kept in sync with [parseSimpleIdentifier]. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5409 token = _skipStringInterpolation(token); | 5453 token = _skipStringInterpolation(token); |
| 5410 } | 5454 } |
| 5411 } | 5455 } |
| 5412 if (identical(token, startToken)) { | 5456 if (identical(token, startToken)) { |
| 5413 return null; | 5457 return null; |
| 5414 } | 5458 } |
| 5415 return token; | 5459 return token; |
| 5416 } | 5460 } |
| 5417 | 5461 |
| 5418 /** | 5462 /** |
| 5463 * Parse a type annotation, starting at the [startToken], without actually |
| 5464 * creating a type annotation or changing the current token. Return the token |
| 5465 * following the type annotation that was parsed, or `null` if the given token |
| 5466 * is not the first token in a valid type annotation. |
| 5467 * |
| 5468 * This method must be kept in sync with [parseTypeAnnotation]. |
| 5469 */ |
| 5470 Token skipTypeAnnotation(Token startToken) { |
| 5471 Token next = null; |
| 5472 if (_atGenericFunctionTypeAfterReturnType(startToken)) { |
| 5473 next = skipGenericFunctionTypeAfterReturnType(startToken); |
| 5474 } else if (_currentToken.keyword == Keyword.VOID && |
| 5475 _atGenericFunctionTypeAfterReturnType(_currentToken.next)) { |
| 5476 next = next.next; |
| 5477 } else { |
| 5478 next = skipTypeName(startToken); |
| 5479 } |
| 5480 while (next != null && _tokenMatchesString(next, 'Function')) { |
| 5481 next = skipGenericFunctionTypeAfterReturnType(next); |
| 5482 } |
| 5483 return next; |
| 5484 } |
| 5485 |
| 5486 /** |
| 5419 * Parse a list of type arguments, starting at the [startToken], without | 5487 * Parse a list of type arguments, starting at the [startToken], without |
| 5420 * actually creating a type argument list or changing the current token. | 5488 * actually creating a type argument list or changing the current token. |
| 5421 * Return the token following the type argument list that was parsed, or | 5489 * Return the token following the type argument list that was parsed, or |
| 5422 * `null` if the given token is not the first token in a valid type argument | 5490 * `null` if the given token is not the first token in a valid type argument |
| 5423 * list. | 5491 * list. |
| 5424 * | 5492 * |
| 5425 * This method must be kept in sync with [parseTypeArgumentList]. | 5493 * This method must be kept in sync with [parseTypeArgumentList]. |
| 5426 * | 5494 * |
| 5427 * typeArguments ::= | 5495 * typeArguments ::= |
| 5428 * '<' typeList '>' | 5496 * '<' typeList '>' |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5478 if (token == null) { | 5546 if (token == null) { |
| 5479 return null; | 5547 return null; |
| 5480 } | 5548 } |
| 5481 if (_tokenMatches(token, TokenType.LT)) { | 5549 if (_tokenMatches(token, TokenType.LT)) { |
| 5482 token = skipTypeArgumentList(token); | 5550 token = skipTypeArgumentList(token); |
| 5483 } | 5551 } |
| 5484 return token; | 5552 return token; |
| 5485 } | 5553 } |
| 5486 | 5554 |
| 5487 /** | 5555 /** |
| 5556 * Parse a type parameter list, starting at the [startToken], without actually |
| 5557 * creating a type parameter list or changing the current token. Return the |
| 5558 * token following the type parameter list that was parsed, or `null` if the |
| 5559 * given token is not the first token in a valid type parameter list. |
| 5560 * |
| 5561 * This method must be kept in sync with [parseTypeParameterList]. |
| 5562 */ |
| 5563 Token skipTypeParameterList(Token startToken) { |
| 5564 if (!_tokenMatches(startToken, TokenType.LT)) { |
| 5565 return null; |
| 5566 } |
| 5567 int depth = 1; |
| 5568 Token previous = startToken; |
| 5569 Token next = startToken.next; |
| 5570 while (next != previous) { |
| 5571 if (_tokenMatches(startToken, TokenType.LT)) { |
| 5572 depth++; |
| 5573 } else if (_tokenMatches(next, TokenType.GT)) { |
| 5574 depth--; |
| 5575 if (depth == 0) { |
| 5576 return next; |
| 5577 } |
| 5578 } |
| 5579 previous = next; |
| 5580 next = next.next; |
| 5581 } |
| 5582 return null; |
| 5583 } |
| 5584 |
| 5585 /** |
| 5488 * Advance to the next token in the token stream. | 5586 * Advance to the next token in the token stream. |
| 5489 */ | 5587 */ |
| 5490 void _advance() { | 5588 void _advance() { |
| 5491 _currentToken = _currentToken.next; | 5589 _currentToken = _currentToken.next; |
| 5492 } | 5590 } |
| 5493 | 5591 |
| 5494 /** | 5592 /** |
| 5495 * Append the character equivalent of the given [codePoint] to the given | 5593 * Append the character equivalent of the given [codePoint] to the given |
| 5496 * [builder]. Use the [startIndex] and [endIndex] to report an error, and | 5594 * [builder]. Use the [startIndex] and [endIndex] to report an error, and |
| 5497 * don't append anything to the builder, if the code point is invalid. The | 5595 * don't append anything to the builder, if the code point is invalid. The |
| 5498 * [escapeSequence] is the escape sequence that was parsed to produce the | 5596 * [escapeSequence] is the escape sequence that was parsed to produce the |
| 5499 * code point (used for error reporting). | 5597 * code point (used for error reporting). |
| 5500 */ | 5598 */ |
| 5501 void _appendCodePoint(StringBuffer buffer, String source, int codePoint, | 5599 void _appendCodePoint(StringBuffer buffer, String source, int codePoint, |
| 5502 int startIndex, int endIndex) { | 5600 int startIndex, int endIndex) { |
| 5503 if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) { | 5601 if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) { |
| 5504 String escapeSequence = source.substring(startIndex, endIndex + 1); | 5602 String escapeSequence = source.substring(startIndex, endIndex + 1); |
| 5505 _reportErrorForCurrentToken( | 5603 _reportErrorForCurrentToken( |
| 5506 ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]); | 5604 ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]); |
| 5507 return; | 5605 return; |
| 5508 } | 5606 } |
| 5509 if (codePoint < Character.MAX_VALUE) { | 5607 if (codePoint < Character.MAX_VALUE) { |
| 5510 buffer.writeCharCode(codePoint); | 5608 buffer.writeCharCode(codePoint); |
| 5511 } else { | 5609 } else { |
| 5512 buffer.write(Character.toChars(codePoint)); | 5610 buffer.write(Character.toChars(codePoint)); |
| 5513 } | 5611 } |
| 5514 } | 5612 } |
| 5515 | 5613 |
| 5516 /** | 5614 /** |
| 5615 * Return `true` if we are positioned at the keyword 'Function' in a generic |
| 5616 * function type alias. |
| 5617 */ |
| 5618 bool _atGenericFunctionTypeAfterReturnType(Token startToken) { |
| 5619 if (_tokenMatchesString(startToken, 'Function')) { |
| 5620 Token next = startToken.next; |
| 5621 if (next != null && |
| 5622 (_tokenMatches(next, TokenType.OPEN_PAREN) || |
| 5623 _tokenMatches(next, TokenType.LT))) { |
| 5624 return true; |
| 5625 } |
| 5626 } |
| 5627 return false; |
| 5628 } |
| 5629 |
| 5630 /** |
| 5517 * Clone all token starting from the given [token] up to the end of the token | 5631 * Clone all token starting from the given [token] up to the end of the token |
| 5518 * stream, and return the first token in the new token stream. | 5632 * stream, and return the first token in the new token stream. |
| 5519 */ | 5633 */ |
| 5520 Token _cloneTokens(Token token) { | 5634 Token _cloneTokens(Token token) { |
| 5521 if (token == null) { | 5635 if (token == null) { |
| 5522 return null; | 5636 return null; |
| 5523 } | 5637 } |
| 5524 token = token is CommentToken ? token.parent : token; | 5638 token = token is CommentToken ? token.parent : token; |
| 5525 Token head = new Token(TokenType.EOF, -1); | 5639 Token head = new Token(TokenType.EOF, -1); |
| 5526 head.setNext(head); | 5640 head.setNext(head); |
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6642 /** | 6756 /** |
| 6643 * Parse a function declaration statement. The [commentAndMetadata] is the | 6757 * Parse a function declaration statement. The [commentAndMetadata] is the |
| 6644 * documentation comment and metadata to be associated with the declaration. | 6758 * documentation comment and metadata to be associated with the declaration. |
| 6645 * The [returnType] is the return type, or `null` if there is no return type. | 6759 * The [returnType] is the return type, or `null` if there is no return type. |
| 6646 * Return the function declaration statement that was parsed. | 6760 * Return the function declaration statement that was parsed. |
| 6647 * | 6761 * |
| 6648 * functionDeclarationStatement ::= | 6762 * functionDeclarationStatement ::= |
| 6649 * functionSignature functionBody | 6763 * functionSignature functionBody |
| 6650 */ | 6764 */ |
| 6651 Statement _parseFunctionDeclarationStatementAfterReturnType( | 6765 Statement _parseFunctionDeclarationStatementAfterReturnType( |
| 6652 CommentAndMetadata commentAndMetadata, TypeName returnType) { | 6766 CommentAndMetadata commentAndMetadata, TypeAnnotation returnType) { |
| 6653 FunctionDeclaration declaration = | 6767 FunctionDeclaration declaration = |
| 6654 parseFunctionDeclaration(commentAndMetadata, null, returnType); | 6768 parseFunctionDeclaration(commentAndMetadata, null, returnType); |
| 6655 Token propertyKeyword = declaration.propertyKeyword; | 6769 Token propertyKeyword = declaration.propertyKeyword; |
| 6656 if (propertyKeyword != null) { | 6770 if (propertyKeyword != null) { |
| 6657 if (propertyKeyword.keyword == Keyword.GET) { | 6771 if (propertyKeyword.keyword == Keyword.GET) { |
| 6658 _reportErrorForToken( | 6772 _reportErrorForToken( |
| 6659 ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword); | 6773 ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword); |
| 6660 } else { | 6774 } else { |
| 6661 _reportErrorForToken( | 6775 _reportErrorForToken( |
| 6662 ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword); | 6776 ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword); |
| 6663 } | 6777 } |
| 6664 } | 6778 } |
| 6665 return astFactory.functionDeclarationStatement(declaration); | 6779 return astFactory.functionDeclarationStatement(declaration); |
| 6666 } | 6780 } |
| 6667 | 6781 |
| 6668 /** | 6782 /** |
| 6669 * Parse a function type alias. The [commentAndMetadata] is the metadata to be | 6783 * Parse a function type alias. The [commentAndMetadata] is the metadata to be |
| 6670 * associated with the member. The [keyword] is the token representing the | 6784 * associated with the member. The [keyword] is the token representing the |
| 6671 * 'typedef' keyword. Return the function type alias that was parsed. | 6785 * 'typedef' keyword. Return the function type alias that was parsed. |
| 6672 * | 6786 * |
| 6673 * functionTypeAlias ::= | 6787 * functionTypeAlias ::= |
| 6674 * functionPrefix typeParameterList? formalParameterList ';' | 6788 * functionPrefix typeParameterList? formalParameterList ';' |
| 6675 * | 6789 * |
| 6676 * functionPrefix ::= | 6790 * functionPrefix ::= |
| 6677 * returnType? name | 6791 * returnType? name |
| 6678 */ | 6792 */ |
| 6679 FunctionTypeAlias _parseFunctionTypeAlias( | 6793 FunctionTypeAlias _parseFunctionTypeAlias( |
| 6680 CommentAndMetadata commentAndMetadata, Token keyword) { | 6794 CommentAndMetadata commentAndMetadata, Token keyword) { |
| 6681 TypeName returnType = null; | 6795 TypeAnnotation returnType = null; |
| 6682 if (hasReturnTypeInTypeAlias) { | 6796 if (hasReturnTypeInTypeAlias) { |
| 6683 returnType = parseReturnType(); | 6797 returnType = parseReturnType(false); |
| 6684 } | 6798 } |
| 6685 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 6799 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 6686 TypeParameterList typeParameters = null; | 6800 TypeParameterList typeParameters = null; |
| 6687 if (_matches(TokenType.LT)) { | 6801 if (_matches(TokenType.LT)) { |
| 6688 typeParameters = parseTypeParameterList(); | 6802 typeParameters = parseTypeParameterList(); |
| 6689 } | 6803 } |
| 6690 TokenType type = _currentToken.type; | 6804 TokenType type = _currentToken.type; |
| 6691 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { | 6805 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { |
| 6692 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); | 6806 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); |
| 6693 FormalParameterList parameters = astFactory.formalParameterList( | 6807 FormalParameterList parameters = astFactory.formalParameterList( |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6806 * that was parsed. | 6920 * that was parsed. |
| 6807 * | 6921 * |
| 6808 * functionDeclaration ::= | 6922 * functionDeclaration ::= |
| 6809 * ('external' 'static'?)? functionSignature functionBody | 6923 * ('external' 'static'?)? functionSignature functionBody |
| 6810 * | 'external'? functionSignature ';' | 6924 * | 'external'? functionSignature ';' |
| 6811 */ | 6925 */ |
| 6812 MethodDeclaration _parseMethodDeclarationAfterParameters( | 6926 MethodDeclaration _parseMethodDeclarationAfterParameters( |
| 6813 CommentAndMetadata commentAndMetadata, | 6927 CommentAndMetadata commentAndMetadata, |
| 6814 Token externalKeyword, | 6928 Token externalKeyword, |
| 6815 Token staticKeyword, | 6929 Token staticKeyword, |
| 6816 TypeName returnType, | 6930 TypeAnnotation returnType, |
| 6817 SimpleIdentifier name, | 6931 SimpleIdentifier name, |
| 6818 TypeParameterList typeParameters, | 6932 TypeParameterList typeParameters, |
| 6819 FormalParameterList parameters) { | 6933 FormalParameterList parameters) { |
| 6820 FunctionBody body = parseFunctionBody( | 6934 FunctionBody body = parseFunctionBody( |
| 6821 externalKeyword != null || staticKeyword == null, | 6935 externalKeyword != null || staticKeyword == null, |
| 6822 ParserErrorCode.MISSING_FUNCTION_BODY, | 6936 ParserErrorCode.MISSING_FUNCTION_BODY, |
| 6823 false); | 6937 false); |
| 6824 if (externalKeyword != null) { | 6938 if (externalKeyword != null) { |
| 6825 if (body is! EmptyFunctionBody) { | 6939 if (body is! EmptyFunctionBody) { |
| 6826 _reportErrorForNode(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body); | 6940 _reportErrorForNode(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 6853 * parsed. | 6967 * parsed. |
| 6854 * | 6968 * |
| 6855 * functionDeclaration ::= | 6969 * functionDeclaration ::= |
| 6856 * 'external'? 'static'? functionSignature functionBody | 6970 * 'external'? 'static'? functionSignature functionBody |
| 6857 * | 'external'? functionSignature ';' | 6971 * | 'external'? functionSignature ';' |
| 6858 */ | 6972 */ |
| 6859 MethodDeclaration _parseMethodDeclarationAfterReturnType( | 6973 MethodDeclaration _parseMethodDeclarationAfterReturnType( |
| 6860 CommentAndMetadata commentAndMetadata, | 6974 CommentAndMetadata commentAndMetadata, |
| 6861 Token externalKeyword, | 6975 Token externalKeyword, |
| 6862 Token staticKeyword, | 6976 Token staticKeyword, |
| 6863 TypeName returnType) { | 6977 TypeAnnotation returnType) { |
| 6864 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); | 6978 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); |
| 6865 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); | 6979 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); |
| 6866 FormalParameterList parameters; | 6980 FormalParameterList parameters; |
| 6867 TokenType type = _currentToken.type; | 6981 TokenType type = _currentToken.type; |
| 6868 // TODO(brianwilkerson) Figure out why we care what the current token is if | 6982 // TODO(brianwilkerson) Figure out why we care what the current token is if |
| 6869 // it isn't a paren. | 6983 // it isn't a paren. |
| 6870 if (type != TokenType.OPEN_PAREN && | 6984 if (type != TokenType.OPEN_PAREN && |
| 6871 (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.FUNCTION)) { | 6985 (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.FUNCTION)) { |
| 6872 _reportErrorForToken( | 6986 _reportErrorForToken( |
| 6873 ParserErrorCode.MISSING_METHOD_PARAMETERS, _currentToken.previous); | 6987 ParserErrorCode.MISSING_METHOD_PARAMETERS, _currentToken.previous); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6915 * | 7029 * |
| 6916 * operatorDeclaration ::= | 7030 * operatorDeclaration ::= |
| 6917 * operatorSignature (';' | functionBody) | 7031 * operatorSignature (';' | functionBody) |
| 6918 * | 7032 * |
| 6919 * operatorSignature ::= | 7033 * operatorSignature ::= |
| 6920 * 'external'? returnType? 'operator' operator formalParameterList | 7034 * 'external'? returnType? 'operator' operator formalParameterList |
| 6921 */ | 7035 */ |
| 6922 MethodDeclaration _parseOperatorAfterKeyword( | 7036 MethodDeclaration _parseOperatorAfterKeyword( |
| 6923 CommentAndMetadata commentAndMetadata, | 7037 CommentAndMetadata commentAndMetadata, |
| 6924 Token externalKeyword, | 7038 Token externalKeyword, |
| 6925 TypeName returnType, | 7039 TypeAnnotation returnType, |
| 6926 Token operatorKeyword) { | 7040 Token operatorKeyword) { |
| 6927 if (!_currentToken.isUserDefinableOperator) { | 7041 if (!_currentToken.isUserDefinableOperator) { |
| 6928 _reportErrorForCurrentToken( | 7042 _reportErrorForCurrentToken( |
| 6929 ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]); | 7043 ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]); |
| 6930 } | 7044 } |
| 6931 SimpleIdentifier name = | 7045 SimpleIdentifier name = |
| 6932 astFactory.simpleIdentifier(getAndAdvance(), isDeclaration: true); | 7046 astFactory.simpleIdentifier(getAndAdvance(), isDeclaration: true); |
| 6933 if (_matches(TokenType.EQ)) { | 7047 if (_matches(TokenType.EQ)) { |
| 6934 Token previous = _currentToken.previous; | 7048 Token previous = _currentToken.previous; |
| 6935 if ((_tokenMatches(previous, TokenType.EQ_EQ) || | 7049 if ((_tokenMatches(previous, TokenType.EQ_EQ) || |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6958 name, | 7072 name, |
| 6959 null, | 7073 null, |
| 6960 parameters, | 7074 parameters, |
| 6961 body); | 7075 body); |
| 6962 } | 7076 } |
| 6963 | 7077 |
| 6964 /** | 7078 /** |
| 6965 * Parse a return type if one is given, otherwise return `null` without | 7079 * Parse a return type if one is given, otherwise return `null` without |
| 6966 * advancing. Return the return type that was parsed. | 7080 * advancing. Return the return type that was parsed. |
| 6967 */ | 7081 */ |
| 6968 TypeName _parseOptionalReturnType() { | 7082 TypeAnnotation _parseOptionalReturnType() { |
| 6969 TypeName typeComment = _parseOptionalTypeNameComment(); | 7083 TypeName typeComment = _parseOptionalTypeNameComment(); |
| 6970 if (typeComment != null) { | 7084 if (typeComment != null) { |
| 6971 return typeComment; | 7085 return typeComment; |
| 6972 } | 7086 } |
| 6973 Keyword keyword = _currentToken.keyword; | 7087 Keyword keyword = _currentToken.keyword; |
| 6974 if (keyword == Keyword.VOID) { | 7088 if (keyword == Keyword.VOID) { |
| 6975 return astFactory.typeName( | 7089 return astFactory.typeName( |
| 6976 astFactory.simpleIdentifier(getAndAdvance()), null); | 7090 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 6977 } else if (_matchesIdentifier()) { | 7091 } else if (_matchesIdentifier()) { |
| 6978 Token next = _peek(); | 7092 Token next = _peek(); |
| 6979 if (keyword != Keyword.GET && | 7093 if (keyword != Keyword.GET && |
| 6980 keyword != Keyword.SET && | 7094 keyword != Keyword.SET && |
| 6981 keyword != Keyword.OPERATOR && | 7095 keyword != Keyword.OPERATOR && |
| 6982 (_tokenMatchesIdentifier(next) || | 7096 (_tokenMatchesIdentifier(next) || |
| 6983 _tokenMatches(next, TokenType.LT))) { | 7097 _tokenMatches(next, TokenType.LT))) { |
| 6984 Token afterTypeParameters = _skipTypeParameterList(next); | 7098 Token afterTypeParameters = _skipTypeParameterList(next); |
| 6985 if (afterTypeParameters != null && | 7099 if (afterTypeParameters != null && |
| 6986 _tokenMatches(afterTypeParameters, TokenType.OPEN_PAREN)) { | 7100 _tokenMatches(afterTypeParameters, TokenType.OPEN_PAREN)) { |
| 6987 // If the identifier is followed by type parameters and a parenthesis, | 7101 // If the identifier is followed by type parameters and a parenthesis, |
| 6988 // then the identifier is the name of a generic method, not a return | 7102 // then the identifier is the name of a generic method, not a return |
| 6989 // type. | 7103 // type. |
| 6990 return null; | 7104 return null; |
| 6991 } | 7105 } |
| 6992 return parseReturnType(); | 7106 return parseReturnType(false); |
| 6993 } | 7107 } |
| 6994 Token next2 = next.next; | 7108 Token next2 = next.next; |
| 6995 Token next3 = next2.next; | 7109 Token next3 = next2.next; |
| 6996 if (_tokenMatches(next, TokenType.PERIOD) && | 7110 if (_tokenMatches(next, TokenType.PERIOD) && |
| 6997 _tokenMatchesIdentifier(next2) && | 7111 _tokenMatchesIdentifier(next2) && |
| 6998 (_tokenMatchesIdentifier(next3) || | 7112 (_tokenMatchesIdentifier(next3) || |
| 6999 _tokenMatches(next3, TokenType.LT))) { | 7113 _tokenMatches(next3, TokenType.LT))) { |
| 7000 return parseReturnType(); | 7114 return parseReturnType(false); |
| 7001 } | 7115 } |
| 7002 } | 7116 } |
| 7003 return null; | 7117 return null; |
| 7004 } | 7118 } |
| 7005 | 7119 |
| 7006 /** | 7120 /** |
| 7007 * Parse a [TypeArgumentList] if present, otherwise return null. | 7121 * Parse a [TypeArgumentList] if present, otherwise return null. |
| 7008 * This also supports the comment form, if enabled: `/*<T>*/` | 7122 * This also supports the comment form, if enabled: `/*<T>*/` |
| 7009 */ | 7123 */ |
| 7010 TypeArgumentList _parseOptionalTypeArguments() { | 7124 TypeArgumentList _parseOptionalTypeArguments() { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7227 } else { | 7341 } else { |
| 7228 strings.add(astFactory.simpleStringLiteral( | 7342 strings.add(astFactory.simpleStringLiteral( |
| 7229 string, computeStringValue(string.lexeme, true, true))); | 7343 string, computeStringValue(string.lexeme, true, true))); |
| 7230 } | 7344 } |
| 7231 } while (_matches(TokenType.STRING)); | 7345 } while (_matches(TokenType.STRING)); |
| 7232 return strings.length == 1 | 7346 return strings.length == 1 |
| 7233 ? strings[0] | 7347 ? strings[0] |
| 7234 : astFactory.adjacentStrings(strings); | 7348 : astFactory.adjacentStrings(strings); |
| 7235 } | 7349 } |
| 7236 | 7350 |
| 7351 /** |
| 7352 * Parse a type annotation, possibly superseded by a type name in a comment. |
| 7353 * Return the type name that was parsed. |
| 7354 * |
| 7355 * This method assumes that the current token is an identifier. |
| 7356 * |
| 7357 * type ::= |
| 7358 * qualified typeArguments? |
| 7359 */ |
| 7360 TypeAnnotation _parseTypeAnnotationAfterIdentifier() { |
| 7361 TypeAnnotation type = parseTypeAnnotation(false); |
| 7362 // If this is followed by a generic method type comment, allow the comment |
| 7363 // type to replace the real type name. |
| 7364 TypeName typeFromComment = _parseOptionalTypeNameComment(); |
| 7365 return typeFromComment ?? type; |
| 7366 } |
| 7367 |
| 7237 TypeName _parseTypeName(bool inExpression) { | 7368 TypeName _parseTypeName(bool inExpression) { |
| 7238 Identifier typeName; | 7369 Identifier typeName; |
| 7239 if (_matchesIdentifier()) { | 7370 if (_matchesIdentifier()) { |
| 7240 typeName = _parsePrefixedIdentifierUnchecked(); | 7371 typeName = _parsePrefixedIdentifierUnchecked(); |
| 7241 } else if (_matchesKeyword(Keyword.VAR)) { | 7372 } else if (_matchesKeyword(Keyword.VAR)) { |
| 7242 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); | 7373 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); |
| 7243 typeName = astFactory.simpleIdentifier(getAndAdvance()); | 7374 typeName = astFactory.simpleIdentifier(getAndAdvance()); |
| 7244 } else { | 7375 } else { |
| 7245 typeName = createSyntheticIdentifier(); | 7376 typeName = createSyntheticIdentifier(); |
| 7246 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); | 7377 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); |
| 7247 } | 7378 } |
| 7248 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7379 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 7249 Token question = null; | 7380 Token question = null; |
| 7250 if (enableNnbd && _matches(TokenType.QUESTION)) { | 7381 if (enableNnbd && _matches(TokenType.QUESTION)) { |
| 7251 if (!inExpression || !_isConditionalOperator()) { | 7382 if (!inExpression || !_isConditionalOperator()) { |
| 7252 question = getAndAdvance(); | 7383 question = getAndAdvance(); |
| 7253 } | 7384 } |
| 7254 } | 7385 } |
| 7255 return astFactory.typeName(typeName, typeArguments, question: question); | 7386 return astFactory.typeName(typeName, typeArguments, question: question); |
| 7256 } | 7387 } |
| 7257 | 7388 |
| 7258 /** | 7389 /** |
| 7259 * Parse a type name. Return the type name that was parsed. | |
| 7260 * | |
| 7261 * This method assumes that the current token is an identifier. | |
| 7262 * | |
| 7263 * type ::= | |
| 7264 * qualified typeArguments? | |
| 7265 */ | |
| 7266 TypeName _parseTypeNameAfterIdentifier() { | |
| 7267 Identifier typeName = _parsePrefixedIdentifierUnchecked(); | |
| 7268 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | |
| 7269 // If this is followed by a generic method type comment, allow the comment | |
| 7270 // type to replace the real type name. | |
| 7271 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to | |
| 7272 // only work inside generic methods? | |
| 7273 TypeName typeFromComment = _parseOptionalTypeNameComment(); | |
| 7274 return typeFromComment ?? astFactory.typeName(typeName, typeArguments); | |
| 7275 } | |
| 7276 | |
| 7277 /** | |
| 7278 * Parse a string literal representing a URI. Return the string literal that | 7390 * Parse a string literal representing a URI. Return the string literal that |
| 7279 * was parsed. | 7391 * was parsed. |
| 7280 */ | 7392 */ |
| 7281 StringLiteral _parseUri() { | 7393 StringLiteral _parseUri() { |
| 7282 // TODO(brianwilkerson) Should this function also return true for valid | 7394 // TODO(brianwilkerson) Should this function also return true for valid |
| 7283 // top-level keywords? | 7395 // top-level keywords? |
| 7284 bool isKeywordAfterUri(Token token) => | 7396 bool isKeywordAfterUri(Token token) => |
| 7285 token.lexeme == Keyword.AS.syntax || | 7397 token.lexeme == Keyword.AS.syntax || |
| 7286 token.lexeme == _HIDE || | 7398 token.lexeme == _HIDE || |
| 7287 token.lexeme == _SHOW; | 7399 token.lexeme == _SHOW; |
| (...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8294 */ | 8406 */ |
| 8295 Parser_SyntheticKeywordToken(Keyword keyword, int offset) | 8407 Parser_SyntheticKeywordToken(Keyword keyword, int offset) |
| 8296 : super(keyword, offset); | 8408 : super(keyword, offset); |
| 8297 | 8409 |
| 8298 @override | 8410 @override |
| 8299 int get length => 0; | 8411 int get length => 0; |
| 8300 | 8412 |
| 8301 @override | 8413 @override |
| 8302 Token copy() => new Parser_SyntheticKeywordToken(keyword, offset); | 8414 Token copy() => new Parser_SyntheticKeywordToken(keyword, offset); |
| 8303 } | 8415 } |
| OLD | NEW |