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

Side by Side Diff: pkg/compiler/lib/src/parser/parser.dart

Issue 1878253002: Adds support for remaining generic method syntax constructs. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Review 2 response Created 4 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
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 dart2js.parser; 5 library dart2js.parser;
6 6
7 import '../options.dart' show ParserOptions; 7 import '../options.dart' show ParserOptions;
8 import '../common.dart'; 8 import '../common.dart';
9 import '../tokens/keyword.dart' show Keyword; 9 import '../tokens/keyword.dart' show Keyword;
10 import '../tokens/precedence.dart' show PrecedenceInfo; 10 import '../tokens/precedence.dart' show PrecedenceInfo;
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 token = parseReturnTypeOpt(token); 456 token = parseReturnTypeOpt(token);
457 Token thisKeyword = null; 457 Token thisKeyword = null;
458 if (optional('this', token)) { 458 if (optional('this', token)) {
459 thisKeyword = token; 459 thisKeyword = token;
460 // TODO(ahe): Validate field initializers are only used in 460 // TODO(ahe): Validate field initializers are only used in
461 // constructors, and not for function-typed arguments. 461 // constructors, and not for function-typed arguments.
462 token = expect('.', token.next); 462 token = expect('.', token.next);
463 } 463 }
464 token = parseIdentifier(token); 464 token = parseIdentifier(token);
465 if (optional('(', token)) { 465 if (optional('(', token)) {
466 listener.handleNoTypeVariables(token);
467 token = parseFormalParameters(token);
468 listener.handleFunctionTypedFormalParameter(token);
469 } else if (enableGenericMethodSyntax && optional('<', token)) {
470 token = parseTypeVariablesOpt(token);
466 token = parseFormalParameters(token); 471 token = parseFormalParameters(token);
467 listener.handleFunctionTypedFormalParameter(token); 472 listener.handleFunctionTypedFormalParameter(token);
468 } 473 }
469 String value = token.stringValue; 474 String value = token.stringValue;
470 if ((identical('=', value)) || (identical(':', value))) { 475 if ((identical('=', value)) || (identical(':', value))) {
471 // TODO(ahe): Validate that these are only used for optional parameters. 476 // TODO(ahe): Validate that these are only used for optional parameters.
472 Token equal = token; 477 Token equal = token;
473 token = parseExpression(token.next); 478 token = parseExpression(token.next);
474 listener.handleValuedFormalParameter(equal, token); 479 listener.handleValuedFormalParameter(equal, token);
475 if (type.isRequired) { 480 if (type.isRequired) {
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 Token expect(String string, Token token) { 765 Token expect(String string, Token token) {
761 if (!identical(string, token.stringValue)) { 766 if (!identical(string, token.stringValue)) {
762 return listener.expected(string, token); 767 return listener.expected(string, token);
763 } 768 }
764 return token.next; 769 return token.next;
765 } 770 }
766 771
767 Token parseTypeVariable(Token token) { 772 Token parseTypeVariable(Token token) {
768 listener.beginTypeVariable(token); 773 listener.beginTypeVariable(token);
769 token = parseIdentifier(token); 774 token = parseIdentifier(token);
770 if (optional('extends', token)) { 775 Token extendsOrSuper = null;
776 if (optional('extends', token) ||
777 (enableGenericMethodSyntax && optional('super', token))) {
778 extendsOrSuper = token;
771 token = parseType(token.next); 779 token = parseType(token.next);
772 } else { 780 } else {
773 listener.handleNoType(token); 781 listener.handleNoType(token);
774 } 782 }
775 listener.endTypeVariable(token); 783 listener.endTypeVariable(token, extendsOrSuper);
776 return token; 784 return token;
777 } 785 }
778 786
779 /** 787 /**
780 * Returns true if the stringValue of the [token] is [value]. 788 * Returns true if the stringValue of the [token] is [value].
781 */ 789 */
782 bool optional(String value, Token token) { 790 bool optional(String value, Token token) {
783 return identical(value, token.stringValue); 791 return identical(value, token.stringValue);
784 } 792 }
785 793
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 int afterIdKind = afterId.kind; 1846 int afterIdKind = afterId.kind;
1839 if (identical(afterIdKind, EQ_TOKEN) || 1847 if (identical(afterIdKind, EQ_TOKEN) ||
1840 identical(afterIdKind, SEMICOLON_TOKEN) || 1848 identical(afterIdKind, SEMICOLON_TOKEN) ||
1841 identical(afterIdKind, COMMA_TOKEN)) { 1849 identical(afterIdKind, COMMA_TOKEN)) {
1842 // We are looking at "type identifier" followed by '=', ';', ','. 1850 // We are looking at "type identifier" followed by '=', ';', ','.
1843 return parseVariablesDeclaration(token); 1851 return parseVariablesDeclaration(token);
1844 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { 1852 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
1845 // We are looking at "type identifier '('". 1853 // We are looking at "type identifier '('".
1846 BeginGroupToken beginParen = afterId; 1854 BeginGroupToken beginParen = afterId;
1847 Token endParen = beginParen.endGroup; 1855 Token endParen = beginParen.endGroup;
1856 // TODO(eernst): Check for NPE as described in issue 26252.
1848 Token afterParens = endParen.next; 1857 Token afterParens = endParen.next;
1849 if (optional('{', afterParens) || 1858 if (optional('{', afterParens) ||
1850 optional('=>', afterParens) || 1859 optional('=>', afterParens) ||
1851 optional('async', afterParens) || 1860 optional('async', afterParens) ||
1852 optional('sync', afterParens)) { 1861 optional('sync', afterParens)) {
1853 // We are looking at "type identifier '(' ... ')'" followed 1862 // We are looking at "type identifier '(' ... ')'" followed
1854 // by '=>' or '{'. 1863 // by '{', '=>', 'async', or 'sync'.
1855 return parseFunctionDeclaration(token); 1864 return parseFunctionDeclaration(token);
1856 } 1865 }
1866 } else if (enableGenericMethodSyntax &&
1867 identical(afterIdKind, LT_TOKEN)) {
1868 // We are looking at "type identifier '<'".
1869 BeginGroupToken beginAngle = afterId;
1870 Token endAngle = beginAngle.endGroup;
1871 if (endAngle != null &&
1872 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
1873 BeginGroupToken beginParen = endAngle.next;
1874 Token endParen = beginParen.endGroup;
1875 if (endParen != null) {
1876 Token afterParens = endParen.next;
1877 if (optional('{', afterParens) ||
1878 optional('=>', afterParens) ||
1879 optional('async', afterParens) ||
1880 optional('sync', afterParens)) {
1881 // We are looking at "type identifier '<' ... '>' '(' ... ')'"
1882 // followed by '{', '=>', 'async', or 'sync'.
1883 return parseFunctionDeclaration(token);
1884 }
1885 }
1886 }
1857 } 1887 }
1858 // Fall-through to expression statement. 1888 // Fall-through to expression statement.
1859 } else { 1889 } else {
1860 if (optional(':', token.next)) { 1890 if (optional(':', token.next)) {
1861 return parseLabeledStatement(token); 1891 return parseLabeledStatement(token);
1862 } else if (optional('(', token.next)) { 1892 } else if (optional('(', token.next)) {
1863 BeginGroupToken begin = token.next; 1893 BeginGroupToken begin = token.next;
1894 // TODO(eernst): Check for NPE as described in issue 26252.
1864 String afterParens = begin.endGroup.next.stringValue; 1895 String afterParens = begin.endGroup.next.stringValue;
1865 if (identical(afterParens, '{') || 1896 if (identical(afterParens, '{') ||
1866 identical(afterParens, '=>') || 1897 identical(afterParens, '=>') ||
1867 identical(afterParens, 'async') || 1898 identical(afterParens, 'async') ||
1868 identical(afterParens, 'sync')) { 1899 identical(afterParens, 'sync')) {
1869 return parseFunctionDeclaration(token); 1900 return parseFunctionDeclaration(token);
1870 } 1901 }
1902 } else if (enableGenericMethodSyntax && optional('<', token.next)) {
1903 BeginGroupToken beginAngle = token.next;
1904 Token endAngle = beginAngle.endGroup;
1905 if (endAngle != null &&
1906 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
1907 BeginGroupToken beginParen = endAngle.next;
1908 Token endParen = beginParen.endGroup;
1909 if (endParen != null) {
1910 String afterParens = endParen.next.stringValue;
1911 if (identical(afterParens, '{') ||
1912 identical(afterParens, '=>') ||
1913 identical(afterParens, 'async') ||
1914 identical(afterParens, 'sync')) {
1915 return parseFunctionDeclaration(token);
1916 }
1917 }
1918 }
1919 // Fall through to expression statement.
1871 } 1920 }
1872 } 1921 }
1873 return parseExpressionStatement(token); 1922 return parseExpressionStatement(token);
1874 } 1923 }
1875 1924
1876 Token parseExpressionStatementOrConstDeclaration(Token token) { 1925 Token parseExpressionStatementOrConstDeclaration(Token token) {
1877 assert(identical(token.stringValue, 'const')); 1926 assert(identical(token.stringValue, 'const'));
1878 if (isModifier(token.next)) { 1927 if (isModifier(token.next)) {
1879 return parseVariablesDeclaration(token); 1928 return parseVariablesDeclaration(token);
1880 } 1929 }
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 } else if (asyncAwaitKeywordsEnabled && 2177 } else if (asyncAwaitKeywordsEnabled &&
2129 (value == 'yield' || value == 'async')) { 2178 (value == 'yield' || value == 'async')) {
2130 return listener.expectedExpression(token); 2179 return listener.expectedExpression(token);
2131 } else if (token.isIdentifier()) { 2180 } else if (token.isIdentifier()) {
2132 return parseSendOrFunctionLiteral(token); 2181 return parseSendOrFunctionLiteral(token);
2133 } else { 2182 } else {
2134 return listener.expectedExpression(token); 2183 return listener.expectedExpression(token);
2135 } 2184 }
2136 } else if (kind == OPEN_PAREN_TOKEN) { 2185 } else if (kind == OPEN_PAREN_TOKEN) {
2137 return parseParenthesizedExpressionOrFunctionLiteral(token); 2186 return parseParenthesizedExpressionOrFunctionLiteral(token);
2138 } else if ((kind == LT_TOKEN) || 2187 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || token.stringValue == '[]') {
2139 (kind == OPEN_SQUARE_BRACKET_TOKEN) || 2188 listener.handleNoTypeArguments(token);
2140 (kind == OPEN_CURLY_BRACKET_TOKEN) || 2189 return parseLiteralListSuffix(token, null);
2141 token.stringValue == '[]') { 2190 } else if (kind == OPEN_CURLY_BRACKET_TOKEN) {
2142 return parseLiteralListOrMap(token); 2191 listener.handleNoTypeArguments(token);
2192 return parseLiteralMapSuffix(token, null);
2193 } else if (kind == LT_TOKEN) {
2194 return parseLiteralListOrMapOrFunction(token, null);
2143 } else { 2195 } else {
2144 return listener.expectedExpression(token); 2196 return listener.expectedExpression(token);
2145 } 2197 }
2146 } 2198 }
2147 2199
2148 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 2200 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
2149 BeginGroupToken beginGroup = token; 2201 BeginGroupToken beginGroup = token;
2202 // TODO(eernst): Check for NPE as described in issue 26252.
2150 Token nextToken = beginGroup.endGroup.next; 2203 Token nextToken = beginGroup.endGroup.next;
2151 int kind = nextToken.kind; 2204 int kind = nextToken.kind;
2152 if (mayParseFunctionExpressions && 2205 if (mayParseFunctionExpressions &&
2153 (identical(kind, FUNCTION_TOKEN) || 2206 (identical(kind, FUNCTION_TOKEN) ||
2154 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || 2207 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
2155 (identical(kind, KEYWORD_TOKEN) && 2208 (identical(kind, KEYWORD_TOKEN) &&
2156 (nextToken.value == 'async' || nextToken.value == 'sync')))) { 2209 (nextToken.value == 'async' || nextToken.value == 'sync')))) {
2210 listener.handleNoTypeVariables(token);
2157 return parseUnnamedFunction(token); 2211 return parseUnnamedFunction(token);
2158 } else { 2212 } else {
2159 bool old = mayParseFunctionExpressions; 2213 bool old = mayParseFunctionExpressions;
2160 mayParseFunctionExpressions = true; 2214 mayParseFunctionExpressions = true;
2161 token = parseParenthesizedExpression(token); 2215 token = parseParenthesizedExpression(token);
2162 mayParseFunctionExpressions = old; 2216 mayParseFunctionExpressions = old;
2163 return token; 2217 return token;
2164 } 2218 }
2165 } 2219 }
2166 2220
(...skipping 29 matching lines...) Expand all
2196 token = token.next; 2250 token = token.next;
2197 if (optional('(', token)) { 2251 if (optional('(', token)) {
2198 // Super constructor. 2252 // Super constructor.
2199 listener.handleNoTypeArguments(token); 2253 listener.handleNoTypeArguments(token);
2200 token = parseArguments(token); 2254 token = parseArguments(token);
2201 listener.endSend(token); 2255 listener.endSend(token);
2202 } 2256 }
2203 return token; 2257 return token;
2204 } 2258 }
2205 2259
2206 Token parseLiteralListOrMap(Token token) { 2260 /// '[' (expressionList ','?)? ']'.
2207 Token constKeyword = null; 2261 ///
2208 if (optional('const', token)) { 2262 /// Provide [constKeyword] if preceded by 'const', null if not.
2209 constKeyword = token; 2263 /// This is a suffix parser because it is assumed that type arguments have
2210 token = token.next; 2264 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
2211 } 2265 Token parseLiteralListSuffix(Token token, Token constKeyword) {
2212 token = parseTypeArgumentsOpt(token); 2266 assert(optional('[', token) || optional('[]', token));
2213 Token beginToken = token; 2267 Token beginToken = token;
2214 int count = 0; 2268 int count = 0;
2215 if (optional('{', token)) { 2269 if (optional('[', token)) {
2216 bool old = mayParseFunctionExpressions; 2270 bool old = mayParseFunctionExpressions;
2217 mayParseFunctionExpressions = true; 2271 mayParseFunctionExpressions = true;
2218 do { 2272 do {
2219 if (optional('}', token.next)) {
2220 token = token.next;
2221 break;
2222 }
2223 token = parseMapLiteralEntry(token.next);
2224 ++count;
2225 } while (optional(',', token));
2226 mayParseFunctionExpressions = old;
2227 listener.handleLiteralMap(count, beginToken, constKeyword, token);
2228 return expect('}', token);
2229 } else if (optional('[', token)) {
2230 bool old = mayParseFunctionExpressions;
2231 mayParseFunctionExpressions = true;
2232 do {
2233 if (optional(']', token.next)) { 2273 if (optional(']', token.next)) {
2234 token = token.next; 2274 token = token.next;
2235 break; 2275 break;
2236 } 2276 }
2237 token = parseExpression(token.next); 2277 token = parseExpression(token.next);
2238 ++count; 2278 ++count;
2239 } while (optional(',', token)); 2279 } while (optional(',', token));
2240 mayParseFunctionExpressions = old; 2280 mayParseFunctionExpressions = old;
2241 listener.handleLiteralList(count, beginToken, constKeyword, token); 2281 listener.handleLiteralList(count, beginToken, constKeyword, token);
2242 return expect(']', token); 2282 return expect(']', token);
2243 } else if (optional('[]', token)) { 2283 }
2244 listener.handleLiteralList(0, token, constKeyword, token); 2284 // Looking at '[]'.
2245 return token.next; 2285 listener.handleLiteralList(0, token, constKeyword, token);
2286 return token.next;
2287 }
2288
2289 /// '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'.
2290 ///
2291 /// Provide token for [constKeyword] if preceded by 'const', null if not.
2292 /// This is a suffix parser because it is assumed that type arguments have
2293 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
2294 Token parseLiteralMapSuffix(Token token, Token constKeyword) {
2295 assert(optional('{', token));
2296 Token beginToken = token;
2297 int count = 0;
2298 bool old = mayParseFunctionExpressions;
2299 mayParseFunctionExpressions = true;
2300 do {
2301 if (optional('}', token.next)) {
2302 token = token.next;
2303 break;
2304 }
2305 token = parseMapLiteralEntry(token.next);
2306 ++count;
2307 } while (optional(',', token));
2308 mayParseFunctionExpressions = old;
2309 listener.handleLiteralMap(count, beginToken, constKeyword, token);
2310 return expect('}', token);
2311 }
2312
2313 /// formalParameterList functionBody.
2314 ///
2315 /// This is a suffix parser because it is assumed that type arguments have
2316 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
2317 Token parseLiteralFunctionSuffix(Token token) {
2318 assert(optional('(',token));
2319 BeginGroupToken beginGroup = token;
2320 if (beginGroup.endGroup != null) {
2321 Token nextToken = beginGroup.endGroup.next;
2322 int kind = nextToken.kind;
2323 if (identical(kind, FUNCTION_TOKEN) ||
2324 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
2325 (identical(kind, KEYWORD_TOKEN) &&
2326 (nextToken.value == 'async' || nextToken.value == 'sync'))) {
2327 return parseUnnamedFunction(token);
2328 }
2329 // Fall through.
2330 }
2331 listener.unexpected(token);
2332 return null;
2333 }
2334
2335 /// (typeArguments (
2336 /// '[' (expressionList ','?)? ']' |
2337 /// '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}')) |
2338 /// typeParameters formalParameterList functionBody.
2339 ///
2340 /// Provide token for [constKeyword] if preceded by 'const', null if not.
2341 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
2342 assert(optional('<', token));
2343 BeginGroupToken begin = token;
2344 if (enableGenericMethodSyntax &&
2345 constKeyword == null &&
2346 begin.endGroup != null &&
2347 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
2348 token = parseTypeVariablesOpt(token);
2349 return parseLiteralFunctionSuffix(token);
2246 } else { 2350 } else {
2351 token = parseTypeArgumentsOpt(token);
2352 if (optional('{', token)) {
2353 return parseLiteralMapSuffix(token, constKeyword);
2354 } else if ((optional('[', token)) || (optional('[]', token))) {
2355 return parseLiteralListSuffix(token, constKeyword);
2356 }
2247 listener.unexpected(token); 2357 listener.unexpected(token);
2248 return null; 2358 return null;
2249 } 2359 }
2250 } 2360 }
2251 2361
2252 Token parseMapLiteralEntry(Token token) { 2362 Token parseMapLiteralEntry(Token token) {
2253 listener.beginLiteralMapEntry(token); 2363 listener.beginLiteralMapEntry(token);
2254 // Assume the listener rejects non-string keys. 2364 // Assume the listener rejects non-string keys.
2255 token = parseExpression(token); 2365 token = parseExpression(token);
2256 Token colon = token; 2366 Token colon = token;
(...skipping 11 matching lines...) Expand all
2268 isFunctionDeclaration(peek.next)) { 2378 isFunctionDeclaration(peek.next)) {
2269 return parseFunctionExpression(token); 2379 return parseFunctionExpression(token);
2270 } else if (isFunctionDeclaration(token.next)) { 2380 } else if (isFunctionDeclaration(token.next)) {
2271 return parseFunctionExpression(token); 2381 return parseFunctionExpression(token);
2272 } else { 2382 } else {
2273 return parseSend(token); 2383 return parseSend(token);
2274 } 2384 }
2275 } 2385 }
2276 2386
2277 bool isFunctionDeclaration(Token token) { 2387 bool isFunctionDeclaration(Token token) {
2388 if (enableGenericMethodSyntax && optional('<', token)) {
2389 BeginGroupToken begin = token;
2390 if (begin.endGroup == null) return false;
2391 token = begin.endGroup.next;
2392 }
2278 if (optional('(', token)) { 2393 if (optional('(', token)) {
2279 BeginGroupToken begin = token; 2394 BeginGroupToken begin = token;
2395 // TODO(eernst): Check for NPE as described in issue 26252.
2280 String afterParens = begin.endGroup.next.stringValue; 2396 String afterParens = begin.endGroup.next.stringValue;
2281 if (identical(afterParens, '{') || 2397 if (identical(afterParens, '{') ||
2282 identical(afterParens, '=>') || 2398 identical(afterParens, '=>') ||
2283 identical(afterParens, 'async') || 2399 identical(afterParens, 'async') ||
2284 identical(afterParens, 'sync')) { 2400 identical(afterParens, 'sync')) {
2285 return true; 2401 return true;
2286 } 2402 }
2287 } 2403 }
2288 return false; 2404 return false;
2289 } 2405 }
(...skipping 14 matching lines...) Expand all
2304 token = parseConstructorReference(token); 2420 token = parseConstructorReference(token);
2305 token = parseRequiredArguments(token); 2421 token = parseRequiredArguments(token);
2306 listener.handleNewExpression(newKeyword); 2422 listener.handleNewExpression(newKeyword);
2307 return token; 2423 return token;
2308 } 2424 }
2309 2425
2310 Token parseConstExpression(Token token) { 2426 Token parseConstExpression(Token token) {
2311 Token constKeyword = token; 2427 Token constKeyword = token;
2312 token = expect('const', token); 2428 token = expect('const', token);
2313 final String value = token.stringValue; 2429 final String value = token.stringValue;
2314 if ((identical(value, '<')) || 2430 if ((identical(value, '[')) || (identical(value, '[]'))) {
2315 (identical(value, '[')) || 2431 listener.handleNoTypeArguments(token);
2316 (identical(value, '[]')) || 2432 return parseLiteralListSuffix(token, constKeyword);
2317 (identical(value, '{'))) { 2433 }
2318 return parseLiteralListOrMap(constKeyword); 2434 if (identical(value, '{')) {
2435 listener.handleNoTypeArguments(token);
2436 return parseLiteralMapSuffix(token, constKeyword);
2437 }
2438 if (identical(value, '<')) {
2439 return parseLiteralListOrMapOrFunction(token, constKeyword);
2319 } 2440 }
2320 token = parseConstructorReference(token); 2441 token = parseConstructorReference(token);
2321 token = parseRequiredArguments(token); 2442 token = parseRequiredArguments(token);
2322 listener.handleConstExpression(constKeyword); 2443 listener.handleConstExpression(constKeyword);
2323 return token; 2444 return token;
2324 } 2445 }
2325 2446
2326 Token parseLiteralInt(Token token) { 2447 Token parseLiteralInt(Token token) {
2327 listener.handleLiteralInt(token); 2448 listener.handleLiteralInt(token);
2328 return token.next; 2449 return token.next;
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2861 } 2982 }
2862 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2983 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2863 return expectSemicolon(token); 2984 return expectSemicolon(token);
2864 } 2985 }
2865 2986
2866 Token parseEmptyStatement(Token token) { 2987 Token parseEmptyStatement(Token token) {
2867 listener.handleEmptyStatement(token); 2988 listener.handleEmptyStatement(token);
2868 return expectSemicolon(token); 2989 return expectSemicolon(token);
2869 } 2990 }
2870 } 2991 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/node_listener.dart ('k') | pkg/compiler/lib/src/scanner/array_based_scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698