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

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

Issue 1863053003: Adds support for --generic-method-syntax (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Added support for parsing generic methods (buggy, will upload again when fixed) 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 7 import '../options.dart' show
8 ParserOptions; 8 ParserOptions;
9 import '../common.dart'; 9 import '../common.dart';
10 import '../tokens/keyword.dart' show 10 import '../tokens/keyword.dart' show
(...skipping 23 matching lines...) Expand all
34 KeywordToken, 34 KeywordToken,
35 SymbolToken, 35 SymbolToken,
36 Token; 36 Token;
37 import '../tokens/token_constants.dart' show 37 import '../tokens/token_constants.dart' show
38 BAD_INPUT_TOKEN, 38 BAD_INPUT_TOKEN,
39 COMMA_TOKEN, 39 COMMA_TOKEN,
40 DOUBLE_TOKEN, 40 DOUBLE_TOKEN,
41 EOF_TOKEN, 41 EOF_TOKEN,
42 EQ_TOKEN, 42 EQ_TOKEN,
43 FUNCTION_TOKEN, 43 FUNCTION_TOKEN,
44 GT_TOKEN,
45 GT_GT_TOKEN,
44 HASH_TOKEN, 46 HASH_TOKEN,
45 HEXADECIMAL_TOKEN, 47 HEXADECIMAL_TOKEN,
46 IDENTIFIER_TOKEN, 48 IDENTIFIER_TOKEN,
47 INT_TOKEN, 49 INT_TOKEN,
48 KEYWORD_TOKEN, 50 KEYWORD_TOKEN,
49 LT_TOKEN, 51 LT_TOKEN,
50 OPEN_CURLY_BRACKET_TOKEN, 52 OPEN_CURLY_BRACKET_TOKEN,
51 OPEN_PAREN_TOKEN, 53 OPEN_PAREN_TOKEN,
52 OPEN_SQUARE_BRACKET_TOKEN, 54 OPEN_SQUARE_BRACKET_TOKEN,
53 PERIOD_TOKEN, 55 PERIOD_TOKEN,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 * matches, "star" means zero or more matches. For example, 98 * matches, "star" means zero or more matches. For example,
97 * [parseMetadataStar] corresponds to this grammar snippet: [: 99 * [parseMetadataStar] corresponds to this grammar snippet: [:
98 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. 100 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :].
99 */ 101 */
100 class Parser { 102 class Parser {
101 final Listener listener; 103 final Listener listener;
102 final ParserOptions parserOptions; 104 final ParserOptions parserOptions;
103 bool mayParseFunctionExpressions = true; 105 bool mayParseFunctionExpressions = true;
104 bool asyncAwaitKeywordsEnabled; 106 bool asyncAwaitKeywordsEnabled;
105 107
106 Parser(this.listener, this.parserOptions, 108 final bool _enableGenericMethodSyntax;
ahe 2016/04/08 09:53:33 Please avoid private fields, a subclass outside th
eernst 2016/04/08 17:07:10 I'm not sure what the right approach would be here
107 {this.asyncAwaitKeywordsEnabled: false}); 109
110 Parser(this.listener, ParserOptions _parserOptions,
ahe 2016/04/08 09:53:32 Remove _ from parameter.
eernst 2016/04/08 17:07:10 Done.
111 {this.asyncAwaitKeywordsEnabled: false}) :
112 parserOptions = _parserOptions,
ahe 2016/04/08 09:53:32 In: parserOption = parserOptions The left-hand
eernst 2016/04/08 17:07:10 Acknowledged.
113 _enableGenericMethodSyntax = _parserOptions.enableGenericMethodSyntax;
108 114
109 Token parseUnit(Token token) { 115 Token parseUnit(Token token) {
110 listener.beginCompilationUnit(token); 116 listener.beginCompilationUnit(token);
111 int count = 0; 117 int count = 0;
112 while (!identical(token.kind, EOF_TOKEN)) { 118 while (!identical(token.kind, EOF_TOKEN)) {
113 token = parseTopLevelDeclaration(token); 119 token = parseTopLevelDeclaration(token);
114 listener.endTopLevelDeclaration(token); 120 listener.endTopLevelDeclaration(token);
115 count++; 121 count++;
116 } 122 }
117 listener.endCompilationUnit(count, token); 123 listener.endCompilationUnit(count, token);
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 if (identical(kind, KEYWORD_TOKEN)) { 524 if (identical(kind, KEYWORD_TOKEN)) {
519 Keyword keyword = (token as KeywordToken).keyword; 525 Keyword keyword = (token as KeywordToken).keyword;
520 String value = keyword.syntax; 526 String value = keyword.syntax;
521 return keyword.isPseudo 527 return keyword.isPseudo
522 || (identical(value, 'dynamic')) 528 || (identical(value, 'dynamic'))
523 || (identical(value, 'void')); 529 || (identical(value, 'void'));
524 } 530 }
525 return false; 531 return false;
526 } 532 }
527 533
534 /// Checks for '<' type (',' type)* '>', returns null iff failing.
ahe 2016/04/08 09:53:32 Avoid using academic short-hand and notation in do
ahe 2016/04/08 09:53:33 How about: Returns next token after match token i
eernst 2016/04/08 17:07:10 Done.
535 /// Does not produce listener events. In this case the final '>' may be
536 /// the first character in a '>>' token, in which case the `endGroup` of
537 /// the initial '<' will be null, so we cannot rely on `endGroup`.
538 Token tryParseTypeArgumentsNested(Token token) {
ahe 2016/04/08 09:53:32 Below I question if this method is necessary. Howe
eernst 2016/04/08 17:07:10 The old (abandoned) CL did express the same distin
539 final kind = token.kind;
ahe 2016/04/08 09:53:33 Remove this variable. It's confusing that token is
eernst 2016/04/08 17:07:11 Done.
540 if (!identical(kind, LT_TOKEN)) return null;
541 token = token.next;
542 if (token == null) return null;
543 token = tryParseType(token);
544 while (token != null && identical(token.kind, COMMA_TOKEN)) {
545 token = token.next;
546 if (token == null) return null;
547 token = tryParseType(token);
548 }
549 if (token == null) return null;
550 if (identical(token.kind, GT_TOKEN)) return token.next;
551 if (!identical(token.kind, GT_GT_TOKEN)) return null;
552 // [token] is '>>' of which the final '>' that we are parsing is the first
553 // character. In order to keep the parsing process on track we must return
554 // a synthetic '>' corresponding to the second character of that '>>'.
555 Token syntheticToken = new SymbolToken(GT_INFO, token.charOffset + 1);
556 syntheticToken.next = token.next;
557 return syntheticToken;
558 }
559
560 /// Checks for identifier ('.' identifier)?, returns null iff failing.
ahe 2016/04/08 09:53:33 iff -> if. What does "failing" mean? How about:
eernst 2016/04/08 17:07:10 Rephrased in a similar manner as several earlier d
561 /// Does not produce listener events.
562 Token tryParseQualified(Token token) {
ahe 2016/04/08 09:53:32 There's probably suboptimal error recovery here. F
eernst 2016/04/08 17:07:10 It would be nice if they _could_ do that. ;) For
563 if (!identical(token.kind, IDENTIFIER_TOKEN)) return null;
564 token = token.next;
565 if (!identical(token.kind, PERIOD_TOKEN)) return token;
566 token = token.next;
567 if (!identical(token.kind, IDENTIFIER_TOKEN)) return null;
568 return token.next;
569 }
570
571 /// Checks for typeName typeArguments? and returns null iff failing.
ahe 2016/04/08 09:53:32 iff -> if, but what about: Returns next token aft
eernst 2016/04/08 17:07:11 Rephrased in a similar manner as several earlier d
572 /// Does not produce listener events.
573 Token tryParseType(Token token) {
574 token = tryParseQualified(token);
575 if (token == null) return null;
576 Token tokenAfterQualified = token;
577 token = tryParseTypeArgumentsNested(token);
578 return token == null ? tokenAfterQualified : token;
579 }
580
581 /// Checks for '<' type (',' type)* '>' '(' and returns null iff failing.
ahe 2016/04/08 09:53:33 iff -> if, but what about: Returns last token of
eernst 2016/04/08 17:07:10 Rephrased in a similar manner as several earlier d
582 /// Does not produce listener events. With respect to the final '(', please
583 /// see the description of [isValidTypeArguments].
584 Token tryParseTypeArguments(Token token) {
585 final kind = token.kind;
586 if (!identical(kind, LT_TOKEN)) return null;
587 BeginGroupToken beginToken = token;
588 Token endToken = beginToken.endGroup;
589 token = token.next;
590 if (token == null || endToken == null ||
591 !identical(endToken.next?.kind, OPEN_PAREN_TOKEN)) return null;
592 token = tryParseType(token);
ahe 2016/04/08 09:53:32 Is this really necessary? If so, perhaps push back
593 while (token != null && identical(token.kind, COMMA_TOKEN)) {
594 token = token.next;
595 if (token == null) return null;
596 token = tryParseType(token);
597 }
598 if (!identical(token?.kind, GT_TOKEN)) return null;
599 return token.next;
600 }
601
602 /// Returns true iff the tokens starting from [token] match
ahe 2016/04/08 09:53:32 iff->if. We normally emit "otherwise returns fals
eernst 2016/04/08 17:07:10 Rephrased in a similar manner as several earlier d
603 /// '<' type (',' type)* '>' '('. The final '(' is not part of the
604 /// grammar construct `typeArguments`, but it is required here such that
605 /// type arguments in generic method invocations can be recognized, and
606 /// as few as possible other constructs will pass (e.g., 'a < C, D > 3').
607 bool isValidTypeArguments(Token token) {
ahe 2016/04/08 09:53:32 Rename to "isValidMethodTypeArguments" to signal t
eernst 2016/04/08 17:07:10 Makes sense, done. (This deviates from the naming
floitsch 2016/04/11 11:00:13 Fwiw, this CL only adds syntactic support. The sem
608 return tryParseTypeArguments(token) != null;
609 }
ahe 2016/04/08 09:53:32 Please reverse the order of all these methods. It'
eernst 2016/04/08 17:07:10 Ah, that's funny. The literate programming credo (
610
528 Token parseQualified(Token token) { 611 Token parseQualified(Token token) {
529 token = parseIdentifier(token); 612 token = parseIdentifier(token);
530 while (optional('.', token)) { 613 while (optional('.', token)) {
531 token = parseQualifiedRest(token); 614 token = parseQualifiedRest(token);
532 } 615 }
533 return token; 616 return token;
534 } 617 }
535 618
536 Token parseQualifiedRestOpt(Token token) { 619 Token parseQualifiedRestOpt(Token token) {
537 if (optional('.', token)) { 620 if (optional('.', token)) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 listener.handleModifiers(0); 1087 listener.handleModifiers(0);
1005 } 1088 }
1006 1089
1007 if (type == null) { 1090 if (type == null) {
1008 listener.handleNoType(name); 1091 listener.handleNoType(name);
1009 } else { 1092 } else {
1010 parseReturnTypeOpt(type); 1093 parseReturnTypeOpt(type);
1011 } 1094 }
1012 Token token = parseIdentifier(name); 1095 Token token = parseIdentifier(name);
1013 1096
1097 if (_enableGenericMethodSyntax && getOrSet == null) {
1098 token = parseTypeVariablesOpt(token);
1099 } else {
1100 listener.handleNoTypeVariables(token);
1101 }
1014 token = parseFormalParametersOpt(token); 1102 token = parseFormalParametersOpt(token);
1015 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1103 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1016 token = parseAsyncModifier(token); 1104 token = parseAsyncModifier(token);
1017 token = parseFunctionBody(token, false, externalModifier != null); 1105 token = parseFunctionBody(token, false, externalModifier != null);
1018 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1106 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
1019 Token endToken = token; 1107 Token endToken = token;
1020 token = token.next; 1108 token = token.next;
1021 if (token.kind == BAD_INPUT_TOKEN) { 1109 if (token.kind == BAD_INPUT_TOKEN) {
1022 token = listener.unexpected(token); 1110 token = listener.unexpected(token);
1023 } 1111 }
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 } 1400 }
1313 } 1401 }
1314 1402
1315 token = afterName; 1403 token = afterName;
1316 bool isField; 1404 bool isField;
1317 while (true) { 1405 while (true) {
1318 // Loop to allow the listener to rewrite the token stream for 1406 // Loop to allow the listener to rewrite the token stream for
1319 // error handling. 1407 // error handling.
1320 final String value = token.stringValue; 1408 final String value = token.stringValue;
1321 if ((identical(value, '(')) || (identical(value, '.')) 1409 if ((identical(value, '(')) || (identical(value, '.'))
1322 || (identical(value, '{')) || (identical(value, '=>'))) { 1410 || (identical(value, '{')) || (identical(value, '=>'))
1411 || (_enableGenericMethodSyntax && identical(value, '<'))) {
1323 isField = false; 1412 isField = false;
1324 break; 1413 break;
1325 } else if (identical(value, ';')) { 1414 } else if (identical(value, ';')) {
1326 if (getOrSet != null) { 1415 if (getOrSet != null) {
1327 // If we found a "get" keyword, this must be an abstract 1416 // If we found a "get" keyword, this must be an abstract
1328 // getter. 1417 // getter.
1329 isField = (!identical(getOrSet.stringValue, 'get')); 1418 isField = (!identical(getOrSet.stringValue, 'get'));
1330 // TODO(ahe): This feels like a hack. 1419 // TODO(ahe): This feels like a hack.
1331 } else { 1420 } else {
1332 isField = true; 1421 isField = true;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 if (staticModifier != null) { 1502 if (staticModifier != null) {
1414 listener.reportError( 1503 listener.reportError(
1415 staticModifier, MessageKind.EXTRANEOUS_MODIFIER, 1504 staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
1416 {'modifier': staticModifier}); 1505 {'modifier': staticModifier});
1417 } 1506 }
1418 } else { 1507 } else {
1419 token = parseIdentifier(name); 1508 token = parseIdentifier(name);
1420 } 1509 }
1421 1510
1422 token = parseQualifiedRestOpt(token); 1511 token = parseQualifiedRestOpt(token);
1512 if (_enableGenericMethodSyntax && getOrSet == null) {
1513 token = parseTypeVariablesOpt(token);
1514 } else {
1515 listener.handleNoTypeVariables(token);
1516 }
1423 token = parseFormalParametersOpt(token); 1517 token = parseFormalParametersOpt(token);
1424 token = parseInitializersOpt(token); 1518 token = parseInitializersOpt(token);
1425 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1519 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1426 token = parseAsyncModifier(token); 1520 token = parseAsyncModifier(token);
1427 if (optional('=', token)) { 1521 if (optional('=', token)) {
1428 token = parseRedirectingFactoryBody(token); 1522 token = parseRedirectingFactoryBody(token);
1429 } else { 1523 } else {
1430 token = parseFunctionBody( 1524 token = parseFunctionBody(
1431 token, false, staticModifier == null || externalModifier != null); 1525 token, false, staticModifier == null || externalModifier != null);
1432 } 1526 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 } 1593 }
1500 listener.beginFunctionName(token); 1594 listener.beginFunctionName(token);
1501 if (optional('operator', token)) { 1595 if (optional('operator', token)) {
1502 token = parseOperatorName(token); 1596 token = parseOperatorName(token);
1503 } else { 1597 } else {
1504 token = parseIdentifier(token); 1598 token = parseIdentifier(token);
1505 } 1599 }
1506 } 1600 }
1507 token = parseQualifiedRestOpt(token); 1601 token = parseQualifiedRestOpt(token);
1508 listener.endFunctionName(token); 1602 listener.endFunctionName(token);
1603 if (_enableGenericMethodSyntax && getOrSet == null) {
1604 token = parseTypeVariablesOpt(token);
1605 } else {
1606 listener.handleNoTypeVariables(token);
1607 }
1509 token = parseFormalParametersOpt(token); 1608 token = parseFormalParametersOpt(token);
1510 token = parseInitializersOpt(token); 1609 token = parseInitializersOpt(token);
1511 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1610 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1512 token = parseAsyncModifier(token); 1611 token = parseAsyncModifier(token);
1513 if (optional('=', token)) { 1612 if (optional('=', token)) {
1514 token = parseRedirectingFactoryBody(token); 1613 token = parseRedirectingFactoryBody(token);
1515 } else { 1614 } else {
1516 token = parseFunctionBody(token, false, true); 1615 token = parseFunctionBody(token, false, true);
1517 } 1616 }
1518 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1617 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
(...skipping 20 matching lines...) Expand all
1539 return token; 1638 return token;
1540 } 1639 }
1541 1640
1542 Token parseFunctionExpression(Token token) { 1641 Token parseFunctionExpression(Token token) {
1543 listener.beginFunction(token); 1642 listener.beginFunction(token);
1544 listener.handleModifiers(0); 1643 listener.handleModifiers(0);
1545 token = parseReturnTypeOpt(token); 1644 token = parseReturnTypeOpt(token);
1546 listener.beginFunctionName(token); 1645 listener.beginFunctionName(token);
1547 token = parseIdentifier(token); 1646 token = parseIdentifier(token);
1548 listener.endFunctionName(token); 1647 listener.endFunctionName(token);
1648 if (_enableGenericMethodSyntax) {
1649 token = parseTypeVariablesOpt(token);
1650 } else {
1651 listener.handleNoTypeVariables(token);
1652 }
1549 token = parseFormalParameters(token); 1653 token = parseFormalParameters(token);
1550 listener.handleNoInitializers(); 1654 listener.handleNoInitializers();
1551 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1655 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1552 token = parseAsyncModifier(token); 1656 token = parseAsyncModifier(token);
1553 bool isBlock = optional('{', token); 1657 bool isBlock = optional('{', token);
1554 token = parseFunctionBody(token, true, false); 1658 token = parseFunctionBody(token, true, false);
1555 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1659 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
1556 listener.endFunction(null, token); 1660 listener.endFunction(null, token);
1557 return isBlock ? token.next : token; 1661 return isBlock ? token.next : token;
1558 } 1662 }
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 while (true) { 2108 while (true) {
2005 if (optional('[', token)) { 2109 if (optional('[', token)) {
2006 Token openSquareBracket = token; 2110 Token openSquareBracket = token;
2007 bool old = mayParseFunctionExpressions; 2111 bool old = mayParseFunctionExpressions;
2008 mayParseFunctionExpressions = true; 2112 mayParseFunctionExpressions = true;
2009 token = parseExpression(token.next); 2113 token = parseExpression(token.next);
2010 mayParseFunctionExpressions = old; 2114 mayParseFunctionExpressions = old;
2011 listener.handleIndexedExpression(openSquareBracket, token); 2115 listener.handleIndexedExpression(openSquareBracket, token);
2012 token = expect(']', token); 2116 token = expect(']', token);
2013 } else if (optional('(', token)) { 2117 } else if (optional('(', token)) {
2118 listener.handleNoTypeArguments(token);
2014 token = parseArguments(token); 2119 token = parseArguments(token);
2015 listener.endSend(token); 2120 listener.endSend(token);
2016 } else { 2121 } else {
2017 break; 2122 break;
2018 } 2123 }
2019 } 2124 }
2020 return token; 2125 return token;
2021 } 2126 }
2022 2127
2023 Token parsePrimary(Token token) { 2128 Token parsePrimary(Token token) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 } 2206 }
2102 listener.handleParenthesizedExpression(begin); 2207 listener.handleParenthesizedExpression(begin);
2103 return expect(')', token); 2208 return expect(')', token);
2104 } 2209 }
2105 2210
2106 Token parseThisExpression(Token token) { 2211 Token parseThisExpression(Token token) {
2107 listener.handleThisExpression(token); 2212 listener.handleThisExpression(token);
2108 token = token.next; 2213 token = token.next;
2109 if (optional('(', token)) { 2214 if (optional('(', token)) {
2110 // Constructor forwarding. 2215 // Constructor forwarding.
2216 listener.handleNoTypeArguments(token);
2111 token = parseArguments(token); 2217 token = parseArguments(token);
2112 listener.endSend(token); 2218 listener.endSend(token);
2113 } 2219 }
2114 return token; 2220 return token;
2115 } 2221 }
2116 2222
2117 Token parseSuperExpression(Token token) { 2223 Token parseSuperExpression(Token token) {
2118 listener.handleSuperExpression(token); 2224 listener.handleSuperExpression(token);
2119 token = token.next; 2225 token = token.next;
2120 if (optional('(', token)) { 2226 if (optional('(', token)) {
2121 // Super constructor. 2227 // Super constructor.
2228 listener.handleNoTypeArguments(token);
2122 token = parseArguments(token); 2229 token = parseArguments(token);
2123 listener.endSend(token); 2230 listener.endSend(token);
2124 } 2231 }
2125 return token; 2232 return token;
2126 } 2233 }
2127 2234
2128 Token parseLiteralListOrMap(Token token) { 2235 Token parseLiteralListOrMap(Token token) {
2129 Token constKeyword = null; 2236 Token constKeyword = null;
2130 if (optional('const', token)) { 2237 if (optional('const', token)) {
2131 constKeyword = token; 2238 constKeyword = token;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 } 2435 }
2329 2436
2330 Token parseLiteralNull(Token token) { 2437 Token parseLiteralNull(Token token) {
2331 listener.handleLiteralNull(token); 2438 listener.handleLiteralNull(token);
2332 return token.next; 2439 return token.next;
2333 } 2440 }
2334 2441
2335 Token parseSend(Token token) { 2442 Token parseSend(Token token) {
2336 listener.beginSend(token); 2443 listener.beginSend(token);
2337 token = parseIdentifier(token); 2444 token = parseIdentifier(token);
2445 if (_enableGenericMethodSyntax && isValidTypeArguments(token)) {
2446 token = parseTypeArgumentsOpt(token);
2447 } else {
2448 listener.handleNoTypeArguments(token);
2449 }
2338 token = parseArgumentsOpt(token); 2450 token = parseArgumentsOpt(token);
2339 listener.endSend(token); 2451 listener.endSend(token);
2340 return token; 2452 return token;
2341 } 2453 }
2342 2454
2343 Token parseArgumentsOpt(Token token) { 2455 Token parseArgumentsOpt(Token token) {
2344 if (!optional('(', token)) { 2456 if (!optional('(', token)) {
2345 listener.handleNoArguments(token); 2457 listener.handleNoArguments(token);
2346 return token; 2458 return token;
2347 } else { 2459 } else {
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 } 2891 }
2780 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2892 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2781 return expectSemicolon(token); 2893 return expectSemicolon(token);
2782 } 2894 }
2783 2895
2784 Token parseEmptyStatement(Token token) { 2896 Token parseEmptyStatement(Token token) {
2785 listener.handleEmptyStatement(token); 2897 listener.handleEmptyStatement(token);
2786 return expectSemicolon(token); 2898 return expectSemicolon(token);
2787 } 2899 }
2788 } 2900 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/node_listener.dart ('k') | tests/compiler/dart2js/options_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698