Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: pkg/analyzer/lib/src/generated/parser.dart

Issue 2638463002: Remaining parser changes for generic function types (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698