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

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

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