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

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

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

Powered by Google App Engine
This is Rietveld 408576698