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

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

Issue 1736873002: Improve parser recovery on missing semicolon (issue 25846) (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 0, (Parser target) => target._createSyntheticStringLiteral()), 118 0, (Parser target) => target._createSyntheticStringLiteral()),
119 'createSyntheticToken_1': new MethodTrampoline( 119 'createSyntheticToken_1': new MethodTrampoline(
120 1, (Parser target, arg0) => target._createSyntheticToken(arg0)), 120 1, (Parser target, arg0) => target._createSyntheticToken(arg0)),
121 'ensureAssignable_1': new MethodTrampoline( 121 'ensureAssignable_1': new MethodTrampoline(
122 1, (Parser target, arg0) => target._ensureAssignable(arg0)), 122 1, (Parser target, arg0) => target._ensureAssignable(arg0)),
123 'expect_1': 123 'expect_1':
124 new MethodTrampoline(1, (Parser target, arg0) => target._expect(arg0)), 124 new MethodTrampoline(1, (Parser target, arg0) => target._expect(arg0)),
125 'expectGt_0': new MethodTrampoline(0, (Parser target) => target._expectGt()), 125 'expectGt_0': new MethodTrampoline(0, (Parser target) => target._expectGt()),
126 'expectKeyword_1': new MethodTrampoline( 126 'expectKeyword_1': new MethodTrampoline(
127 1, (Parser target, arg0) => target._expectKeyword(arg0)), 127 1, (Parser target, arg0) => target._expectKeyword(arg0)),
128 'expectSemicolon_0':
129 new MethodTrampoline(0, (Parser target) => target._expectSemicolon()),
130 'findRange_2': new MethodTrampoline( 128 'findRange_2': new MethodTrampoline(
131 2, (Parser target, arg0, arg1) => target._findRange(arg0, arg1)), 129 2, (Parser target, arg0, arg1) => target._findRange(arg0, arg1)),
132 'getCodeBlockRanges_1': new MethodTrampoline( 130 'getCodeBlockRanges_1': new MethodTrampoline(
133 1, (Parser target, arg0) => target._getCodeBlockRanges(arg0)), 131 1, (Parser target, arg0) => target._getCodeBlockRanges(arg0)),
134 'getEndToken_1': new MethodTrampoline( 132 'getEndToken_1': new MethodTrampoline(
135 1, (Parser target, arg0) => target._getEndToken(arg0)), 133 1, (Parser target, arg0) => target._getEndToken(arg0)),
136 'injectToken_1': new MethodTrampoline( 134 'injectToken_1': new MethodTrampoline(
137 1, (Parser target, arg0) => target._injectToken(arg0)), 135 1, (Parser target, arg0) => target._injectToken(arg0)),
138 'isFunctionDeclaration_0': new MethodTrampoline( 136 'isFunctionDeclaration_0': new MethodTrampoline(
139 0, (Parser target) => target._isFunctionDeclaration()), 137 0, (Parser target) => target._isFunctionDeclaration()),
(...skipping 2363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 // 2501 //
2504 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); 2502 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
2505 List<VariableDeclaration> variables = new List<VariableDeclaration>(); 2503 List<VariableDeclaration> variables = new List<VariableDeclaration>();
2506 variables.add( 2504 variables.add(
2507 new VariableDeclaration(_createSyntheticIdentifier(), null, null)); 2505 new VariableDeclaration(_createSyntheticIdentifier(), null, null));
2508 return new FieldDeclaration( 2506 return new FieldDeclaration(
2509 commentAndMetadata.comment, 2507 commentAndMetadata.comment,
2510 commentAndMetadata.metadata, 2508 commentAndMetadata.metadata,
2511 null, 2509 null,
2512 new VariableDeclarationList(null, null, keyword, null, variables), 2510 new VariableDeclarationList(null, null, keyword, null, variables),
2513 _expectSemicolon()); 2511 _expect(TokenType.SEMICOLON));
2514 } 2512 }
2515 _reportErrorForToken( 2513 _reportErrorForToken(
2516 ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken); 2514 ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken);
2517 if (commentAndMetadata.comment != null || 2515 if (commentAndMetadata.comment != null ||
2518 !commentAndMetadata.metadata.isEmpty) { 2516 !commentAndMetadata.metadata.isEmpty) {
2519 // 2517 //
2520 // We appear to have found an incomplete declaration at the end of the 2518 // We appear to have found an incomplete declaration at the end of the
2521 // class. At this point it consists of a metadata, which we don't want 2519 // class. At this point it consists of a metadata, which we don't want
2522 // to loose, so we'll treat it as a method declaration with a missing 2520 // to loose, so we'll treat it as a method declaration with a missing
2523 // name, parameters and empty body. 2521 // name, parameters and empty body.
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
3790 // Pass in the error code to use to report the error? 3788 // Pass in the error code to use to report the error?
3791 if (type == TokenType.SEMICOLON) { 3789 if (type == TokenType.SEMICOLON) {
3792 if (_tokenMatches(_currentToken.next, TokenType.SEMICOLON)) { 3790 if (_tokenMatches(_currentToken.next, TokenType.SEMICOLON)) {
3793 _reportErrorForCurrentToken( 3791 _reportErrorForCurrentToken(
3794 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]); 3792 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
3795 _advance(); 3793 _advance();
3796 return getAndAdvance(); 3794 return getAndAdvance();
3797 } 3795 }
3798 _reportErrorForToken(ParserErrorCode.EXPECTED_TOKEN, 3796 _reportErrorForToken(ParserErrorCode.EXPECTED_TOKEN,
3799 _currentToken.previous, [type.lexeme]); 3797 _currentToken.previous, [type.lexeme]);
3800 } else { 3798 return _createSyntheticToken(TokenType.SEMICOLON);
3801 _reportErrorForCurrentToken(
3802 ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
3803 } 3799 }
3800 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]);
3804 return _currentToken; 3801 return _currentToken;
3805 } 3802 }
3806 3803
3807 /** 3804 /**
3808 * If the current token has the type [TokenType.GT], return it after advancing 3805 * If the current token has the type [TokenType.GT], return it after advancing
3809 * to the next token. Otherwise report an error and create a synthetic token. 3806 * to the next token. Otherwise report an error and create a synthetic token.
3810 */ 3807 */
3811 Token _expectGt() { 3808 Token _expectGt() {
3812 if (_matchesGt()) { 3809 if (_matchesGt()) {
3813 return getAndAdvance(); 3810 return getAndAdvance();
(...skipping 13 matching lines...) Expand all
3827 return getAndAdvance(); 3824 return getAndAdvance();
3828 } 3825 }
3829 // Remove uses of this method in favor of matches? 3826 // Remove uses of this method in favor of matches?
3830 // Pass in the error code to use to report the error? 3827 // Pass in the error code to use to report the error?
3831 _reportErrorForCurrentToken( 3828 _reportErrorForCurrentToken(
3832 ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]); 3829 ParserErrorCode.EXPECTED_TOKEN, [keyword.syntax]);
3833 return _currentToken; 3830 return _currentToken;
3834 } 3831 }
3835 3832
3836 /** 3833 /**
3837 * If the current token is a semicolon, return it after advancing to the next
3838 * token. Otherwise report an error and create a synthetic semicolon.
3839 */
3840 Token _expectSemicolon() {
3841 // TODO(scheglov) consider pushing this behavior into [_expect]
3842 if (_matches(TokenType.SEMICOLON)) {
3843 return getAndAdvance();
3844 } else {
3845 _reportErrorForToken(
3846 ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [";"]);
3847 return _createSyntheticToken(TokenType.SEMICOLON);
3848 }
3849 }
3850
3851 /**
3852 * Search the given list of [ranges] for a range that contains the given 3834 * Search the given list of [ranges] for a range that contains the given
3853 * [index]. Return the range that was found, or `null` if none of the ranges 3835 * [index]. Return the range that was found, or `null` if none of the ranges
3854 * contain the index. 3836 * contain the index.
3855 */ 3837 */
3856 List<int> _findRange(List<List<int>> ranges, int index) { 3838 List<int> _findRange(List<List<int>> ranges, int index) {
3857 int rangeCount = ranges.length; 3839 int rangeCount = ranges.length;
3858 for (int i = 0; i < rangeCount; i++) { 3840 for (int i = 0; i < rangeCount; i++) {
3859 List<int> range = ranges[i]; 3841 List<int> range = ranges[i];
3860 if (range[0] <= index && index <= range[1]) { 3842 if (range[0] <= index && index <= range[1]) {
3861 return range; 3843 return range;
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
5234 // We appear to have found an incomplete top-level variable declaration. 5216 // We appear to have found an incomplete top-level variable declaration.
5235 // 5217 //
5236 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); 5218 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
5237 List<VariableDeclaration> variables = new List<VariableDeclaration>(); 5219 List<VariableDeclaration> variables = new List<VariableDeclaration>();
5238 variables.add( 5220 variables.add(
5239 new VariableDeclaration(_createSyntheticIdentifier(), null, null)); 5221 new VariableDeclaration(_createSyntheticIdentifier(), null, null));
5240 return new TopLevelVariableDeclaration( 5222 return new TopLevelVariableDeclaration(
5241 commentAndMetadata.comment, 5223 commentAndMetadata.comment,
5242 commentAndMetadata.metadata, 5224 commentAndMetadata.metadata,
5243 new VariableDeclarationList(null, null, keyword, null, variables), 5225 new VariableDeclarationList(null, null, keyword, null, variables),
5244 _expectSemicolon()); 5226 _expect(TokenType.SEMICOLON));
5245 } 5227 }
5246 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); 5228 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken);
5247 return null; 5229 return null;
5248 } else if (_isPeekGenericTypeParametersAndOpenParen()) { 5230 } else if (_isPeekGenericTypeParametersAndOpenParen()) {
5249 return _parseFunctionDeclaration( 5231 return _parseFunctionDeclaration(
5250 commentAndMetadata, modifiers.externalKeyword, null); 5232 commentAndMetadata, modifiers.externalKeyword, null);
5251 } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) { 5233 } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
5252 TypeName returnType = _parseOptionalTypeNameComment(); 5234 TypeName returnType = _parseOptionalTypeNameComment();
5253 _validateModifiersForTopLevelFunction(modifiers); 5235 _validateModifiersForTopLevelFunction(modifiers);
5254 return _parseFunctionDeclaration( 5236 return _parseFunctionDeclaration(
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
5810 * associated with the directive. Return the export directive that was parsed. 5792 * associated with the directive. Return the export directive that was parsed.
5811 * 5793 *
5812 * exportDirective ::= 5794 * exportDirective ::=
5813 * metadata 'export' stringLiteral configuration* combinator*';' 5795 * metadata 'export' stringLiteral configuration* combinator*';'
5814 */ 5796 */
5815 ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) { 5797 ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
5816 Token exportKeyword = _expectKeyword(Keyword.EXPORT); 5798 Token exportKeyword = _expectKeyword(Keyword.EXPORT);
5817 StringLiteral libraryUri = _parseUri(); 5799 StringLiteral libraryUri = _parseUri();
5818 List<Configuration> configurations = _parseConfigurations(); 5800 List<Configuration> configurations = _parseConfigurations();
5819 List<Combinator> combinators = _parseCombinators(); 5801 List<Combinator> combinators = _parseCombinators();
5820 Token semicolon = _expectSemicolon(); 5802 Token semicolon = _expect(TokenType.SEMICOLON);
5821 return new ExportDirective( 5803 return new ExportDirective(
5822 commentAndMetadata.comment, 5804 commentAndMetadata.comment,
5823 commentAndMetadata.metadata, 5805 commentAndMetadata.metadata,
5824 exportKeyword, 5806 exportKeyword,
5825 libraryUri, 5807 libraryUri,
5826 configurations, 5808 configurations,
5827 combinators, 5809 combinators,
5828 semicolon); 5810 semicolon);
5829 } 5811 }
5830 5812
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
6033 inKeyword, 6015 inKeyword,
6034 iterator, 6016 iterator,
6035 rightParenthesis, 6017 rightParenthesis,
6036 body); 6018 body);
6037 } 6019 }
6038 } 6020 }
6039 if (awaitKeyword != null) { 6021 if (awaitKeyword != null) {
6040 _reportErrorForToken( 6022 _reportErrorForToken(
6041 ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword); 6023 ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword);
6042 } 6024 }
6043 Token leftSeparator = _expectSemicolon(); 6025 Token leftSeparator = _expect(TokenType.SEMICOLON);
6044 Expression condition = null; 6026 Expression condition = null;
6045 if (!_matches(TokenType.SEMICOLON)) { 6027 if (!_matches(TokenType.SEMICOLON)) {
6046 condition = parseExpression2(); 6028 condition = parseExpression2();
6047 } 6029 }
6048 Token rightSeparator = _expectSemicolon(); 6030 Token rightSeparator = _expect(TokenType.SEMICOLON);
6049 List<Expression> updaters = null; 6031 List<Expression> updaters = null;
6050 if (!_matches(TokenType.CLOSE_PAREN)) { 6032 if (!_matches(TokenType.CLOSE_PAREN)) {
6051 updaters = _parseExpressionList(); 6033 updaters = _parseExpressionList();
6052 } 6034 }
6053 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); 6035 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
6054 Statement body = parseStatement2(); 6036 Statement body = parseStatement2();
6055 return new ForStatement( 6037 return new ForStatement(
6056 forKeyword, 6038 forKeyword,
6057 leftParenthesis, 6039 leftParenthesis,
6058 variableList, 6040 variableList,
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
6513 _reportErrorForCurrentToken( 6495 _reportErrorForCurrentToken(
6514 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken]); 6496 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken]);
6515 _advance(); 6497 _advance();
6516 if (_matchesKeyword(Keyword.AS)) { 6498 if (_matchesKeyword(Keyword.AS)) {
6517 asToken = getAndAdvance(); 6499 asToken = getAndAdvance();
6518 prefix = parseSimpleIdentifier(); 6500 prefix = parseSimpleIdentifier();
6519 } 6501 }
6520 } 6502 }
6521 } 6503 }
6522 List<Combinator> combinators = _parseCombinators(); 6504 List<Combinator> combinators = _parseCombinators();
6523 Token semicolon = _expectSemicolon(); 6505 Token semicolon = _expect(TokenType.SEMICOLON);
6524 return new ImportDirective( 6506 return new ImportDirective(
6525 commentAndMetadata.comment, 6507 commentAndMetadata.comment,
6526 commentAndMetadata.metadata, 6508 commentAndMetadata.metadata,
6527 importKeyword, 6509 importKeyword,
6528 libraryUri, 6510 libraryUri,
6529 configurations, 6511 configurations,
6530 deferredToken, 6512 deferredToken,
6531 asToken, 6513 asToken,
6532 prefix, 6514 prefix,
6533 combinators, 6515 combinators,
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
7147 return _parseEmptyStatement(); 7129 return _parseEmptyStatement();
7148 } else if (_isInitializedVariableDeclaration()) { 7130 } else if (_isInitializedVariableDeclaration()) {
7149 return _parseVariableDeclarationStatementAfterMetadata( 7131 return _parseVariableDeclarationStatementAfterMetadata(
7150 commentAndMetadata); 7132 commentAndMetadata);
7151 } else if (_isFunctionDeclaration()) { 7133 } else if (_isFunctionDeclaration()) {
7152 return _parseFunctionDeclarationStatement(); 7134 return _parseFunctionDeclarationStatement();
7153 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { 7135 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
7154 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); 7136 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
7155 return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); 7137 return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
7156 } else { 7138 } else {
7157 return new ExpressionStatement(parseExpression2(), _expectSemicolon()); 7139 return new ExpressionStatement(
7140 parseExpression2(), _expect(TokenType.SEMICOLON));
7158 } 7141 }
7159 } 7142 }
7160 7143
7161 /** 7144 /**
7162 * Parse an operator declaration. The [commentAndMetadata] is the 7145 * Parse an operator declaration. The [commentAndMetadata] is the
7163 * documentation comment and metadata to be associated with the declaration. 7146 * documentation comment and metadata to be associated with the declaration.
7164 * The [externalKeyword] is the 'external' token. The [returnType] is the 7147 * The [externalKeyword] is the 'external' token. The [returnType] is the
7165 * return type that has already been parsed, or `null` if there was no return 7148 * return type that has already been parsed, or `null` if there was no return
7166 * type. Return the operator declaration that was parsed. 7149 * type. Return the operator declaration that was parsed.
7167 * 7150 *
(...skipping 4192 matching lines...) Expand 10 before | Expand all | Expand 10 after
11360 } 11343 }
11361 11344
11362 /** 11345 /**
11363 * Copy resolution data from the [fromNode] to the [toNode]. 11346 * Copy resolution data from the [fromNode] to the [toNode].
11364 */ 11347 */
11365 static void copyResolutionData(AstNode fromNode, AstNode toNode) { 11348 static void copyResolutionData(AstNode fromNode, AstNode toNode) {
11366 ResolutionCopier copier = new ResolutionCopier(); 11349 ResolutionCopier copier = new ResolutionCopier();
11367 copier._isEqualNodes(fromNode, toNode); 11350 copier._isEqualNodes(fromNode, toNode);
11368 } 11351 }
11369 } 11352 }
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