Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 /** | 5 /** |
| 6 * An event generating parser of Dart programs. This parser expects | 6 * An event generating parser of Dart programs. This parser expects |
| 7 * all tokens in a linked list (aka a token stream). | 7 * all tokens in a linked list (aka a token stream). |
| 8 * | 8 * |
| 9 * The class [Scanner] is used to generate a token stream. See the | 9 * The class [Scanner] is used to generate a token stream. See the |
| 10 * file scanner.dart. | 10 * file scanner.dart. |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 } else { | 200 } else { |
| 201 return expect(']', token); | 201 return expect(']', token); |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 | 204 |
| 205 Token parseTypeOpt(Token token) { | 205 Token parseTypeOpt(Token token) { |
| 206 String value = token.stringValue; | 206 String value = token.stringValue; |
| 207 if (value === 'var') return parseType(token); | 207 if (value === 'var') return parseType(token); |
| 208 if (value !== 'this') { | 208 if (value !== 'this') { |
| 209 Token peek = peekAfterExpectedType(token); | 209 Token peek = peekAfterExpectedType(token); |
| 210 if (isIdentifier(peek) || optional('this', peek)) { | 210 if (peek.isIdentifier() || optional('this', peek)) { |
| 211 return parseType(token); | 211 return parseType(token); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 listener.handleNoType(token); | 214 listener.handleNoType(token); |
| 215 return token; | 215 return token; |
| 216 } | 216 } |
| 217 | 217 |
| 218 bool isIdentifier(Token token) => token.isIdentifier(); | 218 bool isValidTypeReference(Token token) { |
| 219 final kind = token.kind; | |
| 220 if (kind === IDENTIFIER_TOKEN) return true; | |
| 221 if (kind === KEYWORD_TOKEN) { | |
| 222 Keyword keyword = token.value; | |
| 223 String value = keyword.stringValue; | |
| 224 return (keyword.isPseudo) || (value === 'Dynamic') || (value === 'void'); | |
|
ngeoffray
2012/09/10 16:20:54
No need for parens in keyword.isPseudo
| |
| 225 } | |
| 226 return false; | |
| 227 } | |
| 219 | 228 |
| 220 Token parseDefaultClauseOpt(Token token) { | 229 Token parseDefaultClauseOpt(Token token) { |
| 221 if (isDefaultKeyword(token)) { | 230 if (isDefaultKeyword(token)) { |
| 222 // TODO(ahe): Remove support for 'factory' in this position. | 231 // TODO(ahe): Remove support for 'factory' in this position. |
| 223 Token defaultKeyword = token; | 232 Token defaultKeyword = token; |
| 224 listener.beginDefaultClause(defaultKeyword); | 233 listener.beginDefaultClause(defaultKeyword); |
| 225 token = parseIdentifier(token.next); | 234 token = parseIdentifier(token.next); |
| 226 token = parseQualifiedRestOpt(token); | 235 token = parseQualifiedRestOpt(token); |
| 227 token = parseTypeVariablesOpt(token); | 236 token = parseTypeVariablesOpt(token); |
| 228 listener.endDefaultClause(defaultKeyword); | 237 listener.endDefaultClause(defaultKeyword); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 Token parseStringPart(Token token) { | 305 Token parseStringPart(Token token) { |
| 297 if (token.kind === STRING_TOKEN) { | 306 if (token.kind === STRING_TOKEN) { |
| 298 listener.handleStringPart(token); | 307 listener.handleStringPart(token); |
| 299 return token.next; | 308 return token.next; |
| 300 } else { | 309 } else { |
| 301 return listener.expected('string', token); | 310 return listener.expected('string', token); |
| 302 } | 311 } |
| 303 } | 312 } |
| 304 | 313 |
| 305 Token parseIdentifier(Token token) { | 314 Token parseIdentifier(Token token) { |
| 306 if (isIdentifier(token)) { | 315 if (token.isIdentifier()) { |
| 307 listener.handleIdentifier(token); | 316 listener.handleIdentifier(token); |
| 308 } else { | 317 } else { |
| 309 listener.expectedIdentifier(token); | 318 listener.expectedIdentifier(token); |
| 310 } | 319 } |
| 311 return token.next; | 320 return token.next; |
| 312 } | 321 } |
| 313 | 322 |
| 314 Token expect(String string, Token token) { | 323 Token expect(String string, Token token) { |
| 315 if (string !== token.stringValue) { | 324 if (string !== token.stringValue) { |
| 316 return listener.expected(string, token); | 325 return listener.expected(string, token); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 334 * Returns true if the stringValue of the [token] is [value]. | 343 * Returns true if the stringValue of the [token] is [value]. |
| 335 */ | 344 */ |
| 336 bool optional(String value, Token token) => value === token.stringValue; | 345 bool optional(String value, Token token) => value === token.stringValue; |
| 337 | 346 |
| 338 bool notEofOrValue(String value, Token token) { | 347 bool notEofOrValue(String value, Token token) { |
| 339 return token.kind !== EOF_TOKEN && value !== token.stringValue; | 348 return token.kind !== EOF_TOKEN && value !== token.stringValue; |
| 340 } | 349 } |
| 341 | 350 |
| 342 Token parseType(Token token) { | 351 Token parseType(Token token) { |
| 343 Token begin = token; | 352 Token begin = token; |
| 344 if (isIdentifier(token)) { | 353 if (isValidTypeReference(token)) { |
| 345 token = parseIdentifier(token); | 354 token = parseIdentifier(token); |
| 346 token = parseQualifiedRestOpt(token); | 355 token = parseQualifiedRestOpt(token); |
| 347 } else { | 356 } else { |
| 348 token = listener.expectedType(token); | 357 token = listener.expectedType(token); |
| 349 } | 358 } |
| 350 token = parseTypeArgumentsOpt(token); | 359 token = parseTypeArgumentsOpt(token); |
| 351 listener.endType(begin, token); | 360 listener.endType(begin, token); |
| 352 return token; | 361 return token; |
| 353 } | 362 } |
| 354 | 363 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 return token; | 405 return token; |
| 397 } | 406 } |
| 398 | 407 |
| 399 Token parseTopLevelMember(Token token) { | 408 Token parseTopLevelMember(Token token) { |
| 400 Token start = token; | 409 Token start = token; |
| 401 listener.beginTopLevelMember(token); | 410 listener.beginTopLevelMember(token); |
| 402 token = parseModifiers(token); | 411 token = parseModifiers(token); |
| 403 Token getOrSet = findGetOrSet(token); | 412 Token getOrSet = findGetOrSet(token); |
| 404 if (token === getOrSet) token = token.next; | 413 if (token === getOrSet) token = token.next; |
| 405 Token peek = peekAfterExpectedType(token); | 414 Token peek = peekAfterExpectedType(token); |
| 406 if (isIdentifier(peek)) { | 415 if (peek.isIdentifier()) { |
| 407 // Skip type. | 416 // Skip type. |
| 408 token = peek; | 417 token = peek; |
| 409 } | 418 } |
| 410 if (token === getOrSet) token = token.next; | 419 if (token === getOrSet) token = token.next; |
| 411 token = parseIdentifier(token); | 420 token = parseIdentifier(token); |
| 412 bool isField; | 421 bool isField; |
| 413 while (true) { | 422 while (true) { |
| 414 // Loop to allow the listener to rewrite the token stream for | 423 // Loop to allow the listener to rewrite the token stream for |
| 415 // error handling. | 424 // error handling. |
| 416 final String value = token.stringValue; | 425 final String value = token.stringValue; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 } | 549 } |
| 541 listener.handleModifiers(count); | 550 listener.handleModifiers(count); |
| 542 return token; | 551 return token; |
| 543 } | 552 } |
| 544 | 553 |
| 545 Token peekAfterType(Token token) { | 554 Token peekAfterType(Token token) { |
| 546 // TODO(ahe): Also handle var? | 555 // TODO(ahe): Also handle var? |
| 547 // We are looking at "identifier ...". | 556 // We are looking at "identifier ...". |
| 548 Token peek = token.next; | 557 Token peek = token.next; |
| 549 if (peek.kind === PERIOD_TOKEN) { | 558 if (peek.kind === PERIOD_TOKEN) { |
| 550 if (isIdentifier(peek.next)) { | 559 if (peek.next.isIdentifier()) { |
| 551 // Look past a library prefix. | 560 // Look past a library prefix. |
| 552 peek = peek.next.next; | 561 peek = peek.next.next; |
| 553 } | 562 } |
| 554 } | 563 } |
| 555 // We are looking at "qualified ...". | 564 // We are looking at "qualified ...". |
| 556 if (peek.kind === LT_TOKEN) { | 565 if (peek.kind === LT_TOKEN) { |
| 557 // Possibly generic type. | 566 // Possibly generic type. |
| 558 // We are looking at "qualified '<'". | 567 // We are looking at "qualified '<'". |
| 559 BeginGroupToken beginGroupToken = peek; | 568 BeginGroupToken beginGroupToken = peek; |
| 560 Token gtToken = beginGroupToken.endGroup; | 569 Token gtToken = beginGroupToken.endGroup; |
| 561 if (gtToken !== null) { | 570 if (gtToken !== null) { |
| 562 // We are looking at "qualified '<' ... '>' ...". | 571 // We are looking at "qualified '<' ... '>' ...". |
| 563 return gtToken.next; | 572 return gtToken.next; |
| 564 } | 573 } |
| 565 } | 574 } |
| 566 return peek; | 575 return peek; |
| 567 } | 576 } |
| 568 | 577 |
| 569 /** | 578 /** |
| 570 * Returns the token after the type which is expected to begin at [token]. | 579 * Returns the token after the type which is expected to begin at [token]. |
| 571 * If [token] is not the start of a type, [Listener.unexpectedType] is called. | 580 * If [token] is not the start of a type, [Listener.unexpectedType] is called. |
| 572 */ | 581 */ |
| 573 Token peekAfterExpectedType(Token token) { | 582 Token peekAfterExpectedType(Token token) { |
| 574 if ('void' !== token.stringValue && !isIdentifier(token)) { | 583 if ('void' !== token.stringValue && !token.isIdentifier()) { |
| 575 return listener.expectedType(token); | 584 return listener.expectedType(token); |
| 576 } | 585 } |
| 577 return peekAfterType(token); | 586 return peekAfterType(token); |
| 578 } | 587 } |
| 579 | 588 |
| 580 Token parseClassBody(Token token) { | 589 Token parseClassBody(Token token) { |
| 581 Token begin = token; | 590 Token begin = token; |
| 582 listener.beginClassBody(token); | 591 listener.beginClassBody(token); |
| 583 if (!optional('{', token)) { | 592 if (!optional('{', token)) { |
| 584 token = listener.expectedClassBody(token); | 593 token = listener.expectedClassBody(token); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 596 bool isGetOrSet(Token token) { | 605 bool isGetOrSet(Token token) { |
| 597 final String value = token.stringValue; | 606 final String value = token.stringValue; |
| 598 return (value === 'get') || (value === 'set'); | 607 return (value === 'get') || (value === 'set'); |
| 599 } | 608 } |
| 600 | 609 |
| 601 Token findGetOrSet(Token token) { | 610 Token findGetOrSet(Token token) { |
| 602 if (isGetOrSet(token)) { | 611 if (isGetOrSet(token)) { |
| 603 if (optional('<', token.next)) { | 612 if (optional('<', token.next)) { |
| 604 // For example: get<T> ... | 613 // For example: get<T> ... |
| 605 final Token peek = peekAfterExpectedType(token); | 614 final Token peek = peekAfterExpectedType(token); |
| 606 if (isGetOrSet(peek) && isIdentifier(peek.next)) { | 615 if (isGetOrSet(peek) && peek.next.isIdentifier()) { |
| 607 // For example: get<T> get identifier | 616 // For example: get<T> get identifier |
| 608 return peek; | 617 return peek; |
| 609 } | 618 } |
| 610 } else { | 619 } else { |
| 611 // For example: get ... | 620 // For example: get ... |
| 612 if (isGetOrSet(token.next) && isIdentifier(token.next.next)) { | 621 if (isGetOrSet(token.next) && token.next.next.isIdentifier()) { |
| 613 // For example: get get identifier | 622 // For example: get get identifier |
| 614 return token.next; | 623 return token.next; |
| 615 } else { | 624 } else { |
| 616 // For example: get identifier | 625 // For example: get identifier |
| 617 return token; | 626 return token; |
| 618 } | 627 } |
| 619 } | 628 } |
| 620 } else if (token.stringValue !== 'operator') { | 629 } else if (token.stringValue !== 'operator') { |
| 621 final Token peek = peekAfterExpectedType(token); | 630 final Token peek = peekAfterExpectedType(token); |
| 622 if (isGetOrSet(peek) && isIdentifier(peek.next)) { | 631 if (isGetOrSet(peek) && peek.next.isIdentifier()) { |
| 623 // type? get identifier | 632 // type? get identifier |
| 624 return peek; | 633 return peek; |
| 625 } | 634 } |
| 626 } | 635 } |
| 627 return null; | 636 return null; |
| 628 } | 637 } |
| 629 | 638 |
| 630 Token parseMember(Token token) { | 639 Token parseMember(Token token) { |
| 631 token = parseMetadataStar(token); | 640 token = parseMetadataStar(token); |
| 632 String value = token.stringValue; | 641 String value = token.stringValue; |
| 633 if (value === 'factory' || | 642 if (value === 'factory' || |
| 634 (value === 'external' && optional('factory', token.next))) { | 643 (value === 'external' && optional('factory', token.next))) { |
| 635 return parseFactoryMethod(token); | 644 return parseFactoryMethod(token); |
| 636 } | 645 } |
| 637 Token start = token; | 646 Token start = token; |
| 638 listener.beginMember(token); | 647 listener.beginMember(token); |
| 639 token = parseModifiers(token); | 648 token = parseModifiers(token); |
| 640 Token getOrSet = findGetOrSet(token); | 649 Token getOrSet = findGetOrSet(token); |
| 641 if (token === getOrSet) token = token.next; | 650 if (token === getOrSet) token = token.next; |
| 642 Token peek = peekAfterExpectedType(token); | 651 Token peek = peekAfterExpectedType(token); |
| 643 if (isIdentifier(peek) && token.stringValue !== 'operator') { | 652 if (peek.isIdentifier() && token.stringValue !== 'operator') { |
| 644 // Skip type. | 653 // Skip type. |
| 645 token = peek; | 654 token = peek; |
| 646 } | 655 } |
| 647 if (token === getOrSet) token = token.next; | 656 if (token === getOrSet) token = token.next; |
| 648 if (optional('operator', token)) { | 657 if (optional('operator', token)) { |
| 649 token = parseOperatorName(token); | 658 token = parseOperatorName(token); |
| 650 } else { | 659 } else { |
| 651 token = parseIdentifier(token); | 660 token = parseIdentifier(token); |
| 652 } | 661 } |
| 653 bool isField; | 662 bool isField; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 858 } else if (value === 'switch') { | 867 } else if (value === 'switch') { |
| 859 return parseSwitchStatement(token); | 868 return parseSwitchStatement(token); |
| 860 } else if (value === 'break') { | 869 } else if (value === 'break') { |
| 861 return parseBreakStatement(token); | 870 return parseBreakStatement(token); |
| 862 } else if (value === 'continue') { | 871 } else if (value === 'continue') { |
| 863 return parseContinueStatement(token); | 872 return parseContinueStatement(token); |
| 864 } else if (value === ';') { | 873 } else if (value === ';') { |
| 865 return parseEmptyStatement(token); | 874 return parseEmptyStatement(token); |
| 866 } else if (value === 'const') { | 875 } else if (value === 'const') { |
| 867 return parseExpressionStatementOrConstDeclaration(token); | 876 return parseExpressionStatementOrConstDeclaration(token); |
| 868 } else if (isIdentifier(token)) { | 877 } else if (token.isIdentifier()) { |
| 869 return parseExpressionStatementOrDeclaration(token); | 878 return parseExpressionStatementOrDeclaration(token); |
| 870 } else { | 879 } else { |
| 871 return parseExpressionStatement(token); | 880 return parseExpressionStatement(token); |
| 872 } | 881 } |
| 873 } | 882 } |
| 874 | 883 |
| 875 Token parseReturnStatement(Token token) { | 884 Token parseReturnStatement(Token token) { |
| 876 Token begin = token; | 885 Token begin = token; |
| 877 listener.beginReturnStatement(begin); | 886 listener.beginReturnStatement(begin); |
| 878 assert('return' === token.stringValue); | 887 assert('return' === token.stringValue); |
| 879 token = token.next; | 888 token = token.next; |
| 880 if (optional(';', token)) { | 889 if (optional(';', token)) { |
| 881 listener.endReturnStatement(false, begin, token); | 890 listener.endReturnStatement(false, begin, token); |
| 882 } else { | 891 } else { |
| 883 token = parseExpression(token); | 892 token = parseExpression(token); |
| 884 listener.endReturnStatement(true, begin, token); | 893 listener.endReturnStatement(true, begin, token); |
| 885 } | 894 } |
| 886 return expectSemicolon(token); | 895 return expectSemicolon(token); |
| 887 } | 896 } |
| 888 | 897 |
| 889 Token peekIdentifierAfterType(Token token) { | 898 Token peekIdentifierAfterType(Token token) { |
| 890 Token peek = peekAfterType(token); | 899 Token peek = peekAfterType(token); |
| 891 if (peek !== null && isIdentifier(peek)) { | 900 if (peek !== null && peek.isIdentifier()) { |
| 892 // We are looking at "type identifier". | 901 // We are looking at "type identifier". |
| 893 return peek; | 902 return peek; |
| 894 } else { | 903 } else { |
| 895 return null; | 904 return null; |
| 896 } | 905 } |
| 897 } | 906 } |
| 898 | 907 |
| 899 Token peekIdentifierAfterOptionalType(Token token) { | 908 Token peekIdentifierAfterOptionalType(Token token) { |
| 900 Token peek = peekIdentifierAfterType(token); | 909 Token peek = peekIdentifierAfterType(token); |
| 901 if (peek !== null) { | 910 if (peek !== null) { |
| 902 // We are looking at "type identifier". | 911 // We are looking at "type identifier". |
| 903 return peek; | 912 return peek; |
| 904 } else if (isIdentifier(token)) { | 913 } else if (token.isIdentifier()) { |
| 905 // We are looking at "identifier". | 914 // We are looking at "identifier". |
| 906 return token; | 915 return token; |
| 907 } else { | 916 } else { |
| 908 return null; | 917 return null; |
| 909 } | 918 } |
| 910 } | 919 } |
| 911 | 920 |
| 912 Token parseExpressionStatementOrDeclaration(Token token) { | 921 Token parseExpressionStatementOrDeclaration(Token token) { |
| 913 assert(isIdentifier(token) || token.stringValue === 'void'); | 922 assert(token.isIdentifier() || token.stringValue === 'void'); |
| 914 Token identifier = peekIdentifierAfterType(token); | 923 Token identifier = peekIdentifierAfterType(token); |
| 915 if (identifier !== null) { | 924 if (identifier !== null) { |
| 916 assert(isIdentifier(identifier)); | 925 assert(identifier.isIdentifier()); |
| 917 Token afterId = identifier.next; | 926 Token afterId = identifier.next; |
| 918 int afterIdKind = afterId.kind; | 927 int afterIdKind = afterId.kind; |
| 919 if (afterIdKind === EQ_TOKEN || | 928 if (afterIdKind === EQ_TOKEN || |
| 920 afterIdKind === SEMICOLON_TOKEN || | 929 afterIdKind === SEMICOLON_TOKEN || |
| 921 afterIdKind === COMMA_TOKEN) { | 930 afterIdKind === COMMA_TOKEN) { |
| 922 // We are looking at "type identifier" followed by '=', ';', ','. | 931 // We are looking at "type identifier" followed by '=', ';', ','. |
| 923 return parseVariablesDeclaration(token); | 932 return parseVariablesDeclaration(token); |
| 924 } else if (afterIdKind === OPEN_PAREN_TOKEN) { | 933 } else if (afterIdKind === OPEN_PAREN_TOKEN) { |
| 925 // We are looking at "type identifier '('". | 934 // We are looking at "type identifier '('". |
| 926 BeginGroupToken beginParen = afterId; | 935 BeginGroupToken beginParen = afterId; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 947 return parseExpressionStatement(token); | 956 return parseExpressionStatement(token); |
| 948 } | 957 } |
| 949 | 958 |
| 950 Token parseExpressionStatementOrConstDeclaration(Token token) { | 959 Token parseExpressionStatementOrConstDeclaration(Token token) { |
| 951 assert(token.stringValue === 'const'); | 960 assert(token.stringValue === 'const'); |
| 952 if (isModifier(token.next)) { | 961 if (isModifier(token.next)) { |
| 953 return parseVariablesDeclaration(token); | 962 return parseVariablesDeclaration(token); |
| 954 } | 963 } |
| 955 Token identifier = peekIdentifierAfterOptionalType(token.next); | 964 Token identifier = peekIdentifierAfterOptionalType(token.next); |
| 956 if (identifier !== null) { | 965 if (identifier !== null) { |
| 957 assert(isIdentifier(identifier)); | 966 assert(identifier.isIdentifier()); |
| 958 Token afterId = identifier.next; | 967 Token afterId = identifier.next; |
| 959 int afterIdKind = afterId.kind; | 968 int afterIdKind = afterId.kind; |
| 960 if (afterIdKind === EQ_TOKEN || | 969 if (afterIdKind === EQ_TOKEN || |
| 961 afterIdKind === SEMICOLON_TOKEN || | 970 afterIdKind === SEMICOLON_TOKEN || |
| 962 afterIdKind === COMMA_TOKEN) { | 971 afterIdKind === COMMA_TOKEN) { |
| 963 // We are looking at "const type identifier" followed by '=', ';', or | 972 // We are looking at "const type identifier" followed by '=', ';', or |
| 964 // ','. | 973 // ','. |
| 965 return parseVariablesDeclaration(token); | 974 return parseVariablesDeclaration(token); |
| 966 } | 975 } |
| 967 // Fall-through to expression statement. | 976 // Fall-through to expression statement. |
| 968 } | 977 } |
| 969 return parseExpressionStatement(token); | 978 return parseExpressionStatement(token); |
| 970 } | 979 } |
| 971 | 980 |
| 972 Token parseLabel(Token token) { | 981 Token parseLabel(Token token) { |
| 973 token = parseIdentifier(token); | 982 token = parseIdentifier(token); |
| 974 Token colon = token; | 983 Token colon = token; |
| 975 token = expect(':', token); | 984 token = expect(':', token); |
| 976 listener.handleLabel(colon); | 985 listener.handleLabel(colon); |
| 977 return token; | 986 return token; |
| 978 } | 987 } |
| 979 | 988 |
| 980 Token parseLabeledStatement(Token token) { | 989 Token parseLabeledStatement(Token token) { |
| 981 int labelCount = 0; | 990 int labelCount = 0; |
| 982 do { | 991 do { |
| 983 token = parseLabel(token); | 992 token = parseLabel(token); |
| 984 labelCount++; | 993 labelCount++; |
| 985 } while (isIdentifier(token) && optional(':', token.next)); | 994 } while (token.isIdentifier() && optional(':', token.next)); |
| 986 listener.beginLabeledStatement(token, labelCount); | 995 listener.beginLabeledStatement(token, labelCount); |
| 987 token = parseStatement(token); | 996 token = parseStatement(token); |
| 988 listener.endLabeledStatement(labelCount); | 997 listener.endLabeledStatement(labelCount); |
| 989 return token; | 998 return token; |
| 990 } | 999 } |
| 991 | 1000 |
| 992 Token parseExpressionStatement(Token token) { | 1001 Token parseExpressionStatement(Token token) { |
| 993 listener.beginExpressionStatement(token); | 1002 listener.beginExpressionStatement(token); |
| 994 token = parseExpression(token); | 1003 token = parseExpression(token); |
| 995 listener.endExpressionStatement(token); | 1004 listener.endExpressionStatement(token); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1075 return token; | 1084 return token; |
| 1076 } | 1085 } |
| 1077 | 1086 |
| 1078 Token parseCascadeExpression(Token token) { | 1087 Token parseCascadeExpression(Token token) { |
| 1079 listener.beginCascade(token); | 1088 listener.beginCascade(token); |
| 1080 assert(optional('..', token)); | 1089 assert(optional('..', token)); |
| 1081 Token cascadeOperator = token; | 1090 Token cascadeOperator = token; |
| 1082 token = token.next; | 1091 token = token.next; |
| 1083 if (optional('[', token)) { | 1092 if (optional('[', token)) { |
| 1084 token = parseArgumentOrIndexStar(token); | 1093 token = parseArgumentOrIndexStar(token); |
| 1085 } else if (isIdentifier(token)) { | 1094 } else if (token.isIdentifier()) { |
| 1086 token = parseSend(token); | 1095 token = parseSend(token); |
| 1087 listener.handleBinaryExpression(cascadeOperator); | 1096 listener.handleBinaryExpression(cascadeOperator); |
| 1088 } else { | 1097 } else { |
| 1089 return listener.unexpected(token); | 1098 return listener.unexpected(token); |
| 1090 } | 1099 } |
| 1091 Token mark; | 1100 Token mark; |
| 1092 do { | 1101 do { |
| 1093 mark = token; | 1102 mark = token; |
| 1094 if (optional('.', token)) { | 1103 if (optional('.', token)) { |
| 1095 Token period = token; | 1104 Token period = token; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1191 } else if (value === 'this') { | 1200 } else if (value === 'this') { |
| 1192 return parseThisExpression(token); | 1201 return parseThisExpression(token); |
| 1193 } else if (value === 'super') { | 1202 } else if (value === 'super') { |
| 1194 return parseSuperExpression(token); | 1203 return parseSuperExpression(token); |
| 1195 } else if (value === 'new') { | 1204 } else if (value === 'new') { |
| 1196 return parseNewExpression(token); | 1205 return parseNewExpression(token); |
| 1197 } else if (value === 'const') { | 1206 } else if (value === 'const') { |
| 1198 return parseConstExpression(token); | 1207 return parseConstExpression(token); |
| 1199 } else if (value === 'void') { | 1208 } else if (value === 'void') { |
| 1200 return parseFunctionExpression(token); | 1209 return parseFunctionExpression(token); |
| 1201 } else if (isIdentifier(token)) { | 1210 } else if (token.isIdentifier()) { |
| 1202 return parseSendOrFunctionLiteral(token); | 1211 return parseSendOrFunctionLiteral(token); |
| 1203 } else { | 1212 } else { |
| 1204 return listener.expectedExpression(token); | 1213 return listener.expectedExpression(token); |
| 1205 } | 1214 } |
| 1206 } else if (kind === OPEN_PAREN_TOKEN) { | 1215 } else if (kind === OPEN_PAREN_TOKEN) { |
| 1207 return parseParenthesizedExpressionOrFunctionLiteral(token); | 1216 return parseParenthesizedExpressionOrFunctionLiteral(token); |
| 1208 } else if ((kind === LT_TOKEN) || | 1217 } else if ((kind === LT_TOKEN) || |
| 1209 (kind === OPEN_SQUARE_BRACKET_TOKEN) || | 1218 (kind === OPEN_SQUARE_BRACKET_TOKEN) || |
| 1210 (kind === OPEN_CURLY_BRACKET_TOKEN) || | 1219 (kind === OPEN_CURLY_BRACKET_TOKEN) || |
| 1211 token.stringValue === '[]') { | 1220 token.stringValue === '[]') { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1592 Token parseVariablesDeclarationOrExpressionOpt(Token token) { | 1601 Token parseVariablesDeclarationOrExpressionOpt(Token token) { |
| 1593 final String value = token.stringValue; | 1602 final String value = token.stringValue; |
| 1594 if (value === ';') { | 1603 if (value === ';') { |
| 1595 listener.handleNoExpression(token); | 1604 listener.handleNoExpression(token); |
| 1596 return token; | 1605 return token; |
| 1597 } else if ((value === 'var') || (value === 'final')) { | 1606 } else if ((value === 'var') || (value === 'final')) { |
| 1598 return parseVariablesDeclarationNoSemicolon(token); | 1607 return parseVariablesDeclarationNoSemicolon(token); |
| 1599 } | 1608 } |
| 1600 Token identifier = peekIdentifierAfterType(token); | 1609 Token identifier = peekIdentifierAfterType(token); |
| 1601 if (identifier !== null) { | 1610 if (identifier !== null) { |
| 1602 assert(isIdentifier(identifier)); | 1611 assert(identifier.isIdentifier()); |
| 1603 Token afterId = identifier.next; | 1612 Token afterId = identifier.next; |
| 1604 int afterIdKind = afterId.kind; | 1613 int afterIdKind = afterId.kind; |
| 1605 if (afterIdKind === EQ_TOKEN || afterIdKind === SEMICOLON_TOKEN || | 1614 if (afterIdKind === EQ_TOKEN || afterIdKind === SEMICOLON_TOKEN || |
| 1606 afterIdKind === COMMA_TOKEN || optional('in', afterId)) { | 1615 afterIdKind === COMMA_TOKEN || optional('in', afterId)) { |
| 1607 return parseVariablesDeclarationNoSemicolon(token); | 1616 return parseVariablesDeclarationNoSemicolon(token); |
| 1608 } | 1617 } |
| 1609 } | 1618 } |
| 1610 return parseExpression(token); | 1619 return parseExpression(token); |
| 1611 } | 1620 } |
| 1612 | 1621 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1757 expect('}', token); | 1766 expect('}', token); |
| 1758 return token; | 1767 return token; |
| 1759 } | 1768 } |
| 1760 | 1769 |
| 1761 /** | 1770 /** |
| 1762 * Peek after the following labels (if any). The following token | 1771 * Peek after the following labels (if any). The following token |
| 1763 * is used to determine if the labels belong to a statement or a | 1772 * is used to determine if the labels belong to a statement or a |
| 1764 * switch case. | 1773 * switch case. |
| 1765 */ | 1774 */ |
| 1766 Token peekPastLabels(Token token) { | 1775 Token peekPastLabels(Token token) { |
| 1767 while (isIdentifier(token) && optional(':', token.next)) { | 1776 while (token.isIdentifier() && optional(':', token.next)) { |
| 1768 token = token.next.next; | 1777 token = token.next.next; |
| 1769 } | 1778 } |
| 1770 return token; | 1779 return token; |
| 1771 } | 1780 } |
| 1772 | 1781 |
| 1773 /** | 1782 /** |
| 1774 * Parse a group of labels, cases and possibly a default keyword and | 1783 * Parse a group of labels, cases and possibly a default keyword and |
| 1775 * the statements that they select. | 1784 * the statements that they select. |
| 1776 */ | 1785 */ |
| 1777 Token parseSwitchCase(Token token) { | 1786 Token parseSwitchCase(Token token) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1829 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword, | 1838 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword, |
| 1830 statementCount, begin, token); | 1839 statementCount, begin, token); |
| 1831 return token; | 1840 return token; |
| 1832 } | 1841 } |
| 1833 | 1842 |
| 1834 Token parseBreakStatement(Token token) { | 1843 Token parseBreakStatement(Token token) { |
| 1835 assert(optional('break', token)); | 1844 assert(optional('break', token)); |
| 1836 Token breakKeyword = token; | 1845 Token breakKeyword = token; |
| 1837 token = token.next; | 1846 token = token.next; |
| 1838 bool hasTarget = false; | 1847 bool hasTarget = false; |
| 1839 if (isIdentifier(token)) { | 1848 if (token.isIdentifier()) { |
| 1840 token = parseIdentifier(token); | 1849 token = parseIdentifier(token); |
| 1841 hasTarget = true; | 1850 hasTarget = true; |
| 1842 } | 1851 } |
| 1843 listener.handleBreakStatement(hasTarget, breakKeyword, token); | 1852 listener.handleBreakStatement(hasTarget, breakKeyword, token); |
| 1844 return expectSemicolon(token); | 1853 return expectSemicolon(token); |
| 1845 } | 1854 } |
| 1846 | 1855 |
| 1847 Token parseContinueStatement(Token token) { | 1856 Token parseContinueStatement(Token token) { |
| 1848 assert(optional('continue', token)); | 1857 assert(optional('continue', token)); |
| 1849 Token continueKeyword = token; | 1858 Token continueKeyword = token; |
| 1850 token = token.next; | 1859 token = token.next; |
| 1851 bool hasTarget = false; | 1860 bool hasTarget = false; |
| 1852 if (isIdentifier(token)) { | 1861 if (token.isIdentifier()) { |
| 1853 token = parseIdentifier(token); | 1862 token = parseIdentifier(token); |
| 1854 hasTarget = true; | 1863 hasTarget = true; |
| 1855 } | 1864 } |
| 1856 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1865 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1857 return expectSemicolon(token); | 1866 return expectSemicolon(token); |
| 1858 } | 1867 } |
| 1859 | 1868 |
| 1860 Token parseEmptyStatement(Token token) { | 1869 Token parseEmptyStatement(Token token) { |
| 1861 listener.handleEmptyStatement(token); | 1870 listener.handleEmptyStatement(token); |
| 1862 return expectSemicolon(token); | 1871 return expectSemicolon(token); |
| 1863 } | 1872 } |
| 1864 } | 1873 } |
| OLD | NEW |