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

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

Issue 2809773005: Fix parsing of generic function types as return types (Closed)
Patch Set: remove test Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.generated.parser; 5 library analyzer.src.generated.parser;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import "dart:math" as math; 8 import "dart:math" as math;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 * if what was found was not a valid class member. 1227 * if what was found was not a valid class member.
1228 * 1228 *
1229 * classMemberDefinition ::= 1229 * classMemberDefinition ::=
1230 * declaration ';' 1230 * declaration ';'
1231 * | methodSignature functionBody 1231 * | methodSignature functionBody
1232 */ 1232 */
1233 ClassMember parseClassMember(String className) { 1233 ClassMember parseClassMember(String className) {
1234 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); 1234 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
1235 Modifiers modifiers = parseModifiers(); 1235 Modifiers modifiers = parseModifiers();
1236 Keyword keyword = _currentToken.keyword; 1236 Keyword keyword = _currentToken.keyword;
1237 if (keyword == Keyword.VOID) { 1237 if (keyword == Keyword.VOID ||
1238 TypeName returnType = astFactory.typeName( 1238 _atGenericFunctionTypeAfterReturnType(_currentToken)) {
1239 astFactory.simpleIdentifier(getAndAdvance()), null); 1239 TypeAnnotation returnType;
1240 if (keyword == Keyword.VOID) {
1241 if (_atGenericFunctionTypeAfterReturnType(_peek())) {
1242 returnType = parseTypeAnnotation(false);
1243 } else {
1244 returnType = astFactory.typeName(
1245 astFactory.simpleIdentifier(getAndAdvance()), null);
1246 }
1247 } else {
1248 returnType = parseTypeAnnotation(false);
1249 }
1240 keyword = _currentToken.keyword; 1250 keyword = _currentToken.keyword;
1241 Token next = _peek(); 1251 Token next = _peek();
1242 bool isFollowedByIdentifier = _tokenMatchesIdentifier(next); 1252 bool isFollowedByIdentifier = _tokenMatchesIdentifier(next);
1243 if (keyword == Keyword.GET && isFollowedByIdentifier) { 1253 if (keyword == Keyword.GET && isFollowedByIdentifier) {
1244 _validateModifiersForGetterOrSetterOrMethod(modifiers); 1254 _validateModifiersForGetterOrSetterOrMethod(modifiers);
1245 return parseGetter(commentAndMetadata, modifiers.externalKeyword, 1255 return parseGetter(commentAndMetadata, modifiers.externalKeyword,
1246 modifiers.staticKeyword, returnType); 1256 modifiers.staticKeyword, returnType);
1247 } else if (keyword == Keyword.SET && isFollowedByIdentifier) { 1257 } else if (keyword == Keyword.SET && isFollowedByIdentifier) {
1248 _validateModifiersForGetterOrSetterOrMethod(modifiers); 1258 _validateModifiersForGetterOrSetterOrMethod(modifiers);
1249 return parseSetter(commentAndMetadata, modifiers.externalKeyword, 1259 return parseSetter(commentAndMetadata, modifiers.externalKeyword,
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
2024 TokenType nextType = next.type; 2034 TokenType nextType = next.type;
2025 if (keyword == Keyword.TYPEDEF && 2035 if (keyword == Keyword.TYPEDEF &&
2026 nextType != TokenType.PERIOD && 2036 nextType != TokenType.PERIOD &&
2027 nextType != TokenType.LT && 2037 nextType != TokenType.LT &&
2028 nextType != TokenType.OPEN_PAREN) { 2038 nextType != TokenType.OPEN_PAREN) {
2029 _validateModifiersForTypedef(modifiers); 2039 _validateModifiersForTypedef(modifiers);
2030 return parseTypeAlias(commentAndMetadata); 2040 return parseTypeAlias(commentAndMetadata);
2031 } else if (keyword == Keyword.ENUM) { 2041 } else if (keyword == Keyword.ENUM) {
2032 _validateModifiersForEnum(modifiers); 2042 _validateModifiersForEnum(modifiers);
2033 return parseEnumDeclaration(commentAndMetadata); 2043 return parseEnumDeclaration(commentAndMetadata);
2034 } else if (keyword == Keyword.VOID) { 2044 } else if (keyword == Keyword.VOID ||
2035 TypeName returnType = astFactory.typeName( 2045 _atGenericFunctionTypeAfterReturnType(_currentToken)) {
2036 astFactory.simpleIdentifier(getAndAdvance()), null); 2046 TypeAnnotation returnType;
2047 if (keyword == Keyword.VOID) {
2048 if (_atGenericFunctionTypeAfterReturnType(next)) {
2049 returnType = parseTypeAnnotation(false);
2050 } else {
2051 returnType = astFactory.typeName(
2052 astFactory.simpleIdentifier(getAndAdvance()), null);
2053 }
2054 } else {
2055 returnType = parseTypeAnnotation(false);
2056 }
2037 keyword = _currentToken.keyword; 2057 keyword = _currentToken.keyword;
2038 next = _peek(); 2058 next = _peek();
2039 if ((keyword == Keyword.GET || keyword == Keyword.SET) && 2059 if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
2040 _tokenMatchesIdentifier(next)) { 2060 _tokenMatchesIdentifier(next)) {
2041 _validateModifiersForTopLevelFunction(modifiers); 2061 _validateModifiersForTopLevelFunction(modifiers);
2042 return parseFunctionDeclaration( 2062 return parseFunctionDeclaration(
2043 commentAndMetadata, modifiers.externalKeyword, returnType); 2063 commentAndMetadata, modifiers.externalKeyword, returnType);
2044 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { 2064 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
2045 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); 2065 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken);
2046 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( 2066 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword(
(...skipping 1965 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 return astFactory.expressionStatement( 4032 return astFactory.expressionStatement(
4013 parseThrowExpression(), _expect(TokenType.SEMICOLON)); 4033 parseThrowExpression(), _expect(TokenType.SEMICOLON));
4014 } else if (keyword == Keyword.TRY) { 4034 } else if (keyword == Keyword.TRY) {
4015 return parseTryStatement(); 4035 return parseTryStatement();
4016 } else if (keyword == Keyword.WHILE) { 4036 } else if (keyword == Keyword.WHILE) {
4017 return parseWhileStatement(); 4037 return parseWhileStatement();
4018 } else if (keyword == Keyword.VAR || keyword == Keyword.FINAL) { 4038 } else if (keyword == Keyword.VAR || keyword == Keyword.FINAL) {
4019 return parseVariableDeclarationStatementAfterMetadata( 4039 return parseVariableDeclarationStatementAfterMetadata(
4020 commentAndMetadata); 4040 commentAndMetadata);
4021 } else if (keyword == Keyword.VOID) { 4041 } else if (keyword == Keyword.VOID) {
4022 TypeName returnType = astFactory.typeName( 4042 TypeAnnotation returnType;
4023 astFactory.simpleIdentifier(getAndAdvance()), null); 4043 if (_atGenericFunctionTypeAfterReturnType(_peek())) {
4044 returnType = parseTypeAnnotation(false);
4045 } else {
4046 returnType = astFactory.typeName(
4047 astFactory.simpleIdentifier(getAndAdvance()), null);
4048 }
4024 Token next = _currentToken.next; 4049 Token next = _currentToken.next;
4025 if (_matchesIdentifier() && 4050 if (_matchesIdentifier() &&
4026 next.matchesAny(const <TokenType>[ 4051 next.matchesAny(const <TokenType>[
4027 TokenType.OPEN_PAREN, 4052 TokenType.OPEN_PAREN,
4028 TokenType.OPEN_CURLY_BRACKET, 4053 TokenType.OPEN_CURLY_BRACKET,
4029 TokenType.FUNCTION, 4054 TokenType.FUNCTION,
4030 TokenType.LT 4055 TokenType.LT
4031 ])) { 4056 ])) {
4032 return _parseFunctionDeclarationStatementAfterReturnType( 4057 return _parseFunctionDeclarationStatementAfterReturnType(
4033 commentAndMetadata, returnType); 4058 commentAndMetadata, returnType);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
4094 return astFactory.expressionStatement( 4119 return astFactory.expressionStatement(
4095 parseExpression2(), _expect(TokenType.SEMICOLON)); 4120 parseExpression2(), _expect(TokenType.SEMICOLON));
4096 } else { 4121 } else {
4097 // 4122 //
4098 // We have found an error of some kind. Try to recover. 4123 // We have found an error of some kind. Try to recover.
4099 // 4124 //
4100 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); 4125 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
4101 return astFactory 4126 return astFactory
4102 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); 4127 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
4103 } 4128 }
4129 } else if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
4130 TypeAnnotation returnType = parseTypeAnnotation(false);
4131 Token next = _currentToken.next;
4132 if (_matchesIdentifier() &&
4133 next.matchesAny(const <TokenType>[
4134 TokenType.OPEN_PAREN,
4135 TokenType.OPEN_CURLY_BRACKET,
4136 TokenType.FUNCTION,
4137 TokenType.LT
4138 ])) {
4139 return _parseFunctionDeclarationStatementAfterReturnType(
4140 commentAndMetadata, returnType);
4141 } else {
4142 //
4143 // We have found an error of some kind. Try to recover.
4144 //
4145 if (_matchesIdentifier()) {
4146 if (next.matchesAny(const <TokenType>[
4147 TokenType.EQ,
4148 TokenType.COMMA,
4149 TokenType.SEMICOLON
4150 ])) {
4151 //
4152 // We appear to have a variable declaration with a type of "void".
4153 //
4154 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
4155 return parseVariableDeclarationStatementAfterMetadata(
4156 commentAndMetadata);
4157 }
4158 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
4159 //
4160 // We appear to have found an incomplete statement at the end of a
4161 // block. Parse it as a variable declaration.
4162 //
4163 return _parseVariableDeclarationStatementAfterType(
4164 commentAndMetadata, null, returnType);
4165 }
4166 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
4167 // TODO(brianwilkerson) Recover from this error.
4168 return astFactory
4169 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
4170 }
4104 } else if (_inGenerator && _matchesKeyword(Keyword.YIELD)) { 4171 } else if (_inGenerator && _matchesKeyword(Keyword.YIELD)) {
4105 return parseYieldStatement(); 4172 return parseYieldStatement();
4106 } else if (_inAsync && _matchesKeyword(Keyword.AWAIT)) { 4173 } else if (_inAsync && _matchesKeyword(Keyword.AWAIT)) {
4107 if (_tokenMatchesKeyword(_peek(), Keyword.FOR)) { 4174 if (_tokenMatchesKeyword(_peek(), Keyword.FOR)) {
4108 return parseForStatement(); 4175 return parseForStatement();
4109 } 4176 }
4110 return astFactory.expressionStatement( 4177 return astFactory.expressionStatement(
4111 parseExpression2(), _expect(TokenType.SEMICOLON)); 4178 parseExpression2(), _expect(TokenType.SEMICOLON));
4112 } else if (_matchesKeyword(Keyword.AWAIT) && 4179 } else if (_matchesKeyword(Keyword.AWAIT) &&
4113 _tokenMatchesKeyword(_peek(), Keyword.FOR)) { 4180 _tokenMatchesKeyword(_peek(), Keyword.FOR)) {
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
4611 4678
4612 /** 4679 /**
4613 * Parse a return type. Return the return type that was parsed. 4680 * Parse a return type. Return the return type that was parsed.
4614 * 4681 *
4615 * returnType ::= 4682 * returnType ::=
4616 * 'void' 4683 * 'void'
4617 * | type 4684 * | type
4618 */ 4685 */
4619 TypeAnnotation parseReturnType(bool inExpression) { 4686 TypeAnnotation parseReturnType(bool inExpression) {
4620 if (_currentToken.keyword == Keyword.VOID) { 4687 if (_currentToken.keyword == Keyword.VOID) {
4621 return astFactory.typeName( 4688 if (_atGenericFunctionTypeAfterReturnType(_peek())) {
4622 astFactory.simpleIdentifier(getAndAdvance()), null); 4689 return parseTypeAnnotation(false);
4690 } else {
4691 return astFactory.typeName(
4692 astFactory.simpleIdentifier(getAndAdvance()), null);
4693 }
4623 } else { 4694 } else {
4624 return parseTypeAnnotation(inExpression); 4695 return parseTypeAnnotation(inExpression);
4625 } 4696 }
4626 } 4697 }
4627 4698
4628 /** 4699 /**
4629 * Parse a setter. The [commentAndMetadata] is the documentation comment and 4700 * Parse a setter. The [commentAndMetadata] is the documentation comment and
4630 * metadata to be associated with the declaration. The [externalKeyword] is 4701 * metadata to be associated with the declaration. The [externalKeyword] is
4631 * the 'external' token. The [staticKeyword] is the static keyword, or `null` 4702 * the 'external' token. The [staticKeyword] is the static keyword, or `null`
4632 * if the setter is not static. The [returnType] is the return type that has 4703 * if the setter is not static. The [returnType] is the return type that has
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
5473 * not the first token in a valid return type. 5544 * not the first token in a valid return type.
5474 * 5545 *
5475 * This method must be kept in sync with [parseReturnType]. 5546 * This method must be kept in sync with [parseReturnType].
5476 * 5547 *
5477 * returnType ::= 5548 * returnType ::=
5478 * 'void' 5549 * 'void'
5479 * | type 5550 * | type
5480 */ 5551 */
5481 Token skipReturnType(Token startToken) { 5552 Token skipReturnType(Token startToken) {
5482 if (_tokenMatchesKeyword(startToken, Keyword.VOID)) { 5553 if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
5554 if (_atGenericFunctionTypeAfterReturnType(_peek())) {
5555 return skipTypeAnnotation(startToken);
5556 }
5483 return startToken.next; 5557 return startToken.next;
5484 } else { 5558 } else {
5485 return skipTypeAnnotation(startToken); 5559 return skipTypeAnnotation(startToken);
5486 } 5560 }
5487 } 5561 }
5488 5562
5489 /** 5563 /**
5490 * Parse a simple identifier, starting at the [startToken], without actually 5564 * Parse a simple identifier, starting at the [startToken], without actually
5491 * creating a simple identifier or changing the current token. Return the 5565 * creating a simple identifier or changing the current token. Return the
5492 * token following the simple identifier that was parsed, or `null` if the 5566 * token following the simple identifier that was parsed, or `null` if the
(...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after
7141 * Parse a return type if one is given, otherwise return `null` without 7215 * Parse a return type if one is given, otherwise return `null` without
7142 * advancing. Return the return type that was parsed. 7216 * advancing. Return the return type that was parsed.
7143 */ 7217 */
7144 TypeAnnotation _parseOptionalReturnType() { 7218 TypeAnnotation _parseOptionalReturnType() {
7145 TypeName typeComment = _parseOptionalTypeNameComment(); 7219 TypeName typeComment = _parseOptionalTypeNameComment();
7146 if (typeComment != null) { 7220 if (typeComment != null) {
7147 return typeComment; 7221 return typeComment;
7148 } 7222 }
7149 Keyword keyword = _currentToken.keyword; 7223 Keyword keyword = _currentToken.keyword;
7150 if (keyword == Keyword.VOID) { 7224 if (keyword == Keyword.VOID) {
7225 if (_atGenericFunctionTypeAfterReturnType(_peek())) {
7226 return parseTypeAnnotation(false);
7227 }
7151 return astFactory.typeName( 7228 return astFactory.typeName(
7152 astFactory.simpleIdentifier(getAndAdvance()), null); 7229 astFactory.simpleIdentifier(getAndAdvance()), null);
7153 } else if (_matchesIdentifier()) { 7230 } else if (_matchesIdentifier()) {
7154 Token next = _peek(); 7231 Token next = _peek();
7155 if (keyword != Keyword.GET && 7232 if (keyword != Keyword.GET &&
7156 keyword != Keyword.SET && 7233 keyword != Keyword.SET &&
7157 keyword != Keyword.OPERATOR && 7234 keyword != Keyword.OPERATOR &&
7158 (_tokenMatchesIdentifier(next) || 7235 (_tokenMatchesIdentifier(next) ||
7159 _tokenMatches(next, TokenType.LT))) { 7236 _tokenMatches(next, TokenType.LT))) {
7160 Token afterTypeParameters = _skipTypeParameterList(next); 7237 Token afterTypeParameters = _skipTypeParameterList(next);
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
8480 } 8557 }
8481 if (modifiers.finalKeyword != null) { 8558 if (modifiers.finalKeyword != null) {
8482 _reportErrorForToken( 8559 _reportErrorForToken(
8483 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword); 8560 ParserErrorCode.FINAL_TYPEDEF, modifiers.finalKeyword);
8484 } 8561 }
8485 if (modifiers.varKeyword != null) { 8562 if (modifiers.varKeyword != null) {
8486 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword); 8563 _reportErrorForToken(ParserErrorCode.VAR_TYPEDEF, modifiers.varKeyword);
8487 } 8564 }
8488 } 8565 }
8489 } 8566 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698