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

Side by Side Diff: pkg/front_end/lib/src/fasta/parser/parser.dart

Issue 2759623003: Track async state in parser. (Closed)
Patch Set: Created 3 years, 9 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 fasta.parser.parser; 5 library fasta.parser.parser;
6 6
7 import '../scanner.dart' show ErrorToken; 7 import '../scanner.dart' show ErrorToken;
8 8
9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; 9 import '../scanner/recover.dart' show closeBraceFor, skipToEof;
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 PERIOD_TOKEN, 59 PERIOD_TOKEN,
60 SEMICOLON_TOKEN, 60 SEMICOLON_TOKEN,
61 STRING_INTERPOLATION_IDENTIFIER_TOKEN, 61 STRING_INTERPOLATION_IDENTIFIER_TOKEN,
62 STRING_INTERPOLATION_TOKEN, 62 STRING_INTERPOLATION_TOKEN,
63 STRING_TOKEN; 63 STRING_TOKEN;
64 64
65 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET; 65 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET;
66 66
67 import '../util/link.dart' show Link; 67 import '../util/link.dart' show Link;
68 68
69 import 'async_modifier.dart' show AsyncModifier;
70
69 import 'listener.dart' show Listener; 71 import 'listener.dart' show Listener;
70 72
71 import 'error_kind.dart' show ErrorKind; 73 import 'error_kind.dart' show ErrorKind;
72 74
73 import 'identifier_context.dart' show IdentifierContext; 75 import 'identifier_context.dart' show IdentifierContext;
74 76
75 /// Returns true if [token] is the symbol or keyword [value]. 77 /// Returns true if [token] is the symbol or keyword [value].
76 bool optional(String value, Token token) { 78 bool optional(String value, Token token) {
77 return identical(value, token.stringValue); 79 return identical(value, token.stringValue);
78 } 80 }
(...skipping 30 matching lines...) Expand all
109 * suffix can be one of "opt", or "star". "opt" means zero or one 111 * suffix can be one of "opt", or "star". "opt" means zero or one
110 * matches, "star" means zero or more matches. For example, 112 * matches, "star" means zero or more matches. For example,
111 * [parseMetadataStar] corresponds to this grammar snippet: [: 113 * [parseMetadataStar] corresponds to this grammar snippet: [:
112 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. 114 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :].
113 */ 115 */
114 class Parser { 116 class Parser {
115 final Listener listener; 117 final Listener listener;
116 118
117 bool mayParseFunctionExpressions = true; 119 bool mayParseFunctionExpressions = true;
118 120
119 bool asyncAwaitKeywordsEnabled; 121 /// Represents parser state: what asynchronous syntax is allowed in the
122 /// function being currently parsed. In rare situations, this can be set by
123 /// external clients, for example, to parse an expression outside a function.
124 AsyncModifier asyncState = AsyncModifier.Sync;
120 125
121 Parser(this.listener, {this.asyncAwaitKeywordsEnabled: false}); 126 Parser(this.listener);
127
128 bool get inGenerator {
129 return asyncState == AsyncModifier.AsyncStar ||
130 asyncState == AsyncModifier.SyncStar;
131 }
132
133 bool get inAsync {
134 return asyncState == AsyncModifier.Async ||
135 asyncState == AsyncModifier.AsyncStar;
136 }
122 137
123 Token parseUnit(Token token) { 138 Token parseUnit(Token token) {
124 listener.beginCompilationUnit(token); 139 listener.beginCompilationUnit(token);
125 int count = 0; 140 int count = 0;
126 while (!identical(token.kind, EOF_TOKEN)) { 141 while (!identical(token.kind, EOF_TOKEN)) {
127 token = parseTopLevelDeclaration(token); 142 token = parseTopLevelDeclaration(token);
128 count++; 143 count++;
129 } 144 }
130 listener.endCompilationUnit(count, token); 145 listener.endCompilationUnit(count, token);
131 return token; 146 return token;
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 } 1307 }
1293 Token token = 1308 Token token =
1294 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); 1309 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration);
1295 1310
1296 if (getOrSet == null) { 1311 if (getOrSet == null) {
1297 token = parseTypeVariablesOpt(token); 1312 token = parseTypeVariablesOpt(token);
1298 } else { 1313 } else {
1299 listener.handleNoTypeVariables(token); 1314 listener.handleNoTypeVariables(token);
1300 } 1315 }
1301 token = parseFormalParametersOpt(token); 1316 token = parseFormalParametersOpt(token);
1302 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1317 AsyncModifier savedAsyncModifier = asyncState;
1303 token = parseAsyncModifier(token); 1318 token = parseAsyncModifier(token);
1304 token = parseFunctionBody(token, false, externalModifier != null); 1319 token = parseFunctionBody(token, false, externalModifier != null);
1305 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1320 asyncState = savedAsyncModifier;
1306 Token endToken = token; 1321 Token endToken = token;
1307 token = token.next; 1322 token = token.next;
1308 listener.endTopLevelMethod(start, getOrSet, endToken); 1323 listener.endTopLevelMethod(start, getOrSet, endToken);
1309 return token; 1324 return token;
1310 } 1325 }
1311 1326
1312 /// Looks ahead to find the name of a member. Returns a link of the modifiers, 1327 /// Looks ahead to find the name of a member. Returns a link of the modifiers,
1313 /// set/get, (operator) name, and either the start of the method body or the 1328 /// set/get, (operator) name, and either the start of the method body or the
1314 /// end of the declaration. 1329 /// end of the declaration.
1315 /// 1330 ///
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 1865
1851 token = parseQualifiedRestOpt( 1866 token = parseQualifiedRestOpt(
1852 token, IdentifierContext.methodDeclarationContinuation); 1867 token, IdentifierContext.methodDeclarationContinuation);
1853 if (getOrSet == null) { 1868 if (getOrSet == null) {
1854 token = parseTypeVariablesOpt(token); 1869 token = parseTypeVariablesOpt(token);
1855 } else { 1870 } else {
1856 listener.handleNoTypeVariables(token); 1871 listener.handleNoTypeVariables(token);
1857 } 1872 }
1858 token = parseFormalParametersOpt(token); 1873 token = parseFormalParametersOpt(token);
1859 token = parseInitializersOpt(token); 1874 token = parseInitializersOpt(token);
1860 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1875 AsyncModifier savedAsyncModifier = asyncState;
1861 token = parseAsyncModifier(token); 1876 token = parseAsyncModifier(token);
1862 if (optional('=', token)) { 1877 if (optional('=', token)) {
1863 token = parseRedirectingFactoryBody(token); 1878 token = parseRedirectingFactoryBody(token);
1864 } else { 1879 } else {
1865 token = parseFunctionBody( 1880 token = parseFunctionBody(
1866 token, false, staticModifier == null || externalModifier != null); 1881 token, false, staticModifier == null || externalModifier != null);
1867 } 1882 }
1868 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1883 asyncState = savedAsyncModifier;
1869 listener.endMethod(getOrSet, start, token); 1884 listener.endMethod(getOrSet, start, token);
1870 return token.next; 1885 return token.next;
1871 } 1886 }
1872 1887
1873 Token parseFactoryMethod(Token token) { 1888 Token parseFactoryMethod(Token token) {
1874 assert(isFactoryDeclaration(token)); 1889 assert(isFactoryDeclaration(token));
1875 Token start = token; 1890 Token start = token;
1876 bool isExternal = false; 1891 bool isExternal = false;
1877 int modifierCount = 0; 1892 int modifierCount = 0;
1878 while (isModifier(token)) { 1893 while (isModifier(token)) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 token = parseQualifiedRestOpt( 1961 token = parseQualifiedRestOpt(
1947 token, IdentifierContext.localFunctionDeclarationContinuation); 1962 token, IdentifierContext.localFunctionDeclarationContinuation);
1948 listener.endFunctionName(token); 1963 listener.endFunctionName(token);
1949 if (getOrSet == null) { 1964 if (getOrSet == null) {
1950 token = parseTypeVariablesOpt(token); 1965 token = parseTypeVariablesOpt(token);
1951 } else { 1966 } else {
1952 listener.handleNoTypeVariables(token); 1967 listener.handleNoTypeVariables(token);
1953 } 1968 }
1954 token = parseFormalParametersOpt(token); 1969 token = parseFormalParametersOpt(token);
1955 token = parseInitializersOpt(token); 1970 token = parseInitializersOpt(token);
1956 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1971 AsyncModifier savedAsyncModifier = asyncState;
1957 token = parseAsyncModifier(token); 1972 token = parseAsyncModifier(token);
1958 token = parseFunctionBody(token, false, true); 1973 token = parseFunctionBody(token, false, true);
1959 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1974 asyncState = savedAsyncModifier;
1960 listener.endFunction(getOrSet, token); 1975 listener.endFunction(getOrSet, token);
1961 return token.next; 1976 return token.next;
1962 } 1977 }
1963 1978
1964 Token parseUnnamedFunction(Token token) { 1979 Token parseUnnamedFunction(Token token) {
1965 listener.beginUnnamedFunction(token); 1980 listener.beginUnnamedFunction(token);
1966 token = parseFormalParameters(token); 1981 token = parseFormalParameters(token);
1967 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1982 AsyncModifier savedAsyncModifier = asyncState;
1968 token = parseAsyncModifier(token); 1983 token = parseAsyncModifier(token);
1969 bool isBlock = optional('{', token); 1984 bool isBlock = optional('{', token);
1970 token = parseFunctionBody(token, true, false); 1985 token = parseFunctionBody(token, true, false);
1971 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1986 asyncState = savedAsyncModifier;
1972 listener.endUnnamedFunction(token); 1987 listener.endUnnamedFunction(token);
1973 return isBlock ? token.next : token; 1988 return isBlock ? token.next : token;
1974 } 1989 }
1975 1990
1976 Token parseFunctionDeclaration(Token token) { 1991 Token parseFunctionDeclaration(Token token) {
1977 listener.beginFunctionDeclaration(token); 1992 listener.beginFunctionDeclaration(token);
1978 token = parseFunction(token, null); 1993 token = parseFunction(token, null);
1979 listener.endFunctionDeclaration(token); 1994 listener.endFunctionDeclaration(token);
1980 return token; 1995 return token;
1981 } 1996 }
1982 1997
1983 Token parseFunctionExpression(Token token) { 1998 Token parseFunctionExpression(Token token) {
1984 listener.beginFunction(token); 1999 listener.beginFunction(token);
1985 listener.handleModifiers(0); 2000 listener.handleModifiers(0);
1986 token = parseReturnTypeOpt(token); 2001 token = parseReturnTypeOpt(token);
1987 listener.beginFunctionName(token); 2002 listener.beginFunctionName(token);
1988 token = parseIdentifier(token, IdentifierContext.functionExpressionName); 2003 token = parseIdentifier(token, IdentifierContext.functionExpressionName);
1989 listener.endFunctionName(token); 2004 listener.endFunctionName(token);
1990 token = parseTypeVariablesOpt(token); 2005 token = parseTypeVariablesOpt(token);
1991 token = parseFormalParameters(token); 2006 token = parseFormalParameters(token);
1992 listener.handleNoInitializers(); 2007 listener.handleNoInitializers();
1993 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 2008 AsyncModifier savedAsyncModifier = asyncState;
1994 token = parseAsyncModifier(token); 2009 token = parseAsyncModifier(token);
1995 bool isBlock = optional('{', token); 2010 bool isBlock = optional('{', token);
1996 token = parseFunctionBody(token, true, false); 2011 token = parseFunctionBody(token, true, false);
1997 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 2012 asyncState = savedAsyncModifier;
1998 listener.endFunction(null, token); 2013 listener.endFunction(null, token);
1999 return isBlock ? token.next : token; 2014 return isBlock ? token.next : token;
2000 } 2015 }
2001 2016
2002 Token parseConstructorReference(Token token) { 2017 Token parseConstructorReference(Token token) {
2003 Token start = token; 2018 Token start = token;
2004 listener.beginConstructorReference(start); 2019 listener.beginConstructorReference(start);
2005 token = parseIdentifier(token, IdentifierContext.constructorReference); 2020 token = parseIdentifier(token, IdentifierContext.constructorReference);
2006 token = parseQualifiedRestOpt( 2021 token = parseQualifiedRestOpt(
2007 token, IdentifierContext.constructorReferenceContinuation); 2022 token, IdentifierContext.constructorReferenceContinuation);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 if (identical(value, '*')) { 2138 if (identical(value, '*')) {
2124 token = token.next; 2139 token = token.next;
2125 } 2140 }
2126 } 2141 }
2127 return token; 2142 return token;
2128 } 2143 }
2129 2144
2130 Token parseAsyncModifier(Token token) { 2145 Token parseAsyncModifier(Token token) {
2131 Token async; 2146 Token async;
2132 Token star; 2147 Token star;
2133 asyncAwaitKeywordsEnabled = false; 2148 asyncState = AsyncModifier.Sync;
2134 if (optional('async', token)) { 2149 if (optional('async', token)) {
2135 asyncAwaitKeywordsEnabled = true;
2136 async = token; 2150 async = token;
2137 token = token.next; 2151 token = token.next;
2138 if (optional('*', token)) { 2152 if (optional('*', token)) {
2153 asyncState = AsyncModifier.AsyncStar;
2139 star = token; 2154 star = token;
2140 token = token.next; 2155 token = token.next;
2156 } else {
2157 asyncState = AsyncModifier.Async;
2141 } 2158 }
2142 } else if (optional('sync', token)) { 2159 } else if (optional('sync', token)) {
2143 async = token; 2160 async = token;
2144 token = token.next; 2161 token = token.next;
2145 if (optional('*', token)) { 2162 if (optional('*', token)) {
2146 asyncAwaitKeywordsEnabled = true; 2163 asyncState = AsyncModifier.SyncStar;
2147 star = token; 2164 star = token;
2148 token = token.next; 2165 token = token.next;
2149 } else { 2166 } else {
2150 reportRecoverableError(async, ErrorKind.InvalidSyncModifier); 2167 reportRecoverableError(async, ErrorKind.InvalidSyncModifier);
2151 } 2168 }
2152 } 2169 }
2153 listener.handleAsyncModifier(async, star); 2170 listener.handleAsyncModifier(async, star);
2154 return token; 2171 return token;
2155 } 2172 }
2156 2173
(...skipping 15 matching lines...) Expand all
2172 if (identical(token.kind, IDENTIFIER_TOKEN)) { 2189 if (identical(token.kind, IDENTIFIER_TOKEN)) {
2173 return parseExpressionStatementOrDeclaration(token); 2190 return parseExpressionStatementOrDeclaration(token);
2174 } else if (identical(value, '{')) { 2191 } else if (identical(value, '{')) {
2175 return parseBlock(token); 2192 return parseBlock(token);
2176 } else if (identical(value, 'return')) { 2193 } else if (identical(value, 'return')) {
2177 return parseReturnStatement(token); 2194 return parseReturnStatement(token);
2178 } else if (identical(value, 'var') || identical(value, 'final')) { 2195 } else if (identical(value, 'var') || identical(value, 'final')) {
2179 return parseVariablesDeclaration(token); 2196 return parseVariablesDeclaration(token);
2180 } else if (identical(value, 'if')) { 2197 } else if (identical(value, 'if')) {
2181 return parseIfStatement(token); 2198 return parseIfStatement(token);
2182 } else if (asyncAwaitKeywordsEnabled && identical(value, 'await')) { 2199 } else if (asyncState != AsyncModifier.Sync && identical(value, 'await')) {
2183 if (identical(token.next.stringValue, 'for')) { 2200 if (identical(token.next.stringValue, 'for')) {
2184 return parseForStatement(token, token.next); 2201 return parseForStatement(token, token.next);
2185 } else { 2202 } else {
2186 return parseExpressionStatement(token); 2203 return parseExpressionStatement(token);
2187 } 2204 }
2188 } else if (identical(value, 'for')) { 2205 } else if (identical(value, 'for')) {
2189 return parseForStatement(null, token); 2206 return parseForStatement(null, token);
2190 } else if (identical(value, 'rethrow')) { 2207 } else if (identical(value, 'rethrow')) {
2191 return parseRethrowStatement(token); 2208 return parseRethrowStatement(token);
2192 } else if (identical(value, 'throw') && optional(';', token.next)) { 2209 } else if (identical(value, 'throw') && optional(';', token.next)) {
(...skipping 10 matching lines...) Expand all
2203 } else if (identical(value, 'switch')) { 2220 } else if (identical(value, 'switch')) {
2204 return parseSwitchStatement(token); 2221 return parseSwitchStatement(token);
2205 } else if (identical(value, 'break')) { 2222 } else if (identical(value, 'break')) {
2206 return parseBreakStatement(token); 2223 return parseBreakStatement(token);
2207 } else if (identical(value, 'continue')) { 2224 } else if (identical(value, 'continue')) {
2208 return parseContinueStatement(token); 2225 return parseContinueStatement(token);
2209 } else if (identical(value, 'assert')) { 2226 } else if (identical(value, 'assert')) {
2210 return parseAssertStatement(token); 2227 return parseAssertStatement(token);
2211 } else if (identical(value, ';')) { 2228 } else if (identical(value, ';')) {
2212 return parseEmptyStatement(token); 2229 return parseEmptyStatement(token);
2213 } else if (asyncAwaitKeywordsEnabled && identical(value, 'yield')) { 2230 } else if (asyncState != AsyncModifier.Sync && identical(value, 'yield')) {
2214 return parseYieldStatement(token); 2231 return parseYieldStatement(token);
2215 } else if (identical(value, 'const')) { 2232 } else if (identical(value, 'const')) {
2216 return parseExpressionStatementOrConstDeclaration(token); 2233 return parseExpressionStatementOrConstDeclaration(token);
2217 } else if (token.isIdentifier()) { 2234 } else if (token.isIdentifier()) {
2218 return parseExpressionStatementOrDeclaration(token); 2235 return parseExpressionStatementOrDeclaration(token);
2219 } else { 2236 } else {
2220 return parseExpressionStatement(token); 2237 return parseExpressionStatement(token);
2221 } 2238 }
2222 } 2239 }
2223 2240
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 token = parseExpressionWithoutCascade(token.next); 2623 token = parseExpressionWithoutCascade(token.next);
2607 listener.handleAssignmentExpression(assignment); 2624 listener.handleAssignmentExpression(assignment);
2608 } 2625 }
2609 listener.endCascade(); 2626 listener.endCascade();
2610 return token; 2627 return token;
2611 } 2628 }
2612 2629
2613 Token parseUnaryExpression(Token token, bool allowCascades) { 2630 Token parseUnaryExpression(Token token, bool allowCascades) {
2614 String value = token.stringValue; 2631 String value = token.stringValue;
2615 // Prefix: 2632 // Prefix:
2616 if (asyncAwaitKeywordsEnabled && optional('await', token)) { 2633 if (asyncState != AsyncModifier.Sync && optional('await', token)) {
2617 return parseAwaitExpression(token, allowCascades); 2634 return parseAwaitExpression(token, allowCascades);
2618 } else if (identical(value, '+')) { 2635 } else if (identical(value, '+')) {
2619 // Dart no longer allows prefix-plus. 2636 // Dart no longer allows prefix-plus.
2620 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); 2637 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus);
2621 return parseUnaryExpression(token.next, allowCascades); 2638 return parseUnaryExpression(token.next, allowCascades);
2622 } else if ((identical(value, '!')) || 2639 } else if ((identical(value, '!')) ||
2623 (identical(value, '-')) || 2640 (identical(value, '-')) ||
2624 (identical(value, '~'))) { 2641 (identical(value, '~'))) {
2625 Token operator = token; 2642 Token operator = token;
2626 // Right associative, so we recurse at the same precedence 2643 // Right associative, so we recurse at the same precedence
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2685 } else if (value == 'this') { 2702 } else if (value == 'this') {
2686 return parseThisExpression(token); 2703 return parseThisExpression(token);
2687 } else if (value == 'super') { 2704 } else if (value == 'super') {
2688 return parseSuperExpression(token); 2705 return parseSuperExpression(token);
2689 } else if (value == 'new') { 2706 } else if (value == 'new') {
2690 return parseNewExpression(token); 2707 return parseNewExpression(token);
2691 } else if (value == 'const') { 2708 } else if (value == 'const') {
2692 return parseConstExpression(token); 2709 return parseConstExpression(token);
2693 } else if (value == 'void') { 2710 } else if (value == 'void') {
2694 return parseFunctionExpression(token); 2711 return parseFunctionExpression(token);
2695 } else if (asyncAwaitKeywordsEnabled && 2712 } else if (asyncState != AsyncModifier.Sync &&
2696 (value == 'yield' || value == 'async')) { 2713 (value == 'yield' || value == 'async')) {
2697 return expressionExpected(token); 2714 return expressionExpected(token);
2698 } else if (token.isIdentifier()) { 2715 } else if (token.isIdentifier()) {
2699 return parseSendOrFunctionLiteral(token); 2716 return parseSendOrFunctionLiteral(token);
2700 } else { 2717 } else {
2701 return expressionExpected(token); 2718 return expressionExpected(token);
2702 } 2719 }
2703 } else if (kind == OPEN_PAREN_TOKEN) { 2720 } else if (kind == OPEN_PAREN_TOKEN) {
2704 return parseParenthesizedExpressionOrFunctionLiteral(token); 2721 return parseParenthesizedExpressionOrFunctionLiteral(token);
2705 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || token.stringValue == '[]') { 2722 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || token.stringValue == '[]') {
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
3626 break; 3643 break;
3627 } 3644 }
3628 if (isRecoverable) { 3645 if (isRecoverable) {
3629 listener.handleRecoverableError(token, kind, arguments); 3646 listener.handleRecoverableError(token, kind, arguments);
3630 return null; 3647 return null;
3631 } else { 3648 } else {
3632 return listener.handleUnrecoverableError(token, kind, arguments); 3649 return listener.handleUnrecoverableError(token, kind, arguments);
3633 } 3650 }
3634 } 3651 }
3635 } 3652 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/class_member_parser.dart ('k') | pkg/front_end/lib/src/fasta/parser/top_level_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698