Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.generated.parser; | 5 library analyzer.src.generated.parser; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| 11 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; | |
| 11 import 'package:analyzer/dart/ast/token.dart'; | 12 import 'package:analyzer/dart/ast/token.dart'; |
| 12 import 'package:analyzer/error/error.dart'; | 13 import 'package:analyzer/error/error.dart'; |
| 13 import 'package:analyzer/error/listener.dart'; | 14 import 'package:analyzer/error/listener.dart'; |
| 14 import 'package:analyzer/src/dart/ast/ast.dart'; | 15 import 'package:analyzer/src/dart/ast/ast.dart'; |
| 15 import 'package:analyzer/src/dart/ast/token.dart'; | 16 import 'package:analyzer/src/dart/ast/token.dart'; |
| 16 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; | 17 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
| 17 import 'package:analyzer/src/dart/scanner/reader.dart'; | 18 import 'package:analyzer/src/dart/scanner/reader.dart'; |
| 18 import 'package:analyzer/src/dart/scanner/scanner.dart'; | 19 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| 19 import 'package:analyzer/src/error/codes.dart'; | 20 import 'package:analyzer/src/error/codes.dart'; |
| 20 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; | 21 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 // Consider current keyword token as an identifier. | 387 // Consider current keyword token as an identifier. |
| 387 // It is not always true, e.g. "^is T" where "^" is place the place for | 388 // It is not always true, e.g. "^is T" where "^" is place the place for |
| 388 // synthetic identifier. By creating SyntheticStringToken we can | 389 // synthetic identifier. By creating SyntheticStringToken we can |
| 389 // distinguish a real identifier from synthetic. In the code completion | 390 // distinguish a real identifier from synthetic. In the code completion |
| 390 // behavior will depend on a cursor position - before or on "is". | 391 // behavior will depend on a cursor position - before or on "is". |
| 391 syntheticToken = _injectToken(new SyntheticStringToken( | 392 syntheticToken = _injectToken(new SyntheticStringToken( |
| 392 TokenType.IDENTIFIER, _currentToken.lexeme, _currentToken.offset)); | 393 TokenType.IDENTIFIER, _currentToken.lexeme, _currentToken.offset)); |
| 393 } else { | 394 } else { |
| 394 syntheticToken = _createSyntheticToken(TokenType.IDENTIFIER); | 395 syntheticToken = _createSyntheticToken(TokenType.IDENTIFIER); |
| 395 } | 396 } |
| 396 return new SimpleIdentifier(syntheticToken, isDeclaration: isDeclaration); | 397 return astFactory.simpleIdentifier(syntheticToken, |
|
Brian Wilkerson
2016/11/30 20:05:31
I'm surprised by these changes. I guess I was expe
Paul Berry
2016/11/30 20:21:57
My long term plan is to make the AST factory an in
| |
| 398 isDeclaration: isDeclaration); | |
| 397 } | 399 } |
| 398 | 400 |
| 399 /** | 401 /** |
| 400 * Return a synthetic string literal. | 402 * Return a synthetic string literal. |
| 401 */ | 403 */ |
| 402 SimpleStringLiteral createSyntheticStringLiteral() => | 404 SimpleStringLiteral createSyntheticStringLiteral() => astFactory |
| 403 new SimpleStringLiteral(_createSyntheticToken(TokenType.STRING), ""); | 405 .simpleStringLiteral(_createSyntheticToken(TokenType.STRING), ""); |
| 404 | 406 |
| 405 /** | 407 /** |
| 406 * Advance to the next token in the token stream, making it the new current | 408 * Advance to the next token in the token stream, making it the new current |
| 407 * token and return the token that was current before this method was invoked. | 409 * token and return the token that was current before this method was invoked. |
| 408 */ | 410 */ |
| 409 Token getAndAdvance() { | 411 Token getAndAdvance() { |
| 410 Token token = _currentToken; | 412 Token token = _currentToken; |
| 411 _currentToken = _currentToken.next; | 413 _currentToken = _currentToken.next; |
| 412 return token; | 414 return token; |
| 413 } | 415 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 * parsed. | 594 * parsed. |
| 593 * | 595 * |
| 594 * additiveExpression ::= | 596 * additiveExpression ::= |
| 595 * multiplicativeExpression (additiveOperator multiplicativeExpression )* | 597 * multiplicativeExpression (additiveOperator multiplicativeExpression )* |
| 596 * | 'super' (additiveOperator multiplicativeExpression)+ | 598 * | 'super' (additiveOperator multiplicativeExpression)+ |
| 597 */ | 599 */ |
| 598 Expression parseAdditiveExpression() { | 600 Expression parseAdditiveExpression() { |
| 599 Expression expression; | 601 Expression expression; |
| 600 if (_currentToken.keyword == Keyword.SUPER && | 602 if (_currentToken.keyword == Keyword.SUPER && |
| 601 _currentToken.next.type.isAdditiveOperator) { | 603 _currentToken.next.type.isAdditiveOperator) { |
| 602 expression = new SuperExpression(getAndAdvance()); | 604 expression = astFactory.superExpression(getAndAdvance()); |
| 603 } else { | 605 } else { |
| 604 expression = parseMultiplicativeExpression(); | 606 expression = parseMultiplicativeExpression(); |
| 605 } | 607 } |
| 606 while (_currentToken.type.isAdditiveOperator) { | 608 while (_currentToken.type.isAdditiveOperator) { |
| 607 expression = new BinaryExpression( | 609 expression = astFactory.binaryExpression( |
| 608 expression, getAndAdvance(), parseMultiplicativeExpression()); | 610 expression, getAndAdvance(), parseMultiplicativeExpression()); |
| 609 } | 611 } |
| 610 return expression; | 612 return expression; |
| 611 } | 613 } |
| 612 | 614 |
| 613 /** | 615 /** |
| 614 * Parse an annotation. Return the annotation that was parsed. | 616 * Parse an annotation. Return the annotation that was parsed. |
| 615 * | 617 * |
| 616 * This method assumes that the current token matches [TokenType.AT]. | 618 * This method assumes that the current token matches [TokenType.AT]. |
| 617 * | 619 * |
| 618 * annotation ::= | 620 * annotation ::= |
| 619 * '@' qualified ('.' identifier)? arguments? | 621 * '@' qualified ('.' identifier)? arguments? |
| 620 */ | 622 */ |
| 621 Annotation parseAnnotation() { | 623 Annotation parseAnnotation() { |
| 622 Token atSign = getAndAdvance(); | 624 Token atSign = getAndAdvance(); |
| 623 Identifier name = parsePrefixedIdentifier(); | 625 Identifier name = parsePrefixedIdentifier(); |
| 624 Token period = null; | 626 Token period = null; |
| 625 SimpleIdentifier constructorName = null; | 627 SimpleIdentifier constructorName = null; |
| 626 if (_matches(TokenType.PERIOD)) { | 628 if (_matches(TokenType.PERIOD)) { |
| 627 period = getAndAdvance(); | 629 period = getAndAdvance(); |
| 628 constructorName = parseSimpleIdentifier(); | 630 constructorName = parseSimpleIdentifier(); |
| 629 } | 631 } |
| 630 ArgumentList arguments = null; | 632 ArgumentList arguments = null; |
| 631 if (_matches(TokenType.OPEN_PAREN)) { | 633 if (_matches(TokenType.OPEN_PAREN)) { |
| 632 arguments = parseArgumentList(); | 634 arguments = parseArgumentList(); |
| 633 } | 635 } |
| 634 return new Annotation(atSign, name, period, constructorName, arguments); | 636 return astFactory.annotation( |
| 637 atSign, name, period, constructorName, arguments); | |
| 635 } | 638 } |
| 636 | 639 |
| 637 /** | 640 /** |
| 638 * Parse an argument. Return the argument that was parsed. | 641 * Parse an argument. Return the argument that was parsed. |
| 639 * | 642 * |
| 640 * argument ::= | 643 * argument ::= |
| 641 * namedArgument | 644 * namedArgument |
| 642 * | expression | 645 * | expression |
| 643 * | 646 * |
| 644 * namedArgument ::= | 647 * namedArgument ::= |
| 645 * label expression | 648 * label expression |
| 646 */ | 649 */ |
| 647 Expression parseArgument() { | 650 Expression parseArgument() { |
| 648 // TODO(brianwilkerson) Consider returning a wrapper indicating whether the | 651 // TODO(brianwilkerson) Consider returning a wrapper indicating whether the |
| 649 // expression is a named expression in order to remove the 'is' check in | 652 // expression is a named expression in order to remove the 'is' check in |
| 650 // 'parseArgumentList'. | 653 // 'parseArgumentList'. |
| 651 // | 654 // |
| 652 // Both namedArgument and expression can start with an identifier, but only | 655 // Both namedArgument and expression can start with an identifier, but only |
| 653 // namedArgument can have an identifier followed by a colon. | 656 // namedArgument can have an identifier followed by a colon. |
| 654 // | 657 // |
| 655 if (_matchesIdentifier() && _tokenMatches(_peek(), TokenType.COLON)) { | 658 if (_matchesIdentifier() && _tokenMatches(_peek(), TokenType.COLON)) { |
| 656 return new NamedExpression(parseLabel(), parseExpression2()); | 659 return astFactory.namedExpression(parseLabel(), parseExpression2()); |
| 657 } else { | 660 } else { |
| 658 return parseExpression2(); | 661 return parseExpression2(); |
| 659 } | 662 } |
| 660 } | 663 } |
| 661 | 664 |
| 662 /** | 665 /** |
| 663 * Parse a list of arguments. Return the argument list that was parsed. | 666 * Parse a list of arguments. Return the argument list that was parsed. |
| 664 * | 667 * |
| 665 * This method assumes that the current token matches [TokenType.OPEN_PAREN]. | 668 * This method assumes that the current token matches [TokenType.OPEN_PAREN]. |
| 666 * | 669 * |
| 667 * arguments ::= | 670 * arguments ::= |
| 668 * '(' argumentList? ')' | 671 * '(' argumentList? ')' |
| 669 * | 672 * |
| 670 * argumentList ::= | 673 * argumentList ::= |
| 671 * namedArgument (',' namedArgument)* | 674 * namedArgument (',' namedArgument)* |
| 672 * | expressionList (',' namedArgument)* | 675 * | expressionList (',' namedArgument)* |
| 673 */ | 676 */ |
| 674 ArgumentList parseArgumentList() { | 677 ArgumentList parseArgumentList() { |
| 675 Token leftParenthesis = getAndAdvance(); | 678 Token leftParenthesis = getAndAdvance(); |
| 676 if (_matches(TokenType.CLOSE_PAREN)) { | 679 if (_matches(TokenType.CLOSE_PAREN)) { |
| 677 return new ArgumentList(leftParenthesis, null, getAndAdvance()); | 680 return astFactory.argumentList(leftParenthesis, null, getAndAdvance()); |
| 678 } | 681 } |
| 679 // | 682 // |
| 680 // Even though unnamed arguments must all appear before any named arguments, | 683 // Even though unnamed arguments must all appear before any named arguments, |
| 681 // we allow them to appear in any order so that we can recover faster. | 684 // we allow them to appear in any order so that we can recover faster. |
| 682 // | 685 // |
| 683 bool wasInInitializer = _inInitializer; | 686 bool wasInInitializer = _inInitializer; |
| 684 _inInitializer = false; | 687 _inInitializer = false; |
| 685 try { | 688 try { |
| 686 Expression argument = parseArgument(); | 689 Expression argument = parseArgument(); |
| 687 List<Expression> arguments = <Expression>[argument]; | 690 List<Expression> arguments = <Expression>[argument]; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 705 generatedError = true; | 708 generatedError = true; |
| 706 } | 709 } |
| 707 } | 710 } |
| 708 } | 711 } |
| 709 } | 712 } |
| 710 // Recovery: If the next token is not a right parenthesis, look at the | 713 // Recovery: If the next token is not a right parenthesis, look at the |
| 711 // left parenthesis to see whether there is a matching right parenthesis. | 714 // left parenthesis to see whether there is a matching right parenthesis. |
| 712 // If there is, then we're more likely missing a comma and should go back | 715 // If there is, then we're more likely missing a comma and should go back |
| 713 // to parsing arguments. | 716 // to parsing arguments. |
| 714 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 717 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 715 return new ArgumentList(leftParenthesis, arguments, rightParenthesis); | 718 return astFactory.argumentList( |
| 719 leftParenthesis, arguments, rightParenthesis); | |
| 716 } finally { | 720 } finally { |
| 717 _inInitializer = wasInInitializer; | 721 _inInitializer = wasInInitializer; |
| 718 } | 722 } |
| 719 } | 723 } |
| 720 | 724 |
| 721 /** | 725 /** |
| 722 * Parse an assert statement. Return the assert statement. | 726 * Parse an assert statement. Return the assert statement. |
| 723 * | 727 * |
| 724 * This method assumes that the current token matches `Keyword.ASSERT`. | 728 * This method assumes that the current token matches `Keyword.ASSERT`. |
| 725 * | 729 * |
| 726 * assertStatement ::= | 730 * assertStatement ::= |
| 727 * 'assert' '(' expression [',' expression] ')' ';' | 731 * 'assert' '(' expression [',' expression] ')' ';' |
| 728 */ | 732 */ |
| 729 AssertStatement parseAssertStatement() { | 733 AssertStatement parseAssertStatement() { |
| 730 Token keyword = getAndAdvance(); | 734 Token keyword = getAndAdvance(); |
| 731 Token leftParen = _expect(TokenType.OPEN_PAREN); | 735 Token leftParen = _expect(TokenType.OPEN_PAREN); |
| 732 Expression expression = parseExpression2(); | 736 Expression expression = parseExpression2(); |
| 733 Token comma; | 737 Token comma; |
| 734 Expression message; | 738 Expression message; |
| 735 if (_matches(TokenType.COMMA)) { | 739 if (_matches(TokenType.COMMA)) { |
| 736 comma = getAndAdvance(); | 740 comma = getAndAdvance(); |
| 737 message = parseExpression2(); | 741 message = parseExpression2(); |
| 738 } | 742 } |
| 739 Token rightParen = _expect(TokenType.CLOSE_PAREN); | 743 Token rightParen = _expect(TokenType.CLOSE_PAREN); |
| 740 Token semicolon = _expect(TokenType.SEMICOLON); | 744 Token semicolon = _expect(TokenType.SEMICOLON); |
| 741 return new AssertStatement( | 745 return astFactory.assertStatement( |
| 742 keyword, leftParen, expression, comma, message, rightParen, semicolon); | 746 keyword, leftParen, expression, comma, message, rightParen, semicolon); |
| 743 } | 747 } |
| 744 | 748 |
| 745 /** | 749 /** |
| 746 * Parse an assignable expression. The [primaryAllowed] is `true` if the | 750 * Parse an assignable expression. The [primaryAllowed] is `true` if the |
| 747 * expression is allowed to be a primary without any assignable selector. | 751 * expression is allowed to be a primary without any assignable selector. |
| 748 * Return the assignable expression that was parsed. | 752 * Return the assignable expression that was parsed. |
| 749 * | 753 * |
| 750 * assignableExpression ::= | 754 * assignableExpression ::= |
| 751 * primary (arguments* assignableSelector)+ | 755 * primary (arguments* assignableSelector)+ |
| 752 * | 'super' unconditionalAssignableSelector | 756 * | 'super' unconditionalAssignableSelector |
| 753 * | identifier | 757 * | identifier |
| 754 */ | 758 */ |
| 755 Expression parseAssignableExpression(bool primaryAllowed) { | 759 Expression parseAssignableExpression(bool primaryAllowed) { |
| 756 if (_matchesKeyword(Keyword.SUPER)) { | 760 if (_matchesKeyword(Keyword.SUPER)) { |
| 757 return parseAssignableSelector( | 761 return parseAssignableSelector( |
| 758 new SuperExpression(getAndAdvance()), false, | 762 astFactory.superExpression(getAndAdvance()), false, |
| 759 allowConditional: false); | 763 allowConditional: false); |
| 760 } | 764 } |
| 761 return _parseAssignableExpressionNotStartingWithSuper(primaryAllowed); | 765 return _parseAssignableExpressionNotStartingWithSuper(primaryAllowed); |
| 762 } | 766 } |
| 763 | 767 |
| 764 /** | 768 /** |
| 765 * Parse an assignable selector. The [prefix] is the expression preceding the | 769 * Parse an assignable selector. The [prefix] is the expression preceding the |
| 766 * selector. The [optional] is `true` if the selector is optional. Return the | 770 * selector. The [optional] is `true` if the selector is optional. Return the |
| 767 * assignable selector that was parsed, or the original prefix if there was no | 771 * assignable selector that was parsed, or the original prefix if there was no |
| 768 * assignable selector. If [allowConditional] is false, then the '?.' | 772 * assignable selector. If [allowConditional] is false, then the '?.' |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 779 Expression parseAssignableSelector(Expression prefix, bool optional, | 783 Expression parseAssignableSelector(Expression prefix, bool optional, |
| 780 {bool allowConditional: true}) { | 784 {bool allowConditional: true}) { |
| 781 TokenType type = _currentToken.type; | 785 TokenType type = _currentToken.type; |
| 782 if (type == TokenType.OPEN_SQUARE_BRACKET) { | 786 if (type == TokenType.OPEN_SQUARE_BRACKET) { |
| 783 Token leftBracket = getAndAdvance(); | 787 Token leftBracket = getAndAdvance(); |
| 784 bool wasInInitializer = _inInitializer; | 788 bool wasInInitializer = _inInitializer; |
| 785 _inInitializer = false; | 789 _inInitializer = false; |
| 786 try { | 790 try { |
| 787 Expression index = parseExpression2(); | 791 Expression index = parseExpression2(); |
| 788 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); | 792 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); |
| 789 return new IndexExpression.forTarget( | 793 return astFactory.indexExpressionForTarget( |
| 790 prefix, leftBracket, index, rightBracket); | 794 prefix, leftBracket, index, rightBracket); |
| 791 } finally { | 795 } finally { |
| 792 _inInitializer = wasInInitializer; | 796 _inInitializer = wasInInitializer; |
| 793 } | 797 } |
| 794 } else { | 798 } else { |
| 795 bool isQuestionPeriod = type == TokenType.QUESTION_PERIOD; | 799 bool isQuestionPeriod = type == TokenType.QUESTION_PERIOD; |
| 796 if (type == TokenType.PERIOD || isQuestionPeriod) { | 800 if (type == TokenType.PERIOD || isQuestionPeriod) { |
| 797 if (isQuestionPeriod && !allowConditional) { | 801 if (isQuestionPeriod && !allowConditional) { |
| 798 _reportErrorForCurrentToken( | 802 _reportErrorForCurrentToken( |
| 799 ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, | 803 ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, |
| 800 [_currentToken.lexeme]); | 804 [_currentToken.lexeme]); |
| 801 } | 805 } |
| 802 Token operator = getAndAdvance(); | 806 Token operator = getAndAdvance(); |
| 803 return new PropertyAccess(prefix, operator, parseSimpleIdentifier()); | 807 return astFactory.propertyAccess( |
| 808 prefix, operator, parseSimpleIdentifier()); | |
| 804 } else if (type == TokenType.INDEX) { | 809 } else if (type == TokenType.INDEX) { |
| 805 _splitIndex(); | 810 _splitIndex(); |
| 806 Token leftBracket = getAndAdvance(); | 811 Token leftBracket = getAndAdvance(); |
| 807 Expression index = parseSimpleIdentifier(); | 812 Expression index = parseSimpleIdentifier(); |
| 808 Token rightBracket = getAndAdvance(); | 813 Token rightBracket = getAndAdvance(); |
| 809 return new IndexExpression.forTarget( | 814 return astFactory.indexExpressionForTarget( |
| 810 prefix, leftBracket, index, rightBracket); | 815 prefix, leftBracket, index, rightBracket); |
| 811 } else { | 816 } else { |
| 812 if (!optional) { | 817 if (!optional) { |
| 813 // Report the missing selector. | 818 // Report the missing selector. |
| 814 _reportErrorForCurrentToken( | 819 _reportErrorForCurrentToken( |
| 815 ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR); | 820 ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR); |
| 816 } | 821 } |
| 817 return prefix; | 822 return prefix; |
| 818 } | 823 } |
| 819 } | 824 } |
| 820 } | 825 } |
| 821 | 826 |
| 822 /** | 827 /** |
| 823 * Parse a await expression. Return the await expression that was parsed. | 828 * Parse a await expression. Return the await expression that was parsed. |
| 824 * | 829 * |
| 825 * This method assumes that the current token matches `_AWAIT`. | 830 * This method assumes that the current token matches `_AWAIT`. |
| 826 * | 831 * |
| 827 * awaitExpression ::= | 832 * awaitExpression ::= |
| 828 * 'await' unaryExpression | 833 * 'await' unaryExpression |
| 829 */ | 834 */ |
| 830 AwaitExpression parseAwaitExpression() { | 835 AwaitExpression parseAwaitExpression() { |
| 831 Token awaitToken = getAndAdvance(); | 836 Token awaitToken = getAndAdvance(); |
| 832 Expression expression = parseUnaryExpression(); | 837 Expression expression = parseUnaryExpression(); |
| 833 return new AwaitExpression(awaitToken, expression); | 838 return astFactory.awaitExpression(awaitToken, expression); |
| 834 } | 839 } |
| 835 | 840 |
| 836 /** | 841 /** |
| 837 * Parse a bitwise and expression. Return the bitwise and expression that was | 842 * Parse a bitwise and expression. Return the bitwise and expression that was |
| 838 * parsed. | 843 * parsed. |
| 839 * | 844 * |
| 840 * bitwiseAndExpression ::= | 845 * bitwiseAndExpression ::= |
| 841 * shiftExpression ('&' shiftExpression)* | 846 * shiftExpression ('&' shiftExpression)* |
| 842 * | 'super' ('&' shiftExpression)+ | 847 * | 'super' ('&' shiftExpression)+ |
| 843 */ | 848 */ |
| 844 Expression parseBitwiseAndExpression() { | 849 Expression parseBitwiseAndExpression() { |
| 845 Expression expression; | 850 Expression expression; |
| 846 if (_currentToken.keyword == Keyword.SUPER && | 851 if (_currentToken.keyword == Keyword.SUPER && |
| 847 _currentToken.next.type == TokenType.AMPERSAND) { | 852 _currentToken.next.type == TokenType.AMPERSAND) { |
| 848 expression = new SuperExpression(getAndAdvance()); | 853 expression = astFactory.superExpression(getAndAdvance()); |
| 849 } else { | 854 } else { |
| 850 expression = parseShiftExpression(); | 855 expression = parseShiftExpression(); |
| 851 } | 856 } |
| 852 while (_currentToken.type == TokenType.AMPERSAND) { | 857 while (_currentToken.type == TokenType.AMPERSAND) { |
| 853 expression = new BinaryExpression( | 858 expression = astFactory.binaryExpression( |
| 854 expression, getAndAdvance(), parseShiftExpression()); | 859 expression, getAndAdvance(), parseShiftExpression()); |
| 855 } | 860 } |
| 856 return expression; | 861 return expression; |
| 857 } | 862 } |
| 858 | 863 |
| 859 /** | 864 /** |
| 860 * Parse a bitwise or expression. Return the bitwise or expression that was | 865 * Parse a bitwise or expression. Return the bitwise or expression that was |
| 861 * parsed. | 866 * parsed. |
| 862 * | 867 * |
| 863 * bitwiseOrExpression ::= | 868 * bitwiseOrExpression ::= |
| 864 * bitwiseXorExpression ('|' bitwiseXorExpression)* | 869 * bitwiseXorExpression ('|' bitwiseXorExpression)* |
| 865 * | 'super' ('|' bitwiseXorExpression)+ | 870 * | 'super' ('|' bitwiseXorExpression)+ |
| 866 */ | 871 */ |
| 867 Expression parseBitwiseOrExpression() { | 872 Expression parseBitwiseOrExpression() { |
| 868 Expression expression; | 873 Expression expression; |
| 869 if (_currentToken.keyword == Keyword.SUPER && | 874 if (_currentToken.keyword == Keyword.SUPER && |
| 870 _currentToken.next.type == TokenType.BAR) { | 875 _currentToken.next.type == TokenType.BAR) { |
| 871 expression = new SuperExpression(getAndAdvance()); | 876 expression = astFactory.superExpression(getAndAdvance()); |
| 872 } else { | 877 } else { |
| 873 expression = parseBitwiseXorExpression(); | 878 expression = parseBitwiseXorExpression(); |
| 874 } | 879 } |
| 875 while (_currentToken.type == TokenType.BAR) { | 880 while (_currentToken.type == TokenType.BAR) { |
| 876 expression = new BinaryExpression( | 881 expression = astFactory.binaryExpression( |
| 877 expression, getAndAdvance(), parseBitwiseXorExpression()); | 882 expression, getAndAdvance(), parseBitwiseXorExpression()); |
| 878 } | 883 } |
| 879 return expression; | 884 return expression; |
| 880 } | 885 } |
| 881 | 886 |
| 882 /** | 887 /** |
| 883 * Parse a bitwise exclusive-or expression. Return the bitwise exclusive-or | 888 * Parse a bitwise exclusive-or expression. Return the bitwise exclusive-or |
| 884 * expression that was parsed. | 889 * expression that was parsed. |
| 885 * | 890 * |
| 886 * bitwiseXorExpression ::= | 891 * bitwiseXorExpression ::= |
| 887 * bitwiseAndExpression ('^' bitwiseAndExpression)* | 892 * bitwiseAndExpression ('^' bitwiseAndExpression)* |
| 888 * | 'super' ('^' bitwiseAndExpression)+ | 893 * | 'super' ('^' bitwiseAndExpression)+ |
| 889 */ | 894 */ |
| 890 Expression parseBitwiseXorExpression() { | 895 Expression parseBitwiseXorExpression() { |
| 891 Expression expression; | 896 Expression expression; |
| 892 if (_currentToken.keyword == Keyword.SUPER && | 897 if (_currentToken.keyword == Keyword.SUPER && |
| 893 _currentToken.next.type == TokenType.CARET) { | 898 _currentToken.next.type == TokenType.CARET) { |
| 894 expression = new SuperExpression(getAndAdvance()); | 899 expression = astFactory.superExpression(getAndAdvance()); |
| 895 } else { | 900 } else { |
| 896 expression = parseBitwiseAndExpression(); | 901 expression = parseBitwiseAndExpression(); |
| 897 } | 902 } |
| 898 while (_currentToken.type == TokenType.CARET) { | 903 while (_currentToken.type == TokenType.CARET) { |
| 899 expression = new BinaryExpression( | 904 expression = astFactory.binaryExpression( |
| 900 expression, getAndAdvance(), parseBitwiseAndExpression()); | 905 expression, getAndAdvance(), parseBitwiseAndExpression()); |
| 901 } | 906 } |
| 902 return expression; | 907 return expression; |
| 903 } | 908 } |
| 904 | 909 |
| 905 /** | 910 /** |
| 906 * Parse a block. Return the block that was parsed. | 911 * Parse a block. Return the block that was parsed. |
| 907 * | 912 * |
| 908 * This method assumes that the current token matches | 913 * This method assumes that the current token matches |
| 909 * [TokenType.OPEN_CURLY_BRACKET]. | 914 * [TokenType.OPEN_CURLY_BRACKET]. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 930 } else if (statement != null) { | 935 } else if (statement != null) { |
| 931 statements.add(statement); | 936 statements.add(statement); |
| 932 } | 937 } |
| 933 statementStart = _currentToken; | 938 statementStart = _currentToken; |
| 934 } | 939 } |
| 935 // Recovery: If the next token is not a right curly bracket, look at the | 940 // Recovery: If the next token is not a right curly bracket, look at the |
| 936 // left curly bracket to see whether there is a matching right bracket. If | 941 // left curly bracket to see whether there is a matching right bracket. If |
| 937 // there is, then we're more likely missing a semi-colon and should go back | 942 // there is, then we're more likely missing a semi-colon and should go back |
| 938 // to parsing statements. | 943 // to parsing statements. |
| 939 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 944 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 940 return new Block(leftBracket, statements, rightBracket); | 945 return astFactory.block(leftBracket, statements, rightBracket); |
| 941 } | 946 } |
| 942 | 947 |
| 943 /** | 948 /** |
| 944 * Parse a break statement. Return the break statement that was parsed. | 949 * Parse a break statement. Return the break statement that was parsed. |
| 945 * | 950 * |
| 946 * This method assumes that the current token matches `Keyword.BREAK`. | 951 * This method assumes that the current token matches `Keyword.BREAK`. |
| 947 * | 952 * |
| 948 * breakStatement ::= | 953 * breakStatement ::= |
| 949 * 'break' identifier? ';' | 954 * 'break' identifier? ';' |
| 950 */ | 955 */ |
| 951 Statement parseBreakStatement() { | 956 Statement parseBreakStatement() { |
| 952 Token breakKeyword = getAndAdvance(); | 957 Token breakKeyword = getAndAdvance(); |
| 953 SimpleIdentifier label = null; | 958 SimpleIdentifier label = null; |
| 954 if (_matchesIdentifier()) { | 959 if (_matchesIdentifier()) { |
| 955 label = _parseSimpleIdentifierUnchecked(); | 960 label = _parseSimpleIdentifierUnchecked(); |
| 956 } | 961 } |
| 957 if (!_inLoop && !_inSwitch && label == null) { | 962 if (!_inLoop && !_inSwitch && label == null) { |
| 958 _reportErrorForToken(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword); | 963 _reportErrorForToken(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword); |
| 959 } | 964 } |
| 960 Token semicolon = _expect(TokenType.SEMICOLON); | 965 Token semicolon = _expect(TokenType.SEMICOLON); |
| 961 return new BreakStatement(breakKeyword, label, semicolon); | 966 return astFactory.breakStatement(breakKeyword, label, semicolon); |
| 962 } | 967 } |
| 963 | 968 |
| 964 /** | 969 /** |
| 965 * Parse a cascade section. Return the expression representing the cascaded | 970 * Parse a cascade section. Return the expression representing the cascaded |
| 966 * method invocation. | 971 * method invocation. |
| 967 * | 972 * |
| 968 * This method assumes that the current token matches | 973 * This method assumes that the current token matches |
| 969 * `TokenType.PERIOD_PERIOD`. | 974 * `TokenType.PERIOD_PERIOD`. |
| 970 * | 975 * |
| 971 * cascadeSection ::= | 976 * cascadeSection ::= |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 985 SimpleIdentifier functionName = null; | 990 SimpleIdentifier functionName = null; |
| 986 if (_matchesIdentifier()) { | 991 if (_matchesIdentifier()) { |
| 987 functionName = _parseSimpleIdentifierUnchecked(); | 992 functionName = _parseSimpleIdentifierUnchecked(); |
| 988 } else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) { | 993 } else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) { |
| 989 Token leftBracket = getAndAdvance(); | 994 Token leftBracket = getAndAdvance(); |
| 990 bool wasInInitializer = _inInitializer; | 995 bool wasInInitializer = _inInitializer; |
| 991 _inInitializer = false; | 996 _inInitializer = false; |
| 992 try { | 997 try { |
| 993 Expression index = parseExpression2(); | 998 Expression index = parseExpression2(); |
| 994 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); | 999 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); |
| 995 expression = new IndexExpression.forCascade( | 1000 expression = astFactory.indexExpressionForCascade( |
| 996 period, leftBracket, index, rightBracket); | 1001 period, leftBracket, index, rightBracket); |
| 997 period = null; | 1002 period = null; |
| 998 } finally { | 1003 } finally { |
| 999 _inInitializer = wasInInitializer; | 1004 _inInitializer = wasInInitializer; |
| 1000 } | 1005 } |
| 1001 } else { | 1006 } else { |
| 1002 _reportErrorForToken(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, | 1007 _reportErrorForToken(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, |
| 1003 [_currentToken.lexeme]); | 1008 [_currentToken.lexeme]); |
| 1004 functionName = createSyntheticIdentifier(); | 1009 functionName = createSyntheticIdentifier(); |
| 1005 } | 1010 } |
| 1006 assert((expression == null && functionName != null) || | 1011 assert((expression == null && functionName != null) || |
| 1007 (expression != null && functionName == null)); | 1012 (expression != null && functionName == null)); |
| 1008 if (_isLikelyArgumentList()) { | 1013 if (_isLikelyArgumentList()) { |
| 1009 do { | 1014 do { |
| 1010 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 1015 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 1011 if (functionName != null) { | 1016 if (functionName != null) { |
| 1012 expression = new MethodInvocation(expression, period, functionName, | 1017 expression = astFactory.methodInvocation(expression, period, |
| 1013 typeArguments, parseArgumentList()); | 1018 functionName, typeArguments, parseArgumentList()); |
| 1014 period = null; | 1019 period = null; |
| 1015 functionName = null; | 1020 functionName = null; |
| 1016 } else if (expression == null) { | 1021 } else if (expression == null) { |
| 1017 // It should not be possible to get here. | 1022 // It should not be possible to get here. |
| 1018 expression = new MethodInvocation(expression, period, | 1023 expression = astFactory.methodInvocation(expression, period, |
| 1019 createSyntheticIdentifier(), typeArguments, parseArgumentList()); | 1024 createSyntheticIdentifier(), typeArguments, parseArgumentList()); |
| 1020 } else { | 1025 } else { |
| 1021 expression = new FunctionExpressionInvocation( | 1026 expression = astFactory.functionExpressionInvocation( |
| 1022 expression, typeArguments, parseArgumentList()); | 1027 expression, typeArguments, parseArgumentList()); |
| 1023 } | 1028 } |
| 1024 } while (_isLikelyArgumentList()); | 1029 } while (_isLikelyArgumentList()); |
| 1025 } else if (functionName != null) { | 1030 } else if (functionName != null) { |
| 1026 expression = new PropertyAccess(expression, period, functionName); | 1031 expression = astFactory.propertyAccess(expression, period, functionName); |
| 1027 period = null; | 1032 period = null; |
| 1028 } | 1033 } |
| 1029 assert(expression != null); | 1034 assert(expression != null); |
| 1030 bool progress = true; | 1035 bool progress = true; |
| 1031 while (progress) { | 1036 while (progress) { |
| 1032 progress = false; | 1037 progress = false; |
| 1033 Expression selector = parseAssignableSelector(expression, true); | 1038 Expression selector = parseAssignableSelector(expression, true); |
| 1034 if (!identical(selector, expression)) { | 1039 if (!identical(selector, expression)) { |
| 1035 expression = selector; | 1040 expression = selector; |
| 1036 progress = true; | 1041 progress = true; |
| 1037 while (_isLikelyArgumentList()) { | 1042 while (_isLikelyArgumentList()) { |
| 1038 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 1043 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 1039 Expression currentExpression = expression; | 1044 Expression currentExpression = expression; |
| 1040 if (currentExpression is PropertyAccess) { | 1045 if (currentExpression is PropertyAccess) { |
| 1041 expression = new MethodInvocation( | 1046 expression = astFactory.methodInvocation( |
| 1042 currentExpression.target, | 1047 currentExpression.target, |
| 1043 currentExpression.operator, | 1048 currentExpression.operator, |
| 1044 currentExpression.propertyName, | 1049 currentExpression.propertyName, |
| 1045 typeArguments, | 1050 typeArguments, |
| 1046 parseArgumentList()); | 1051 parseArgumentList()); |
| 1047 } else { | 1052 } else { |
| 1048 expression = new FunctionExpressionInvocation( | 1053 expression = astFactory.functionExpressionInvocation( |
| 1049 expression, typeArguments, parseArgumentList()); | 1054 expression, typeArguments, parseArgumentList()); |
| 1050 } | 1055 } |
| 1051 } | 1056 } |
| 1052 } | 1057 } |
| 1053 } | 1058 } |
| 1054 if (_currentToken.type.isAssignmentOperator) { | 1059 if (_currentToken.type.isAssignmentOperator) { |
| 1055 Token operator = getAndAdvance(); | 1060 Token operator = getAndAdvance(); |
| 1056 _ensureAssignable(expression); | 1061 _ensureAssignable(expression); |
| 1057 expression = new AssignmentExpression( | 1062 expression = astFactory.assignmentExpression( |
| 1058 expression, operator, parseExpressionWithoutCascade()); | 1063 expression, operator, parseExpressionWithoutCascade()); |
| 1059 } | 1064 } |
| 1060 return expression; | 1065 return expression; |
| 1061 } | 1066 } |
| 1062 | 1067 |
| 1063 /** | 1068 /** |
| 1064 * Parse a class declaration. The [commentAndMetadata] is the metadata to be | 1069 * Parse a class declaration. The [commentAndMetadata] is the metadata to be |
| 1065 * associated with the member. The [abstractKeyword] is the token for the | 1070 * associated with the member. The [abstractKeyword] is the token for the |
| 1066 * keyword 'abstract', or `null` if the keyword was not given. Return the | 1071 * keyword 'abstract', or `null` if the keyword was not given. Return the |
| 1067 * class declaration that was parsed. | 1072 * class declaration that was parsed. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1169 leftBracket = getAndAdvance(); | 1174 leftBracket = getAndAdvance(); |
| 1170 members = _parseClassMembers(className, _getEndToken(leftBracket)); | 1175 members = _parseClassMembers(className, _getEndToken(leftBracket)); |
| 1171 rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 1176 rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 1172 } else { | 1177 } else { |
| 1173 // Recovery: Check for an unmatched closing curly bracket and parse | 1178 // Recovery: Check for an unmatched closing curly bracket and parse |
| 1174 // members until it is reached. | 1179 // members until it is reached. |
| 1175 leftBracket = _createSyntheticToken(TokenType.OPEN_CURLY_BRACKET); | 1180 leftBracket = _createSyntheticToken(TokenType.OPEN_CURLY_BRACKET); |
| 1176 rightBracket = _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET); | 1181 rightBracket = _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET); |
| 1177 _reportErrorForCurrentToken(ParserErrorCode.MISSING_CLASS_BODY); | 1182 _reportErrorForCurrentToken(ParserErrorCode.MISSING_CLASS_BODY); |
| 1178 } | 1183 } |
| 1179 ClassDeclaration classDeclaration = new ClassDeclaration( | 1184 ClassDeclaration classDeclaration = astFactory.classDeclaration( |
| 1180 commentAndMetadata.comment, | 1185 commentAndMetadata.comment, |
| 1181 commentAndMetadata.metadata, | 1186 commentAndMetadata.metadata, |
| 1182 abstractKeyword, | 1187 abstractKeyword, |
| 1183 keyword, | 1188 keyword, |
| 1184 name, | 1189 name, |
| 1185 typeParameters, | 1190 typeParameters, |
| 1186 extendsClause, | 1191 extendsClause, |
| 1187 withClause, | 1192 withClause, |
| 1188 implementsClause, | 1193 implementsClause, |
| 1189 leftBracket, | 1194 leftBracket, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1200 * | 1205 * |
| 1201 * classMemberDefinition ::= | 1206 * classMemberDefinition ::= |
| 1202 * declaration ';' | 1207 * declaration ';' |
| 1203 * | methodSignature functionBody | 1208 * | methodSignature functionBody |
| 1204 */ | 1209 */ |
| 1205 ClassMember parseClassMember(String className) { | 1210 ClassMember parseClassMember(String className) { |
| 1206 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 1211 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 1207 Modifiers modifiers = parseModifiers(); | 1212 Modifiers modifiers = parseModifiers(); |
| 1208 Keyword keyword = _currentToken.keyword; | 1213 Keyword keyword = _currentToken.keyword; |
| 1209 if (keyword == Keyword.VOID) { | 1214 if (keyword == Keyword.VOID) { |
| 1210 TypeName returnType = | 1215 TypeName returnType = astFactory.typeName( |
| 1211 new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 1216 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 1212 keyword = _currentToken.keyword; | 1217 keyword = _currentToken.keyword; |
| 1213 Token next = _peek(); | 1218 Token next = _peek(); |
| 1214 bool isFollowedByIdentifier = _tokenMatchesIdentifier(next); | 1219 bool isFollowedByIdentifier = _tokenMatchesIdentifier(next); |
| 1215 if (keyword == Keyword.GET && isFollowedByIdentifier) { | 1220 if (keyword == Keyword.GET && isFollowedByIdentifier) { |
| 1216 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1221 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1217 return parseGetter(commentAndMetadata, modifiers.externalKeyword, | 1222 return parseGetter(commentAndMetadata, modifiers.externalKeyword, |
| 1218 modifiers.staticKeyword, returnType); | 1223 modifiers.staticKeyword, returnType); |
| 1219 } else if (keyword == Keyword.SET && isFollowedByIdentifier) { | 1224 } else if (keyword == Keyword.SET && isFollowedByIdentifier) { |
| 1220 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1225 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1221 return parseSetter(commentAndMetadata, modifiers.externalKeyword, | 1226 return parseSetter(commentAndMetadata, modifiers.externalKeyword, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1320 keyword = modifiers.finalKeyword; | 1325 keyword = modifiers.finalKeyword; |
| 1321 } | 1326 } |
| 1322 if (keyword == null) { | 1327 if (keyword == null) { |
| 1323 keyword = modifiers.constKeyword; | 1328 keyword = modifiers.constKeyword; |
| 1324 } | 1329 } |
| 1325 if (keyword != null) { | 1330 if (keyword != null) { |
| 1326 // | 1331 // |
| 1327 // We appear to have found an incomplete field declaration. | 1332 // We appear to have found an incomplete field declaration. |
| 1328 // | 1333 // |
| 1329 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); | 1334 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); |
| 1330 VariableDeclaration variable = | 1335 VariableDeclaration variable = astFactory.variableDeclaration( |
| 1331 new VariableDeclaration(createSyntheticIdentifier(), null, null); | 1336 createSyntheticIdentifier(), null, null); |
| 1332 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; | 1337 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; |
| 1333 return new FieldDeclaration( | 1338 return astFactory.fieldDeclaration( |
| 1334 commentAndMetadata.comment, | 1339 commentAndMetadata.comment, |
| 1335 commentAndMetadata.metadata, | 1340 commentAndMetadata.metadata, |
| 1336 null, | 1341 null, |
| 1337 new VariableDeclarationList(null, null, keyword, null, variables), | 1342 astFactory.variableDeclarationList( |
| 1343 null, null, keyword, null, variables), | |
| 1338 _expect(TokenType.SEMICOLON)); | 1344 _expect(TokenType.SEMICOLON)); |
| 1339 } | 1345 } |
| 1340 _reportErrorForToken( | 1346 _reportErrorForToken( |
| 1341 ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken); | 1347 ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken); |
| 1342 if (commentAndMetadata.comment != null || | 1348 if (commentAndMetadata.comment != null || |
| 1343 commentAndMetadata.hasMetadata) { | 1349 commentAndMetadata.hasMetadata) { |
| 1344 // | 1350 // |
| 1345 // We appear to have found an incomplete declaration at the end of the | 1351 // We appear to have found an incomplete declaration at the end of the |
| 1346 // class. At this point it consists of a metadata, which we don't want | 1352 // class. At this point it consists of a metadata, which we don't want |
| 1347 // to loose, so we'll treat it as a method declaration with a missing | 1353 // to loose, so we'll treat it as a method declaration with a missing |
| 1348 // name, parameters and empty body. | 1354 // name, parameters and empty body. |
| 1349 // | 1355 // |
| 1350 return new MethodDeclaration( | 1356 return astFactory.methodDeclaration( |
| 1351 commentAndMetadata.comment, | 1357 commentAndMetadata.comment, |
| 1352 commentAndMetadata.metadata, | 1358 commentAndMetadata.metadata, |
| 1353 null, | 1359 null, |
| 1354 null, | 1360 null, |
| 1355 null, | 1361 null, |
| 1356 null, | 1362 null, |
| 1357 null, | 1363 null, |
| 1358 createSyntheticIdentifier(isDeclaration: true), | 1364 createSyntheticIdentifier(isDeclaration: true), |
| 1359 null, | 1365 null, |
| 1360 new FormalParameterList( | 1366 astFactory.formalParameterList( |
| 1361 null, <FormalParameter>[], null, null, null), | 1367 null, <FormalParameter>[], null, null, null), |
| 1362 new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON))); | 1368 astFactory |
| 1369 .emptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON))); | |
| 1363 } | 1370 } |
| 1364 return null; | 1371 return null; |
| 1365 } else if (_tokenMatches(next, TokenType.PERIOD) && | 1372 } else if (_tokenMatches(next, TokenType.PERIOD) && |
| 1366 _tokenMatchesIdentifier(_peekAt(2)) && | 1373 _tokenMatchesIdentifier(_peekAt(2)) && |
| 1367 _tokenMatches(_peekAt(3), TokenType.OPEN_PAREN)) { | 1374 _tokenMatches(_peekAt(3), TokenType.OPEN_PAREN)) { |
| 1368 return _parseConstructor( | 1375 return _parseConstructor( |
| 1369 commentAndMetadata, | 1376 commentAndMetadata, |
| 1370 modifiers.externalKeyword, | 1377 modifiers.externalKeyword, |
| 1371 _validateModifiersForConstructor(modifiers), | 1378 _validateModifiersForConstructor(modifiers), |
| 1372 modifiers.factoryKeyword, | 1379 modifiers.factoryKeyword, |
| 1373 parseSimpleIdentifier(), | 1380 parseSimpleIdentifier(), |
| 1374 getAndAdvance(), | 1381 getAndAdvance(), |
| 1375 parseSimpleIdentifier(isDeclaration: true), | 1382 parseSimpleIdentifier(isDeclaration: true), |
| 1376 parseFormalParameterList()); | 1383 parseFormalParameterList()); |
| 1377 } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) { | 1384 } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) { |
| 1378 TypeName returnType = _parseOptionalTypeNameComment(); | 1385 TypeName returnType = _parseOptionalTypeNameComment(); |
| 1379 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); | 1386 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); |
| 1380 TypeParameterList typeParameters = _parseGenericCommentTypeParameters(); | 1387 TypeParameterList typeParameters = _parseGenericCommentTypeParameters(); |
| 1381 FormalParameterList parameters = parseFormalParameterList(); | 1388 FormalParameterList parameters = parseFormalParameterList(); |
| 1382 if (_matches(TokenType.COLON) || | 1389 if (_matches(TokenType.COLON) || |
| 1383 modifiers.factoryKeyword != null || | 1390 modifiers.factoryKeyword != null || |
| 1384 methodName.name == className) { | 1391 methodName.name == className) { |
| 1385 return _parseConstructor( | 1392 return _parseConstructor( |
| 1386 commentAndMetadata, | 1393 commentAndMetadata, |
| 1387 modifiers.externalKeyword, | 1394 modifiers.externalKeyword, |
| 1388 _validateModifiersForConstructor(modifiers), | 1395 _validateModifiersForConstructor(modifiers), |
| 1389 modifiers.factoryKeyword, | 1396 modifiers.factoryKeyword, |
| 1390 new SimpleIdentifier(methodName.token, isDeclaration: false), | 1397 astFactory.simpleIdentifier(methodName.token, isDeclaration: false), |
| 1391 null, | 1398 null, |
| 1392 null, | 1399 null, |
| 1393 parameters); | 1400 parameters); |
| 1394 } | 1401 } |
| 1395 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1402 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1396 _validateFormalParameterList(parameters); | 1403 _validateFormalParameterList(parameters); |
| 1397 return _parseMethodDeclarationAfterParameters( | 1404 return _parseMethodDeclarationAfterParameters( |
| 1398 commentAndMetadata, | 1405 commentAndMetadata, |
| 1399 modifiers.externalKeyword, | 1406 modifiers.externalKeyword, |
| 1400 modifiers.staticKeyword, | 1407 modifiers.staticKeyword, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 _parseSimpleIdentifierUnchecked(isDeclaration: true); | 1495 _parseSimpleIdentifierUnchecked(isDeclaration: true); |
| 1489 TypeParameterList typeParameters = _parseGenericCommentTypeParameters(); | 1496 TypeParameterList typeParameters = _parseGenericCommentTypeParameters(); |
| 1490 FormalParameterList parameters = parseFormalParameterList(); | 1497 FormalParameterList parameters = parseFormalParameterList(); |
| 1491 if (methodName.name == className) { | 1498 if (methodName.name == className) { |
| 1492 _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type); | 1499 _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type); |
| 1493 return _parseConstructor( | 1500 return _parseConstructor( |
| 1494 commentAndMetadata, | 1501 commentAndMetadata, |
| 1495 modifiers.externalKeyword, | 1502 modifiers.externalKeyword, |
| 1496 _validateModifiersForConstructor(modifiers), | 1503 _validateModifiersForConstructor(modifiers), |
| 1497 modifiers.factoryKeyword, | 1504 modifiers.factoryKeyword, |
| 1498 new SimpleIdentifier(methodName.token, isDeclaration: true), | 1505 astFactory.simpleIdentifier(methodName.token, isDeclaration: true), |
| 1499 null, | 1506 null, |
| 1500 null, | 1507 null, |
| 1501 parameters); | 1508 parameters); |
| 1502 } | 1509 } |
| 1503 _validateModifiersForGetterOrSetterOrMethod(modifiers); | 1510 _validateModifiersForGetterOrSetterOrMethod(modifiers); |
| 1504 _validateFormalParameterList(parameters); | 1511 _validateFormalParameterList(parameters); |
| 1505 return _parseMethodDeclarationAfterParameters( | 1512 return _parseMethodDeclarationAfterParameters( |
| 1506 commentAndMetadata, | 1513 commentAndMetadata, |
| 1507 modifiers.externalKeyword, | 1514 modifiers.externalKeyword, |
| 1508 modifiers.staticKeyword, | 1515 modifiers.staticKeyword, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1556 /** | 1563 /** |
| 1557 * Parse a single combinator. Return the combinator that was parsed, or `null` | 1564 * Parse a single combinator. Return the combinator that was parsed, or `null` |
| 1558 * if no combinator is found. | 1565 * if no combinator is found. |
| 1559 * | 1566 * |
| 1560 * combinator ::= | 1567 * combinator ::= |
| 1561 * 'show' identifier (',' identifier)* | 1568 * 'show' identifier (',' identifier)* |
| 1562 * | 'hide' identifier (',' identifier)* | 1569 * | 'hide' identifier (',' identifier)* |
| 1563 */ | 1570 */ |
| 1564 Combinator parseCombinator() { | 1571 Combinator parseCombinator() { |
| 1565 if (_matchesString(_SHOW)) { | 1572 if (_matchesString(_SHOW)) { |
| 1566 return new ShowCombinator(getAndAdvance(), parseIdentifierList()); | 1573 return astFactory.showCombinator(getAndAdvance(), parseIdentifierList()); |
| 1567 } else if (_matchesString(_HIDE)) { | 1574 } else if (_matchesString(_HIDE)) { |
| 1568 return new HideCombinator(getAndAdvance(), parseIdentifierList()); | 1575 return astFactory.hideCombinator(getAndAdvance(), parseIdentifierList()); |
| 1569 } | 1576 } |
| 1570 return null; | 1577 return null; |
| 1571 } | 1578 } |
| 1572 | 1579 |
| 1573 /** | 1580 /** |
| 1574 * Parse a list of combinators in a directive. Return the combinators that | 1581 * Parse a list of combinators in a directive. Return the combinators that |
| 1575 * were parsed, or `null` if there are no combinators. | 1582 * were parsed, or `null` if there are no combinators. |
| 1576 * | 1583 * |
| 1577 * combinator ::= | 1584 * combinator ::= |
| 1578 * 'show' identifier (',' identifier)* | 1585 * 'show' identifier (',' identifier)* |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1638 null, new SubSequenceReader(referenceSource, sourceOffset), listener); | 1645 null, new SubSequenceReader(referenceSource, sourceOffset), listener); |
| 1639 scanner.setSourceStart(1, 1); | 1646 scanner.setSourceStart(1, 1); |
| 1640 Token firstToken = scanner.tokenize(); | 1647 Token firstToken = scanner.tokenize(); |
| 1641 if (listener.errorReported) { | 1648 if (listener.errorReported) { |
| 1642 return null; | 1649 return null; |
| 1643 } | 1650 } |
| 1644 if (firstToken.type == TokenType.EOF) { | 1651 if (firstToken.type == TokenType.EOF) { |
| 1645 Token syntheticToken = | 1652 Token syntheticToken = |
| 1646 new SyntheticStringToken(TokenType.IDENTIFIER, "", sourceOffset); | 1653 new SyntheticStringToken(TokenType.IDENTIFIER, "", sourceOffset); |
| 1647 syntheticToken.setNext(firstToken); | 1654 syntheticToken.setNext(firstToken); |
| 1648 return new CommentReference(null, new SimpleIdentifier(syntheticToken)); | 1655 return astFactory.commentReference( |
| 1656 null, astFactory.simpleIdentifier(syntheticToken)); | |
| 1649 } | 1657 } |
| 1650 Token newKeyword = null; | 1658 Token newKeyword = null; |
| 1651 if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) { | 1659 if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) { |
| 1652 newKeyword = firstToken; | 1660 newKeyword = firstToken; |
| 1653 firstToken = firstToken.next; | 1661 firstToken = firstToken.next; |
| 1654 } | 1662 } |
| 1655 if (firstToken.isUserDefinableOperator) { | 1663 if (firstToken.isUserDefinableOperator) { |
| 1656 if (firstToken.next.type != TokenType.EOF) { | 1664 if (firstToken.next.type != TokenType.EOF) { |
| 1657 return null; | 1665 return null; |
| 1658 } | 1666 } |
| 1659 Identifier identifier = new SimpleIdentifier(firstToken); | 1667 Identifier identifier = astFactory.simpleIdentifier(firstToken); |
| 1660 return new CommentReference(null, identifier); | 1668 return astFactory.commentReference(null, identifier); |
| 1661 } else if (_tokenMatchesKeyword(firstToken, Keyword.OPERATOR)) { | 1669 } else if (_tokenMatchesKeyword(firstToken, Keyword.OPERATOR)) { |
| 1662 Token secondToken = firstToken.next; | 1670 Token secondToken = firstToken.next; |
| 1663 if (secondToken.isUserDefinableOperator) { | 1671 if (secondToken.isUserDefinableOperator) { |
| 1664 if (secondToken.next.type != TokenType.EOF) { | 1672 if (secondToken.next.type != TokenType.EOF) { |
| 1665 return null; | 1673 return null; |
| 1666 } | 1674 } |
| 1667 Identifier identifier = new SimpleIdentifier(secondToken); | 1675 Identifier identifier = astFactory.simpleIdentifier(secondToken); |
| 1668 return new CommentReference(null, identifier); | 1676 return astFactory.commentReference(null, identifier); |
| 1669 } | 1677 } |
| 1670 return null; | 1678 return null; |
| 1671 } else if (_tokenMatchesIdentifier(firstToken)) { | 1679 } else if (_tokenMatchesIdentifier(firstToken)) { |
| 1672 Token secondToken = firstToken.next; | 1680 Token secondToken = firstToken.next; |
| 1673 Token thirdToken = secondToken.next; | 1681 Token thirdToken = secondToken.next; |
| 1674 Token nextToken; | 1682 Token nextToken; |
| 1675 Identifier identifier; | 1683 Identifier identifier; |
| 1676 if (_tokenMatches(secondToken, TokenType.PERIOD)) { | 1684 if (_tokenMatches(secondToken, TokenType.PERIOD)) { |
| 1677 if (thirdToken.isUserDefinableOperator) { | 1685 if (thirdToken.isUserDefinableOperator) { |
| 1678 identifier = new PrefixedIdentifier( | 1686 identifier = astFactory.prefixedIdentifier( |
| 1679 new SimpleIdentifier(firstToken), | 1687 astFactory.simpleIdentifier(firstToken), |
| 1680 secondToken, | 1688 secondToken, |
| 1681 new SimpleIdentifier(thirdToken)); | 1689 astFactory.simpleIdentifier(thirdToken)); |
| 1682 nextToken = thirdToken.next; | 1690 nextToken = thirdToken.next; |
| 1683 } else if (_tokenMatchesKeyword(thirdToken, Keyword.OPERATOR)) { | 1691 } else if (_tokenMatchesKeyword(thirdToken, Keyword.OPERATOR)) { |
| 1684 Token fourthToken = thirdToken.next; | 1692 Token fourthToken = thirdToken.next; |
| 1685 if (fourthToken.isUserDefinableOperator) { | 1693 if (fourthToken.isUserDefinableOperator) { |
| 1686 identifier = new PrefixedIdentifier( | 1694 identifier = astFactory.prefixedIdentifier( |
| 1687 new SimpleIdentifier(firstToken), | 1695 astFactory.simpleIdentifier(firstToken), |
| 1688 secondToken, | 1696 secondToken, |
| 1689 new SimpleIdentifier(fourthToken)); | 1697 astFactory.simpleIdentifier(fourthToken)); |
| 1690 nextToken = fourthToken.next; | 1698 nextToken = fourthToken.next; |
| 1691 } else { | 1699 } else { |
| 1692 return null; | 1700 return null; |
| 1693 } | 1701 } |
| 1694 } else if (_tokenMatchesIdentifier(thirdToken)) { | 1702 } else if (_tokenMatchesIdentifier(thirdToken)) { |
| 1695 identifier = new PrefixedIdentifier( | 1703 identifier = astFactory.prefixedIdentifier( |
| 1696 new SimpleIdentifier(firstToken), | 1704 astFactory.simpleIdentifier(firstToken), |
| 1697 secondToken, | 1705 secondToken, |
| 1698 new SimpleIdentifier(thirdToken)); | 1706 astFactory.simpleIdentifier(thirdToken)); |
| 1699 nextToken = thirdToken.next; | 1707 nextToken = thirdToken.next; |
| 1700 } | 1708 } |
| 1701 } else { | 1709 } else { |
| 1702 identifier = new SimpleIdentifier(firstToken); | 1710 identifier = astFactory.simpleIdentifier(firstToken); |
| 1703 nextToken = firstToken.next; | 1711 nextToken = firstToken.next; |
| 1704 } | 1712 } |
| 1705 if (nextToken.type != TokenType.EOF) { | 1713 if (nextToken.type != TokenType.EOF) { |
| 1706 return null; | 1714 return null; |
| 1707 } | 1715 } |
| 1708 return new CommentReference(newKeyword, identifier); | 1716 return astFactory.commentReference(newKeyword, identifier); |
| 1709 } else { | 1717 } else { |
| 1710 Keyword keyword = firstToken.keyword; | 1718 Keyword keyword = firstToken.keyword; |
| 1711 if (keyword == Keyword.THIS || | 1719 if (keyword == Keyword.THIS || |
| 1712 keyword == Keyword.NULL || | 1720 keyword == Keyword.NULL || |
| 1713 keyword == Keyword.TRUE || | 1721 keyword == Keyword.TRUE || |
| 1714 keyword == Keyword.FALSE) { | 1722 keyword == Keyword.FALSE) { |
| 1715 // TODO(brianwilkerson) If we want to support this we will need to | 1723 // TODO(brianwilkerson) If we want to support this we will need to |
| 1716 // extend the definition of CommentReference to take an expression | 1724 // extend the definition of CommentReference to take an expression |
| 1717 // rather than an identifier. For now we just ignore it to reduce the | 1725 // rather than an identifier. For now we just ignore it to reduce the |
| 1718 // number of errors produced, but that's probably not a valid long ter m | 1726 // number of errors produced, but that's probably not a valid long ter m |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1788 int nameEnd = StringUtilities.indexOfFirstNotLetterDigit( | 1796 int nameEnd = StringUtilities.indexOfFirstNotLetterDigit( |
| 1789 comment, leftIndex + 1); | 1797 comment, leftIndex + 1); |
| 1790 String name = comment.substring(leftIndex + 1, nameEnd); | 1798 String name = comment.substring(leftIndex + 1, nameEnd); |
| 1791 nameToken = | 1799 nameToken = |
| 1792 new StringToken(TokenType.IDENTIFIER, name, nameOffset); | 1800 new StringToken(TokenType.IDENTIFIER, name, nameOffset); |
| 1793 } else { | 1801 } else { |
| 1794 nameToken = new SyntheticStringToken( | 1802 nameToken = new SyntheticStringToken( |
| 1795 TokenType.IDENTIFIER, '', nameOffset); | 1803 TokenType.IDENTIFIER, '', nameOffset); |
| 1796 } | 1804 } |
| 1797 nameToken.setNext(new SimpleToken(TokenType.EOF, nameToken.end)); | 1805 nameToken.setNext(new SimpleToken(TokenType.EOF, nameToken.end)); |
| 1798 references.add( | 1806 references.add(astFactory.commentReference( |
| 1799 new CommentReference(null, new SimpleIdentifier(nameToken))); | 1807 null, astFactory.simpleIdentifier(nameToken))); |
| 1800 token.references.add(nameToken); | 1808 token.references.add(nameToken); |
| 1801 // next character | 1809 // next character |
| 1802 rightIndex = leftIndex + 1; | 1810 rightIndex = leftIndex + 1; |
| 1803 } | 1811 } |
| 1804 leftIndex = comment.indexOf('[', rightIndex); | 1812 leftIndex = comment.indexOf('[', rightIndex); |
| 1805 } else { | 1813 } else { |
| 1806 leftIndex = comment.indexOf('[', range[1]); | 1814 leftIndex = comment.indexOf('[', range[1]); |
| 1807 } | 1815 } |
| 1808 } | 1816 } |
| 1809 } | 1817 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1833 * scriptTag? topLevelElement* | 1841 * scriptTag? topLevelElement* |
| 1834 * | 1842 * |
| 1835 * topLevelElement ::= | 1843 * topLevelElement ::= |
| 1836 * directive | 1844 * directive |
| 1837 * | topLevelDeclaration | 1845 * | topLevelDeclaration |
| 1838 */ | 1846 */ |
| 1839 CompilationUnit parseCompilationUnit2() { | 1847 CompilationUnit parseCompilationUnit2() { |
| 1840 Token firstToken = _currentToken; | 1848 Token firstToken = _currentToken; |
| 1841 ScriptTag scriptTag = null; | 1849 ScriptTag scriptTag = null; |
| 1842 if (_matches(TokenType.SCRIPT_TAG)) { | 1850 if (_matches(TokenType.SCRIPT_TAG)) { |
| 1843 scriptTag = new ScriptTag(getAndAdvance()); | 1851 scriptTag = astFactory.scriptTag(getAndAdvance()); |
| 1844 } | 1852 } |
| 1845 // | 1853 // |
| 1846 // Even though all directives must appear before declarations and must occur | 1854 // Even though all directives must appear before declarations and must occur |
| 1847 // in a given order, we allow directives and declarations to occur in any | 1855 // in a given order, we allow directives and declarations to occur in any |
| 1848 // order so that we can recover better. | 1856 // order so that we can recover better. |
| 1849 // | 1857 // |
| 1850 bool libraryDirectiveFound = false; | 1858 bool libraryDirectiveFound = false; |
| 1851 bool partOfDirectiveFound = false; | 1859 bool partOfDirectiveFound = false; |
| 1852 bool partDirectiveFound = false; | 1860 bool partDirectiveFound = false; |
| 1853 bool directiveFoundAfterDeclaration = false; | 1861 bool directiveFoundAfterDeclaration = false; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1964 _reportErrorForToken(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, | 1972 _reportErrorForToken(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES, |
| 1965 directive.partKeyword); | 1973 directive.partKeyword); |
| 1966 } | 1974 } |
| 1967 } else { | 1975 } else { |
| 1968 _reportErrorForToken(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, | 1976 _reportErrorForToken(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, |
| 1969 directives[i].keyword); | 1977 directives[i].keyword); |
| 1970 } | 1978 } |
| 1971 // } | 1979 // } |
| 1972 } | 1980 } |
| 1973 } | 1981 } |
| 1974 return new CompilationUnit( | 1982 return astFactory.compilationUnit( |
| 1975 firstToken, scriptTag, directives, declarations, _currentToken); | 1983 firstToken, scriptTag, directives, declarations, _currentToken); |
| 1976 } | 1984 } |
| 1977 | 1985 |
| 1978 /** | 1986 /** |
| 1979 * Parse a compilation unit member. The [commentAndMetadata] is the metadata | 1987 * Parse a compilation unit member. The [commentAndMetadata] is the metadata |
| 1980 * to be associated with the member. Return the compilation unit member that | 1988 * to be associated with the member. Return the compilation unit member that |
| 1981 * was parsed, or `null` if what was parsed could not be represented as a | 1989 * was parsed, or `null` if what was parsed could not be represented as a |
| 1982 * compilation unit member. | 1990 * compilation unit member. |
| 1983 * | 1991 * |
| 1984 * compilationUnitMember ::= | 1992 * compilationUnitMember ::= |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2005 if (keyword == Keyword.TYPEDEF && | 2013 if (keyword == Keyword.TYPEDEF && |
| 2006 nextType != TokenType.PERIOD && | 2014 nextType != TokenType.PERIOD && |
| 2007 nextType != TokenType.LT && | 2015 nextType != TokenType.LT && |
| 2008 nextType != TokenType.OPEN_PAREN) { | 2016 nextType != TokenType.OPEN_PAREN) { |
| 2009 _validateModifiersForTypedef(modifiers); | 2017 _validateModifiersForTypedef(modifiers); |
| 2010 return parseTypeAlias(commentAndMetadata); | 2018 return parseTypeAlias(commentAndMetadata); |
| 2011 } else if (keyword == Keyword.ENUM) { | 2019 } else if (keyword == Keyword.ENUM) { |
| 2012 _validateModifiersForEnum(modifiers); | 2020 _validateModifiersForEnum(modifiers); |
| 2013 return parseEnumDeclaration(commentAndMetadata); | 2021 return parseEnumDeclaration(commentAndMetadata); |
| 2014 } else if (keyword == Keyword.VOID) { | 2022 } else if (keyword == Keyword.VOID) { |
| 2015 TypeName returnType = | 2023 TypeName returnType = astFactory.typeName( |
| 2016 new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 2024 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 2017 keyword = _currentToken.keyword; | 2025 keyword = _currentToken.keyword; |
| 2018 next = _peek(); | 2026 next = _peek(); |
| 2019 if ((keyword == Keyword.GET || keyword == Keyword.SET) && | 2027 if ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 2020 _tokenMatchesIdentifier(next)) { | 2028 _tokenMatchesIdentifier(next)) { |
| 2021 _validateModifiersForTopLevelFunction(modifiers); | 2029 _validateModifiersForTopLevelFunction(modifiers); |
| 2022 return parseFunctionDeclaration( | 2030 return parseFunctionDeclaration( |
| 2023 commentAndMetadata, modifiers.externalKeyword, returnType); | 2031 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2024 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { | 2032 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { |
| 2025 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); | 2033 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); |
| 2026 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( | 2034 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2045 if (_matchesIdentifier()) { | 2053 if (_matchesIdentifier()) { |
| 2046 if (next.matchesAny(const <TokenType>[ | 2054 if (next.matchesAny(const <TokenType>[ |
| 2047 TokenType.EQ, | 2055 TokenType.EQ, |
| 2048 TokenType.COMMA, | 2056 TokenType.COMMA, |
| 2049 TokenType.SEMICOLON | 2057 TokenType.SEMICOLON |
| 2050 ])) { | 2058 ])) { |
| 2051 // | 2059 // |
| 2052 // We appear to have a variable declaration with a type of "void". | 2060 // We appear to have a variable declaration with a type of "void". |
| 2053 // | 2061 // |
| 2054 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); | 2062 _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType); |
| 2055 return new TopLevelVariableDeclaration( | 2063 return astFactory.topLevelVariableDeclaration( |
| 2056 commentAndMetadata.comment, | 2064 commentAndMetadata.comment, |
| 2057 commentAndMetadata.metadata, | 2065 commentAndMetadata.metadata, |
| 2058 parseVariableDeclarationListAfterType(null, | 2066 parseVariableDeclarationListAfterType(null, |
| 2059 _validateModifiersForTopLevelVariable(modifiers), null), | 2067 _validateModifiersForTopLevelVariable(modifiers), null), |
| 2060 _expect(TokenType.SEMICOLON)); | 2068 _expect(TokenType.SEMICOLON)); |
| 2061 } | 2069 } |
| 2062 } | 2070 } |
| 2063 _reportErrorForToken( | 2071 _reportErrorForToken( |
| 2064 ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); | 2072 ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); |
| 2065 return null; | 2073 return null; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2082 keyword = modifiers.finalKeyword; | 2090 keyword = modifiers.finalKeyword; |
| 2083 } | 2091 } |
| 2084 if (keyword == null) { | 2092 if (keyword == null) { |
| 2085 keyword = modifiers.constKeyword; | 2093 keyword = modifiers.constKeyword; |
| 2086 } | 2094 } |
| 2087 if (keyword != null) { | 2095 if (keyword != null) { |
| 2088 // | 2096 // |
| 2089 // We appear to have found an incomplete top-level variable declaration. | 2097 // We appear to have found an incomplete top-level variable declaration. |
| 2090 // | 2098 // |
| 2091 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); | 2099 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); |
| 2092 VariableDeclaration variable = | 2100 VariableDeclaration variable = astFactory.variableDeclaration( |
| 2093 new VariableDeclaration(createSyntheticIdentifier(), null, null); | 2101 createSyntheticIdentifier(), null, null); |
| 2094 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; | 2102 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; |
| 2095 return new TopLevelVariableDeclaration( | 2103 return astFactory.topLevelVariableDeclaration( |
| 2096 commentAndMetadata.comment, | 2104 commentAndMetadata.comment, |
| 2097 commentAndMetadata.metadata, | 2105 commentAndMetadata.metadata, |
| 2098 new VariableDeclarationList(null, null, keyword, null, variables), | 2106 astFactory.variableDeclarationList( |
| 2107 null, null, keyword, null, variables), | |
| 2099 _expect(TokenType.SEMICOLON)); | 2108 _expect(TokenType.SEMICOLON)); |
| 2100 } | 2109 } |
| 2101 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); | 2110 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); |
| 2102 return null; | 2111 return null; |
| 2103 } else if (_isPeekGenericTypeParametersAndOpenParen()) { | 2112 } else if (_isPeekGenericTypeParametersAndOpenParen()) { |
| 2104 return parseFunctionDeclaration( | 2113 return parseFunctionDeclaration( |
| 2105 commentAndMetadata, modifiers.externalKeyword, null); | 2114 commentAndMetadata, modifiers.externalKeyword, null); |
| 2106 } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) { | 2115 } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) { |
| 2107 TypeName returnType = _parseOptionalTypeNameComment(); | 2116 TypeName returnType = _parseOptionalTypeNameComment(); |
| 2108 _validateModifiersForTopLevelFunction(modifiers); | 2117 _validateModifiersForTopLevelFunction(modifiers); |
| 2109 return parseFunctionDeclaration( | 2118 return parseFunctionDeclaration( |
| 2110 commentAndMetadata, modifiers.externalKeyword, returnType); | 2119 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2111 } else if (next.matchesAny(const <TokenType>[ | 2120 } else if (next.matchesAny(const <TokenType>[ |
| 2112 TokenType.EQ, | 2121 TokenType.EQ, |
| 2113 TokenType.COMMA, | 2122 TokenType.COMMA, |
| 2114 TokenType.SEMICOLON | 2123 TokenType.SEMICOLON |
| 2115 ])) { | 2124 ])) { |
| 2116 if (modifiers.constKeyword == null && | 2125 if (modifiers.constKeyword == null && |
| 2117 modifiers.finalKeyword == null && | 2126 modifiers.finalKeyword == null && |
| 2118 modifiers.varKeyword == null) { | 2127 modifiers.varKeyword == null) { |
| 2119 _reportErrorForCurrentToken( | 2128 _reportErrorForCurrentToken( |
| 2120 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); | 2129 ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE); |
| 2121 } | 2130 } |
| 2122 return new TopLevelVariableDeclaration( | 2131 return astFactory.topLevelVariableDeclaration( |
| 2123 commentAndMetadata.comment, | 2132 commentAndMetadata.comment, |
| 2124 commentAndMetadata.metadata, | 2133 commentAndMetadata.metadata, |
| 2125 parseVariableDeclarationListAfterType( | 2134 parseVariableDeclarationListAfterType( |
| 2126 null, _validateModifiersForTopLevelVariable(modifiers), null), | 2135 null, _validateModifiersForTopLevelVariable(modifiers), null), |
| 2127 _expect(TokenType.SEMICOLON)); | 2136 _expect(TokenType.SEMICOLON)); |
| 2128 } | 2137 } |
| 2129 TypeName returnType = parseReturnType(); | 2138 TypeName returnType = parseReturnType(); |
| 2130 keyword = _currentToken.keyword; | 2139 keyword = _currentToken.keyword; |
| 2131 next = _peek(); | 2140 next = _peek(); |
| 2132 if ((keyword == Keyword.GET || keyword == Keyword.SET) && | 2141 if ((keyword == Keyword.GET || keyword == Keyword.SET) && |
| 2133 _tokenMatchesIdentifier(next)) { | 2142 _tokenMatchesIdentifier(next)) { |
| 2134 _validateModifiersForTopLevelFunction(modifiers); | 2143 _validateModifiersForTopLevelFunction(modifiers); |
| 2135 return parseFunctionDeclaration( | 2144 return parseFunctionDeclaration( |
| 2136 commentAndMetadata, modifiers.externalKeyword, returnType); | 2145 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2137 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { | 2146 } else if (keyword == Keyword.OPERATOR && _isOperator(next)) { |
| 2138 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); | 2147 _reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken); |
| 2139 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( | 2148 return _convertToFunctionDeclaration(_parseOperatorAfterKeyword( |
| 2140 commentAndMetadata, | 2149 commentAndMetadata, |
| 2141 modifiers.externalKeyword, | 2150 modifiers.externalKeyword, |
| 2142 returnType, | 2151 returnType, |
| 2143 getAndAdvance())); | 2152 getAndAdvance())); |
| 2144 } else if (_matches(TokenType.AT)) { | 2153 } else if (_matches(TokenType.AT)) { |
| 2145 return new TopLevelVariableDeclaration( | 2154 return astFactory.topLevelVariableDeclaration( |
| 2146 commentAndMetadata.comment, | 2155 commentAndMetadata.comment, |
| 2147 commentAndMetadata.metadata, | 2156 commentAndMetadata.metadata, |
| 2148 parseVariableDeclarationListAfterType(null, | 2157 parseVariableDeclarationListAfterType(null, |
| 2149 _validateModifiersForTopLevelVariable(modifiers), returnType), | 2158 _validateModifiersForTopLevelVariable(modifiers), returnType), |
| 2150 _expect(TokenType.SEMICOLON)); | 2159 _expect(TokenType.SEMICOLON)); |
| 2151 } else if (!_matchesIdentifier()) { | 2160 } else if (!_matchesIdentifier()) { |
| 2152 // TODO(brianwilkerson) Generalize this error. We could also be parsing a | 2161 // TODO(brianwilkerson) Generalize this error. We could also be parsing a |
| 2153 // top-level variable at this point. | 2162 // top-level variable at this point. |
| 2154 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); | 2163 _reportErrorForToken(ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken); |
| 2155 Token semicolon; | 2164 Token semicolon; |
| 2156 if (_matches(TokenType.SEMICOLON)) { | 2165 if (_matches(TokenType.SEMICOLON)) { |
| 2157 semicolon = getAndAdvance(); | 2166 semicolon = getAndAdvance(); |
| 2158 } else { | 2167 } else { |
| 2159 semicolon = _createSyntheticToken(TokenType.SEMICOLON); | 2168 semicolon = _createSyntheticToken(TokenType.SEMICOLON); |
| 2160 } | 2169 } |
| 2161 VariableDeclaration variable = | 2170 VariableDeclaration variable = astFactory.variableDeclaration( |
| 2162 new VariableDeclaration(createSyntheticIdentifier(), null, null); | 2171 createSyntheticIdentifier(), null, null); |
| 2163 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; | 2172 List<VariableDeclaration> variables = <VariableDeclaration>[variable]; |
| 2164 return new TopLevelVariableDeclaration( | 2173 return astFactory.topLevelVariableDeclaration( |
| 2165 commentAndMetadata.comment, | 2174 commentAndMetadata.comment, |
| 2166 commentAndMetadata.metadata, | 2175 commentAndMetadata.metadata, |
| 2167 new VariableDeclarationList(null, null, null, returnType, variables), | 2176 astFactory.variableDeclarationList( |
| 2177 null, null, null, returnType, variables), | |
| 2168 semicolon); | 2178 semicolon); |
| 2169 } else if (next.matchesAny(const <TokenType>[ | 2179 } else if (next.matchesAny(const <TokenType>[ |
| 2170 TokenType.OPEN_PAREN, | 2180 TokenType.OPEN_PAREN, |
| 2171 TokenType.FUNCTION, | 2181 TokenType.FUNCTION, |
| 2172 TokenType.OPEN_CURLY_BRACKET, | 2182 TokenType.OPEN_CURLY_BRACKET, |
| 2173 TokenType.LT | 2183 TokenType.LT |
| 2174 ])) { | 2184 ])) { |
| 2175 _validateModifiersForTopLevelFunction(modifiers); | 2185 _validateModifiersForTopLevelFunction(modifiers); |
| 2176 return parseFunctionDeclaration( | 2186 return parseFunctionDeclaration( |
| 2177 commentAndMetadata, modifiers.externalKeyword, returnType); | 2187 commentAndMetadata, modifiers.externalKeyword, returnType); |
| 2178 } | 2188 } |
| 2179 return new TopLevelVariableDeclaration( | 2189 return astFactory.topLevelVariableDeclaration( |
| 2180 commentAndMetadata.comment, | 2190 commentAndMetadata.comment, |
| 2181 commentAndMetadata.metadata, | 2191 commentAndMetadata.metadata, |
| 2182 parseVariableDeclarationListAfterType( | 2192 parseVariableDeclarationListAfterType( |
| 2183 null, _validateModifiersForTopLevelVariable(modifiers), returnType), | 2193 null, _validateModifiersForTopLevelVariable(modifiers), returnType), |
| 2184 _expect(TokenType.SEMICOLON)); | 2194 _expect(TokenType.SEMICOLON)); |
| 2185 } | 2195 } |
| 2186 | 2196 |
| 2187 /** | 2197 /** |
| 2188 * Parse a conditional expression. Return the conditional expression that was | 2198 * Parse a conditional expression. Return the conditional expression that was |
| 2189 * parsed. | 2199 * parsed. |
| 2190 * | 2200 * |
| 2191 * conditionalExpression ::= | 2201 * conditionalExpression ::= |
| 2192 * ifNullExpression ('?' expressionWithoutCascade ':' expressionWithou tCascade)? | 2202 * ifNullExpression ('?' expressionWithoutCascade ':' expressionWithou tCascade)? |
| 2193 */ | 2203 */ |
| 2194 Expression parseConditionalExpression() { | 2204 Expression parseConditionalExpression() { |
| 2195 Expression condition = parseIfNullExpression(); | 2205 Expression condition = parseIfNullExpression(); |
| 2196 if (_currentToken.type != TokenType.QUESTION) { | 2206 if (_currentToken.type != TokenType.QUESTION) { |
| 2197 return condition; | 2207 return condition; |
| 2198 } | 2208 } |
| 2199 Token question = getAndAdvance(); | 2209 Token question = getAndAdvance(); |
| 2200 Expression thenExpression = parseExpressionWithoutCascade(); | 2210 Expression thenExpression = parseExpressionWithoutCascade(); |
| 2201 Token colon = _expect(TokenType.COLON); | 2211 Token colon = _expect(TokenType.COLON); |
| 2202 Expression elseExpression = parseExpressionWithoutCascade(); | 2212 Expression elseExpression = parseExpressionWithoutCascade(); |
| 2203 return new ConditionalExpression( | 2213 return astFactory.conditionalExpression( |
| 2204 condition, question, thenExpression, colon, elseExpression); | 2214 condition, question, thenExpression, colon, elseExpression); |
| 2205 } | 2215 } |
| 2206 | 2216 |
| 2207 /** | 2217 /** |
| 2208 * Parse a configuration in either an import or export directive. | 2218 * Parse a configuration in either an import or export directive. |
| 2209 * | 2219 * |
| 2210 * This method assumes that the current token matches `Keyword.IF`. | 2220 * This method assumes that the current token matches `Keyword.IF`. |
| 2211 * | 2221 * |
| 2212 * configuration ::= | 2222 * configuration ::= |
| 2213 * 'if' '(' test ')' uri | 2223 * 'if' '(' test ')' uri |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2227 if (_matches(TokenType.EQ_EQ)) { | 2237 if (_matches(TokenType.EQ_EQ)) { |
| 2228 equalToken = getAndAdvance(); | 2238 equalToken = getAndAdvance(); |
| 2229 value = parseStringLiteral(); | 2239 value = parseStringLiteral(); |
| 2230 if (value is StringInterpolation) { | 2240 if (value is StringInterpolation) { |
| 2231 _reportErrorForNode( | 2241 _reportErrorForNode( |
| 2232 ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, value); | 2242 ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, value); |
| 2233 } | 2243 } |
| 2234 } | 2244 } |
| 2235 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 2245 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 2236 StringLiteral libraryUri = _parseUri(); | 2246 StringLiteral libraryUri = _parseUri(); |
| 2237 return new Configuration(ifKeyword, leftParenthesis, name, equalToken, | 2247 return astFactory.configuration(ifKeyword, leftParenthesis, name, |
| 2238 value, rightParenthesis, libraryUri); | 2248 equalToken, value, rightParenthesis, libraryUri); |
| 2239 } | 2249 } |
| 2240 | 2250 |
| 2241 /** | 2251 /** |
| 2242 * Parse a const expression. Return the const expression that was parsed. | 2252 * Parse a const expression. Return the const expression that was parsed. |
| 2243 * | 2253 * |
| 2244 * This method assumes that the current token matches `Keyword.CONST`. | 2254 * This method assumes that the current token matches `Keyword.CONST`. |
| 2245 * | 2255 * |
| 2246 * constExpression ::= | 2256 * constExpression ::= |
| 2247 * instanceCreationExpression | 2257 * instanceCreationExpression |
| 2248 * | listLiteral | 2258 * | listLiteral |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2285 } else { | 2295 } else { |
| 2286 _reportErrorForCurrentToken( | 2296 _reportErrorForCurrentToken( |
| 2287 ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER); | 2297 ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER); |
| 2288 Keyword keyword = _currentToken.keyword; | 2298 Keyword keyword = _currentToken.keyword; |
| 2289 if (keyword != Keyword.THIS && | 2299 if (keyword != Keyword.THIS && |
| 2290 keyword != Keyword.SUPER && | 2300 keyword != Keyword.SUPER && |
| 2291 type != TokenType.OPEN_CURLY_BRACKET && | 2301 type != TokenType.OPEN_CURLY_BRACKET && |
| 2292 type != TokenType.FUNCTION) { | 2302 type != TokenType.FUNCTION) { |
| 2293 equals = _createSyntheticToken(TokenType.EQ); | 2303 equals = _createSyntheticToken(TokenType.EQ); |
| 2294 } else { | 2304 } else { |
| 2295 return new ConstructorFieldInitializer(keywordToken, period, fieldName, | 2305 return astFactory.constructorFieldInitializer( |
| 2296 _createSyntheticToken(TokenType.EQ), createSyntheticIdentifier()); | 2306 keywordToken, |
| 2307 period, | |
| 2308 fieldName, | |
| 2309 _createSyntheticToken(TokenType.EQ), | |
| 2310 createSyntheticIdentifier()); | |
| 2297 } | 2311 } |
| 2298 } | 2312 } |
| 2299 bool wasInInitializer = _inInitializer; | 2313 bool wasInInitializer = _inInitializer; |
| 2300 _inInitializer = true; | 2314 _inInitializer = true; |
| 2301 try { | 2315 try { |
| 2302 Expression expression = parseConditionalExpression(); | 2316 Expression expression = parseConditionalExpression(); |
| 2303 if (_matches(TokenType.PERIOD_PERIOD)) { | 2317 if (_matches(TokenType.PERIOD_PERIOD)) { |
| 2304 List<Expression> cascadeSections = <Expression>[]; | 2318 List<Expression> cascadeSections = <Expression>[]; |
| 2305 do { | 2319 do { |
| 2306 Expression section = parseCascadeSection(); | 2320 Expression section = parseCascadeSection(); |
| 2307 if (section != null) { | 2321 if (section != null) { |
| 2308 cascadeSections.add(section); | 2322 cascadeSections.add(section); |
| 2309 } | 2323 } |
| 2310 } while (_matches(TokenType.PERIOD_PERIOD)); | 2324 } while (_matches(TokenType.PERIOD_PERIOD)); |
| 2311 expression = new CascadeExpression(expression, cascadeSections); | 2325 expression = astFactory.cascadeExpression(expression, cascadeSections); |
| 2312 } | 2326 } |
| 2313 return new ConstructorFieldInitializer( | 2327 return astFactory.constructorFieldInitializer( |
| 2314 keywordToken, period, fieldName, equals, expression); | 2328 keywordToken, period, fieldName, equals, expression); |
| 2315 } finally { | 2329 } finally { |
| 2316 _inInitializer = wasInInitializer; | 2330 _inInitializer = wasInInitializer; |
| 2317 } | 2331 } |
| 2318 } | 2332 } |
| 2319 | 2333 |
| 2320 /** | 2334 /** |
| 2321 * Parse the name of a constructor. Return the constructor name that was | 2335 * Parse the name of a constructor. Return the constructor name that was |
| 2322 * parsed. | 2336 * parsed. |
| 2323 * | 2337 * |
| 2324 * constructorName: | 2338 * constructorName: |
| 2325 * type ('.' identifier)? | 2339 * type ('.' identifier)? |
| 2326 */ | 2340 */ |
| 2327 ConstructorName parseConstructorName() { | 2341 ConstructorName parseConstructorName() { |
| 2328 TypeName type = parseTypeName(false); | 2342 TypeName type = parseTypeName(false); |
| 2329 Token period = null; | 2343 Token period = null; |
| 2330 SimpleIdentifier name = null; | 2344 SimpleIdentifier name = null; |
| 2331 if (_matches(TokenType.PERIOD)) { | 2345 if (_matches(TokenType.PERIOD)) { |
| 2332 period = getAndAdvance(); | 2346 period = getAndAdvance(); |
| 2333 name = parseSimpleIdentifier(); | 2347 name = parseSimpleIdentifier(); |
| 2334 } | 2348 } |
| 2335 return new ConstructorName(type, period, name); | 2349 return astFactory.constructorName(type, period, name); |
| 2336 } | 2350 } |
| 2337 | 2351 |
| 2338 /** | 2352 /** |
| 2339 * Parse a continue statement. Return the continue statement that was parsed. | 2353 * Parse a continue statement. Return the continue statement that was parsed. |
| 2340 * | 2354 * |
| 2341 * This method assumes that the current token matches `Keyword.CONTINUE`. | 2355 * This method assumes that the current token matches `Keyword.CONTINUE`. |
| 2342 * | 2356 * |
| 2343 * continueStatement ::= | 2357 * continueStatement ::= |
| 2344 * 'continue' identifier? ';' | 2358 * 'continue' identifier? ';' |
| 2345 */ | 2359 */ |
| 2346 Statement parseContinueStatement() { | 2360 Statement parseContinueStatement() { |
| 2347 Token continueKeyword = getAndAdvance(); | 2361 Token continueKeyword = getAndAdvance(); |
| 2348 if (!_inLoop && !_inSwitch) { | 2362 if (!_inLoop && !_inSwitch) { |
| 2349 _reportErrorForToken( | 2363 _reportErrorForToken( |
| 2350 ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword); | 2364 ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword); |
| 2351 } | 2365 } |
| 2352 SimpleIdentifier label = null; | 2366 SimpleIdentifier label = null; |
| 2353 if (_matchesIdentifier()) { | 2367 if (_matchesIdentifier()) { |
| 2354 label = _parseSimpleIdentifierUnchecked(); | 2368 label = _parseSimpleIdentifierUnchecked(); |
| 2355 } | 2369 } |
| 2356 if (_inSwitch && !_inLoop && label == null) { | 2370 if (_inSwitch && !_inLoop && label == null) { |
| 2357 _reportErrorForToken( | 2371 _reportErrorForToken( |
| 2358 ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword); | 2372 ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, continueKeyword); |
| 2359 } | 2373 } |
| 2360 Token semicolon = _expect(TokenType.SEMICOLON); | 2374 Token semicolon = _expect(TokenType.SEMICOLON); |
| 2361 return new ContinueStatement(continueKeyword, label, semicolon); | 2375 return astFactory.continueStatement(continueKeyword, label, semicolon); |
| 2362 } | 2376 } |
| 2363 | 2377 |
| 2364 /** | 2378 /** |
| 2365 * Parse a directive. The [commentAndMetadata] is the metadata to be | 2379 * Parse a directive. The [commentAndMetadata] is the metadata to be |
| 2366 * associated with the directive. Return the directive that was parsed. | 2380 * associated with the directive. Return the directive that was parsed. |
| 2367 * | 2381 * |
| 2368 * directive ::= | 2382 * directive ::= |
| 2369 * exportDirective | 2383 * exportDirective |
| 2370 * | libraryDirective | 2384 * | libraryDirective |
| 2371 * | importDirective | 2385 * | importDirective |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2404 * Parse the script tag and directives in a compilation unit until the first | 2418 * Parse the script tag and directives in a compilation unit until the first |
| 2405 * non-directive is encountered. Return the compilation unit that was parsed. | 2419 * non-directive is encountered. Return the compilation unit that was parsed. |
| 2406 * | 2420 * |
| 2407 * compilationUnit ::= | 2421 * compilationUnit ::= |
| 2408 * scriptTag? directive* | 2422 * scriptTag? directive* |
| 2409 */ | 2423 */ |
| 2410 CompilationUnit parseDirectives2() { | 2424 CompilationUnit parseDirectives2() { |
| 2411 Token firstToken = _currentToken; | 2425 Token firstToken = _currentToken; |
| 2412 ScriptTag scriptTag = null; | 2426 ScriptTag scriptTag = null; |
| 2413 if (_matches(TokenType.SCRIPT_TAG)) { | 2427 if (_matches(TokenType.SCRIPT_TAG)) { |
| 2414 scriptTag = new ScriptTag(getAndAdvance()); | 2428 scriptTag = astFactory.scriptTag(getAndAdvance()); |
| 2415 } | 2429 } |
| 2416 List<Directive> directives = <Directive>[]; | 2430 List<Directive> directives = <Directive>[]; |
| 2417 while (!_matches(TokenType.EOF)) { | 2431 while (!_matches(TokenType.EOF)) { |
| 2418 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 2432 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 2419 Keyword keyword = _currentToken.keyword; | 2433 Keyword keyword = _currentToken.keyword; |
| 2420 TokenType type = _peek().type; | 2434 TokenType type = _peek().type; |
| 2421 if ((keyword == Keyword.IMPORT || | 2435 if ((keyword == Keyword.IMPORT || |
| 2422 keyword == Keyword.EXPORT || | 2436 keyword == Keyword.EXPORT || |
| 2423 keyword == Keyword.LIBRARY || | 2437 keyword == Keyword.LIBRARY || |
| 2424 keyword == Keyword.PART) && | 2438 keyword == Keyword.PART) && |
| 2425 type != TokenType.PERIOD && | 2439 type != TokenType.PERIOD && |
| 2426 type != TokenType.LT && | 2440 type != TokenType.LT && |
| 2427 type != TokenType.OPEN_PAREN) { | 2441 type != TokenType.OPEN_PAREN) { |
| 2428 directives.add(parseDirective(commentAndMetadata)); | 2442 directives.add(parseDirective(commentAndMetadata)); |
| 2429 } else if (_matches(TokenType.SEMICOLON)) { | 2443 } else if (_matches(TokenType.SEMICOLON)) { |
| 2430 _advance(); | 2444 _advance(); |
| 2431 } else { | 2445 } else { |
| 2432 while (!_matches(TokenType.EOF)) { | 2446 while (!_matches(TokenType.EOF)) { |
| 2433 _advance(); | 2447 _advance(); |
| 2434 } | 2448 } |
| 2435 return new CompilationUnit( | 2449 return astFactory.compilationUnit( |
| 2436 firstToken, scriptTag, directives, null, _currentToken); | 2450 firstToken, scriptTag, directives, null, _currentToken); |
| 2437 } | 2451 } |
| 2438 } | 2452 } |
| 2439 return new CompilationUnit( | 2453 return astFactory.compilationUnit( |
| 2440 firstToken, scriptTag, directives, null, _currentToken); | 2454 firstToken, scriptTag, directives, null, _currentToken); |
| 2441 } | 2455 } |
| 2442 | 2456 |
| 2443 /** | 2457 /** |
| 2444 * Parse a documentation comment based on the given list of documentation | 2458 * Parse a documentation comment based on the given list of documentation |
| 2445 * comment tokens. Return the documentation comment that was parsed, or `null` | 2459 * comment tokens. Return the documentation comment that was parsed, or `null` |
| 2446 * if there was no comment. | 2460 * if there was no comment. |
| 2447 * | 2461 * |
| 2448 * documentationComment ::= | 2462 * documentationComment ::= |
| 2449 * multiLineComment? | 2463 * multiLineComment? |
| 2450 * | singleLineComment* | 2464 * | singleLineComment* |
| 2451 */ | 2465 */ |
| 2452 Comment parseDocumentationComment(List<DocumentationCommentToken> tokens) { | 2466 Comment parseDocumentationComment(List<DocumentationCommentToken> tokens) { |
| 2453 if (tokens == null) { | 2467 if (tokens == null) { |
| 2454 return null; | 2468 return null; |
| 2455 } | 2469 } |
| 2456 List<CommentReference> references = parseCommentReferences(tokens); | 2470 List<CommentReference> references = parseCommentReferences(tokens); |
| 2457 return Comment.createDocumentationCommentWithReferences(tokens, references); | 2471 return astFactory.documentationComment(tokens, references); |
| 2458 } | 2472 } |
| 2459 | 2473 |
| 2460 /** | 2474 /** |
| 2461 * Parse a documentation comment. Return the documentation comment that was | 2475 * Parse a documentation comment. Return the documentation comment that was |
| 2462 * parsed, or `null` if there was no comment. | 2476 * parsed, or `null` if there was no comment. |
| 2463 * | 2477 * |
| 2464 * documentationComment ::= | 2478 * documentationComment ::= |
| 2465 * multiLineComment? | 2479 * multiLineComment? |
| 2466 * | singleLineComment* | 2480 * | singleLineComment* |
| 2467 */ | 2481 */ |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2498 bool wasInLoop = _inLoop; | 2512 bool wasInLoop = _inLoop; |
| 2499 _inLoop = true; | 2513 _inLoop = true; |
| 2500 try { | 2514 try { |
| 2501 Token doKeyword = getAndAdvance(); | 2515 Token doKeyword = getAndAdvance(); |
| 2502 Statement body = parseStatement2(); | 2516 Statement body = parseStatement2(); |
| 2503 Token whileKeyword = _expectKeyword(Keyword.WHILE); | 2517 Token whileKeyword = _expectKeyword(Keyword.WHILE); |
| 2504 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); | 2518 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| 2505 Expression condition = parseExpression2(); | 2519 Expression condition = parseExpression2(); |
| 2506 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 2520 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 2507 Token semicolon = _expect(TokenType.SEMICOLON); | 2521 Token semicolon = _expect(TokenType.SEMICOLON); |
| 2508 return new DoStatement(doKeyword, body, whileKeyword, leftParenthesis, | 2522 return astFactory.doStatement(doKeyword, body, whileKeyword, |
| 2509 condition, rightParenthesis, semicolon); | 2523 leftParenthesis, condition, rightParenthesis, semicolon); |
| 2510 } finally { | 2524 } finally { |
| 2511 _inLoop = wasInLoop; | 2525 _inLoop = wasInLoop; |
| 2512 } | 2526 } |
| 2513 } | 2527 } |
| 2514 | 2528 |
| 2515 /** | 2529 /** |
| 2516 * Parse a dotted name. Return the dotted name that was parsed. | 2530 * Parse a dotted name. Return the dotted name that was parsed. |
| 2517 * | 2531 * |
| 2518 * dottedName ::= | 2532 * dottedName ::= |
| 2519 * identifier ('.' identifier)* | 2533 * identifier ('.' identifier)* |
| 2520 */ | 2534 */ |
| 2521 DottedName parseDottedName() { | 2535 DottedName parseDottedName() { |
| 2522 List<SimpleIdentifier> components = <SimpleIdentifier>[ | 2536 List<SimpleIdentifier> components = <SimpleIdentifier>[ |
| 2523 parseSimpleIdentifier() | 2537 parseSimpleIdentifier() |
| 2524 ]; | 2538 ]; |
| 2525 while (_optional(TokenType.PERIOD)) { | 2539 while (_optional(TokenType.PERIOD)) { |
| 2526 components.add(parseSimpleIdentifier()); | 2540 components.add(parseSimpleIdentifier()); |
| 2527 } | 2541 } |
| 2528 return new DottedName(components); | 2542 return astFactory.dottedName(components); |
| 2529 } | 2543 } |
| 2530 | 2544 |
| 2531 /** | 2545 /** |
| 2532 * Parse an empty statement. Return the empty statement that was parsed. | 2546 * Parse an empty statement. Return the empty statement that was parsed. |
| 2533 * | 2547 * |
| 2534 * This method assumes that the current token matches `TokenType.SEMICOLON`. | 2548 * This method assumes that the current token matches `TokenType.SEMICOLON`. |
| 2535 * | 2549 * |
| 2536 * emptyStatement ::= | 2550 * emptyStatement ::= |
| 2537 * ';' | 2551 * ';' |
| 2538 */ | 2552 */ |
| 2539 Statement parseEmptyStatement() => new EmptyStatement(getAndAdvance()); | 2553 Statement parseEmptyStatement() => astFactory.emptyStatement(getAndAdvance()); |
| 2540 | 2554 |
| 2541 /** | 2555 /** |
| 2542 * Parse an enum declaration. The [commentAndMetadata] is the metadata to be | 2556 * Parse an enum declaration. The [commentAndMetadata] is the metadata to be |
| 2543 * associated with the member. Return the enum declaration that was parsed. | 2557 * associated with the member. Return the enum declaration that was parsed. |
| 2544 * | 2558 * |
| 2545 * This method assumes that the current token matches `Keyword.ENUM`. | 2559 * This method assumes that the current token matches `Keyword.ENUM`. |
| 2546 * | 2560 * |
| 2547 * enumType ::= | 2561 * enumType ::= |
| 2548 * metadata 'enum' id '{' id (',' id)* (',')? '}' | 2562 * metadata 'enum' id '{' id (',' id)* (',')? '}' |
| 2549 */ | 2563 */ |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2570 break; | 2584 break; |
| 2571 } | 2585 } |
| 2572 constants.add(_parseEnumConstantDeclaration()); | 2586 constants.add(_parseEnumConstantDeclaration()); |
| 2573 } | 2587 } |
| 2574 rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 2588 rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 2575 } else { | 2589 } else { |
| 2576 leftBracket = _createSyntheticToken(TokenType.OPEN_CURLY_BRACKET); | 2590 leftBracket = _createSyntheticToken(TokenType.OPEN_CURLY_BRACKET); |
| 2577 rightBracket = _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET); | 2591 rightBracket = _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET); |
| 2578 _reportErrorForCurrentToken(ParserErrorCode.MISSING_ENUM_BODY); | 2592 _reportErrorForCurrentToken(ParserErrorCode.MISSING_ENUM_BODY); |
| 2579 } | 2593 } |
| 2580 return new EnumDeclaration( | 2594 return astFactory.enumDeclaration( |
| 2581 commentAndMetadata.comment, | 2595 commentAndMetadata.comment, |
| 2582 commentAndMetadata.metadata, | 2596 commentAndMetadata.metadata, |
| 2583 keyword, | 2597 keyword, |
| 2584 name, | 2598 name, |
| 2585 leftBracket, | 2599 leftBracket, |
| 2586 constants, | 2600 constants, |
| 2587 rightBracket); | 2601 rightBracket); |
| 2588 } | 2602 } |
| 2589 | 2603 |
| 2590 /** | 2604 /** |
| 2591 * Parse an equality expression. Return the equality expression that was | 2605 * Parse an equality expression. Return the equality expression that was |
| 2592 * parsed. | 2606 * parsed. |
| 2593 * | 2607 * |
| 2594 * equalityExpression ::= | 2608 * equalityExpression ::= |
| 2595 * relationalExpression (equalityOperator relationalExpression)? | 2609 * relationalExpression (equalityOperator relationalExpression)? |
| 2596 * | 'super' equalityOperator relationalExpression | 2610 * | 'super' equalityOperator relationalExpression |
| 2597 */ | 2611 */ |
| 2598 Expression parseEqualityExpression() { | 2612 Expression parseEqualityExpression() { |
| 2599 Expression expression; | 2613 Expression expression; |
| 2600 if (_currentToken.keyword == Keyword.SUPER && | 2614 if (_currentToken.keyword == Keyword.SUPER && |
| 2601 _currentToken.next.type.isEqualityOperator) { | 2615 _currentToken.next.type.isEqualityOperator) { |
| 2602 expression = new SuperExpression(getAndAdvance()); | 2616 expression = astFactory.superExpression(getAndAdvance()); |
| 2603 } else { | 2617 } else { |
| 2604 expression = parseRelationalExpression(); | 2618 expression = parseRelationalExpression(); |
| 2605 } | 2619 } |
| 2606 bool leftEqualityExpression = false; | 2620 bool leftEqualityExpression = false; |
| 2607 while (_currentToken.type.isEqualityOperator) { | 2621 while (_currentToken.type.isEqualityOperator) { |
| 2608 if (leftEqualityExpression) { | 2622 if (leftEqualityExpression) { |
| 2609 _reportErrorForNode( | 2623 _reportErrorForNode( |
| 2610 ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, expression); | 2624 ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, expression); |
| 2611 } | 2625 } |
| 2612 expression = new BinaryExpression( | 2626 expression = astFactory.binaryExpression( |
| 2613 expression, getAndAdvance(), parseRelationalExpression()); | 2627 expression, getAndAdvance(), parseRelationalExpression()); |
| 2614 leftEqualityExpression = true; | 2628 leftEqualityExpression = true; |
| 2615 } | 2629 } |
| 2616 return expression; | 2630 return expression; |
| 2617 } | 2631 } |
| 2618 | 2632 |
| 2619 /** | 2633 /** |
| 2620 * Parse an export directive. The [commentAndMetadata] is the metadata to be | 2634 * Parse an export directive. The [commentAndMetadata] is the metadata to be |
| 2621 * associated with the directive. Return the export directive that was parsed. | 2635 * associated with the directive. Return the export directive that was parsed. |
| 2622 * | 2636 * |
| 2623 * This method assumes that the current token matches `Keyword.EXPORT`. | 2637 * This method assumes that the current token matches `Keyword.EXPORT`. |
| 2624 * | 2638 * |
| 2625 * exportDirective ::= | 2639 * exportDirective ::= |
| 2626 * metadata 'export' stringLiteral configuration* combinator*';' | 2640 * metadata 'export' stringLiteral configuration* combinator*';' |
| 2627 */ | 2641 */ |
| 2628 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { | 2642 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { |
| 2629 Token exportKeyword = getAndAdvance(); | 2643 Token exportKeyword = getAndAdvance(); |
| 2630 StringLiteral libraryUri = _parseUri(); | 2644 StringLiteral libraryUri = _parseUri(); |
| 2631 List<Configuration> configurations = _parseConfigurations(); | 2645 List<Configuration> configurations = _parseConfigurations(); |
| 2632 List<Combinator> combinators = parseCombinators(); | 2646 List<Combinator> combinators = parseCombinators(); |
| 2633 Token semicolon = _expect(TokenType.SEMICOLON); | 2647 Token semicolon = _expect(TokenType.SEMICOLON); |
| 2634 return new ExportDirective( | 2648 return astFactory.exportDirective( |
| 2635 commentAndMetadata.comment, | 2649 commentAndMetadata.comment, |
| 2636 commentAndMetadata.metadata, | 2650 commentAndMetadata.metadata, |
| 2637 exportKeyword, | 2651 exportKeyword, |
| 2638 libraryUri, | 2652 libraryUri, |
| 2639 configurations, | 2653 configurations, |
| 2640 combinators, | 2654 combinators, |
| 2641 semicolon); | 2655 semicolon); |
| 2642 } | 2656 } |
| 2643 | 2657 |
| 2644 /** | 2658 /** |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2677 Expression expression = parseConditionalExpression(); | 2691 Expression expression = parseConditionalExpression(); |
| 2678 TokenType type = _currentToken.type; | 2692 TokenType type = _currentToken.type; |
| 2679 if (type == TokenType.PERIOD_PERIOD) { | 2693 if (type == TokenType.PERIOD_PERIOD) { |
| 2680 List<Expression> cascadeSections = <Expression>[]; | 2694 List<Expression> cascadeSections = <Expression>[]; |
| 2681 do { | 2695 do { |
| 2682 Expression section = parseCascadeSection(); | 2696 Expression section = parseCascadeSection(); |
| 2683 if (section != null) { | 2697 if (section != null) { |
| 2684 cascadeSections.add(section); | 2698 cascadeSections.add(section); |
| 2685 } | 2699 } |
| 2686 } while (_currentToken.type == TokenType.PERIOD_PERIOD); | 2700 } while (_currentToken.type == TokenType.PERIOD_PERIOD); |
| 2687 return new CascadeExpression(expression, cascadeSections); | 2701 return astFactory.cascadeExpression(expression, cascadeSections); |
| 2688 } else if (type.isAssignmentOperator) { | 2702 } else if (type.isAssignmentOperator) { |
| 2689 Token operator = getAndAdvance(); | 2703 Token operator = getAndAdvance(); |
| 2690 _ensureAssignable(expression); | 2704 _ensureAssignable(expression); |
| 2691 return new AssignmentExpression(expression, operator, parseExpression2()); | 2705 return astFactory.assignmentExpression( |
| 2706 expression, operator, parseExpression2()); | |
| 2692 } | 2707 } |
| 2693 return expression; | 2708 return expression; |
| 2694 } | 2709 } |
| 2695 | 2710 |
| 2696 /** | 2711 /** |
| 2697 * Parse a list of expressions. Return the expression that was parsed. | 2712 * Parse a list of expressions. Return the expression that was parsed. |
| 2698 * | 2713 * |
| 2699 * expressionList ::= | 2714 * expressionList ::= |
| 2700 * expression (',' expression)* | 2715 * expression (',' expression)* |
| 2701 */ | 2716 */ |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2725 // | 2740 // |
| 2726 // assignableExpression is a subset of conditionalExpression, so we can | 2741 // assignableExpression is a subset of conditionalExpression, so we can |
| 2727 // parse a conditional expression and then determine whether it is followed | 2742 // parse a conditional expression and then determine whether it is followed |
| 2728 // by an assignmentOperator, checking for conformance to the restricted | 2743 // by an assignmentOperator, checking for conformance to the restricted |
| 2729 // grammar after making that determination. | 2744 // grammar after making that determination. |
| 2730 // | 2745 // |
| 2731 Expression expression = parseConditionalExpression(); | 2746 Expression expression = parseConditionalExpression(); |
| 2732 if (_currentToken.type.isAssignmentOperator) { | 2747 if (_currentToken.type.isAssignmentOperator) { |
| 2733 Token operator = getAndAdvance(); | 2748 Token operator = getAndAdvance(); |
| 2734 _ensureAssignable(expression); | 2749 _ensureAssignable(expression); |
| 2735 expression = new AssignmentExpression( | 2750 expression = astFactory.assignmentExpression( |
| 2736 expression, operator, parseExpressionWithoutCascade()); | 2751 expression, operator, parseExpressionWithoutCascade()); |
| 2737 } | 2752 } |
| 2738 return expression; | 2753 return expression; |
| 2739 } | 2754 } |
| 2740 | 2755 |
| 2741 /** | 2756 /** |
| 2742 * Parse a class extends clause. Return the class extends clause that was | 2757 * Parse a class extends clause. Return the class extends clause that was |
| 2743 * parsed. | 2758 * parsed. |
| 2744 * | 2759 * |
| 2745 * This method assumes that the current token matches `Keyword.EXTENDS`. | 2760 * This method assumes that the current token matches `Keyword.EXTENDS`. |
| 2746 * | 2761 * |
| 2747 * classExtendsClause ::= | 2762 * classExtendsClause ::= |
| 2748 * 'extends' type | 2763 * 'extends' type |
| 2749 */ | 2764 */ |
| 2750 ExtendsClause parseExtendsClause() { | 2765 ExtendsClause parseExtendsClause() { |
| 2751 Token keyword = getAndAdvance(); | 2766 Token keyword = getAndAdvance(); |
| 2752 TypeName superclass = parseTypeName(false); | 2767 TypeName superclass = parseTypeName(false); |
| 2753 _mustNotBeNullable(superclass, ParserErrorCode.NULLABLE_TYPE_IN_EXTENDS); | 2768 _mustNotBeNullable(superclass, ParserErrorCode.NULLABLE_TYPE_IN_EXTENDS); |
| 2754 return new ExtendsClause(keyword, superclass); | 2769 return astFactory.extendsClause(keyword, superclass); |
| 2755 } | 2770 } |
| 2756 | 2771 |
| 2757 /** | 2772 /** |
| 2758 * Parse the 'final', 'const', 'var' or type preceding a variable declaration. | 2773 * Parse the 'final', 'const', 'var' or type preceding a variable declaration. |
| 2759 * The [optional] is `true` if the keyword and type are optional. Return the | 2774 * The [optional] is `true` if the keyword and type are optional. Return the |
| 2760 * 'final', 'const', 'var' or type that was parsed. | 2775 * 'final', 'const', 'var' or type that was parsed. |
| 2761 * | 2776 * |
| 2762 * finalConstVarOrType ::= | 2777 * finalConstVarOrType ::= |
| 2763 * 'final' type? | 2778 * 'final' type? |
| 2764 * | 'const' type? | 2779 * | 'const' type? |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2815 NormalFormalParameter parameter = parseNormalFormalParameter(); | 2830 NormalFormalParameter parameter = parseNormalFormalParameter(); |
| 2816 TokenType type = _currentToken.type; | 2831 TokenType type = _currentToken.type; |
| 2817 if (type == TokenType.EQ) { | 2832 if (type == TokenType.EQ) { |
| 2818 Token separator = getAndAdvance(); | 2833 Token separator = getAndAdvance(); |
| 2819 Expression defaultValue = parseExpression2(); | 2834 Expression defaultValue = parseExpression2(); |
| 2820 if (kind == ParameterKind.REQUIRED) { | 2835 if (kind == ParameterKind.REQUIRED) { |
| 2821 _reportErrorForNode( | 2836 _reportErrorForNode( |
| 2822 ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter); | 2837 ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter); |
| 2823 kind = ParameterKind.POSITIONAL; | 2838 kind = ParameterKind.POSITIONAL; |
| 2824 } | 2839 } |
| 2825 return new DefaultFormalParameter( | 2840 return astFactory.defaultFormalParameter( |
| 2826 parameter, kind, separator, defaultValue); | 2841 parameter, kind, separator, defaultValue); |
| 2827 } else if (type == TokenType.COLON) { | 2842 } else if (type == TokenType.COLON) { |
| 2828 Token separator = getAndAdvance(); | 2843 Token separator = getAndAdvance(); |
| 2829 Expression defaultValue = parseExpression2(); | 2844 Expression defaultValue = parseExpression2(); |
| 2830 if (kind == ParameterKind.POSITIONAL) { | 2845 if (kind == ParameterKind.POSITIONAL) { |
| 2831 _reportErrorForToken( | 2846 _reportErrorForToken( |
| 2832 ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, | 2847 ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, |
| 2833 separator); | 2848 separator); |
| 2834 } else if (kind == ParameterKind.REQUIRED) { | 2849 } else if (kind == ParameterKind.REQUIRED) { |
| 2835 _reportErrorForNode( | 2850 _reportErrorForNode( |
| 2836 ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter); | 2851 ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter); |
| 2837 kind = ParameterKind.NAMED; | 2852 kind = ParameterKind.NAMED; |
| 2838 } | 2853 } |
| 2839 return new DefaultFormalParameter( | 2854 return astFactory.defaultFormalParameter( |
| 2840 parameter, kind, separator, defaultValue); | 2855 parameter, kind, separator, defaultValue); |
| 2841 } else if (kind != ParameterKind.REQUIRED) { | 2856 } else if (kind != ParameterKind.REQUIRED) { |
| 2842 return new DefaultFormalParameter(parameter, kind, null, null); | 2857 return astFactory.defaultFormalParameter(parameter, kind, null, null); |
| 2843 } | 2858 } |
| 2844 return parameter; | 2859 return parameter; |
| 2845 } | 2860 } |
| 2846 | 2861 |
| 2847 /** | 2862 /** |
| 2848 * Parse a list of formal parameters. Return the formal parameters that were | 2863 * Parse a list of formal parameters. Return the formal parameters that were |
| 2849 * parsed. | 2864 * parsed. |
| 2850 * | 2865 * |
| 2851 * formalParameterList ::= | 2866 * formalParameterList ::= |
| 2852 * '(' ')' | 2867 * '(' ')' |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2905 Token forKeyword = _expectKeyword(Keyword.FOR); | 2920 Token forKeyword = _expectKeyword(Keyword.FOR); |
| 2906 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); | 2921 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| 2907 VariableDeclarationList variableList = null; | 2922 VariableDeclarationList variableList = null; |
| 2908 Expression initialization = null; | 2923 Expression initialization = null; |
| 2909 if (!_matches(TokenType.SEMICOLON)) { | 2924 if (!_matches(TokenType.SEMICOLON)) { |
| 2910 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 2925 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 2911 if (_matchesIdentifier() && | 2926 if (_matchesIdentifier() && |
| 2912 (_tokenMatchesKeyword(_peek(), Keyword.IN) || | 2927 (_tokenMatchesKeyword(_peek(), Keyword.IN) || |
| 2913 _tokenMatches(_peek(), TokenType.COLON))) { | 2928 _tokenMatches(_peek(), TokenType.COLON))) { |
| 2914 SimpleIdentifier variableName = _parseSimpleIdentifierUnchecked(); | 2929 SimpleIdentifier variableName = _parseSimpleIdentifierUnchecked(); |
| 2915 variableList = new VariableDeclarationList(commentAndMetadata.comment, | 2930 variableList = astFactory.variableDeclarationList( |
| 2916 commentAndMetadata.metadata, null, null, <VariableDeclaration>[ | 2931 commentAndMetadata.comment, |
| 2917 new VariableDeclaration(variableName, null, null) | 2932 commentAndMetadata.metadata, |
| 2933 null, | |
| 2934 null, <VariableDeclaration>[ | |
| 2935 astFactory.variableDeclaration(variableName, null, null) | |
| 2918 ]); | 2936 ]); |
| 2919 } else if (isInitializedVariableDeclaration()) { | 2937 } else if (isInitializedVariableDeclaration()) { |
| 2920 variableList = | 2938 variableList = |
| 2921 parseVariableDeclarationListAfterMetadata(commentAndMetadata); | 2939 parseVariableDeclarationListAfterMetadata(commentAndMetadata); |
| 2922 } else { | 2940 } else { |
| 2923 initialization = parseExpression2(); | 2941 initialization = parseExpression2(); |
| 2924 } | 2942 } |
| 2925 TokenType type = _currentToken.type; | 2943 TokenType type = _currentToken.type; |
| 2926 if (_matchesKeyword(Keyword.IN) || type == TokenType.COLON) { | 2944 if (_matchesKeyword(Keyword.IN) || type == TokenType.COLON) { |
| 2927 if (type == TokenType.COLON) { | 2945 if (type == TokenType.COLON) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2941 [variables.length.toString()]); | 2959 [variables.length.toString()]); |
| 2942 } | 2960 } |
| 2943 VariableDeclaration variable = variables[0]; | 2961 VariableDeclaration variable = variables[0]; |
| 2944 if (variable.initializer != null) { | 2962 if (variable.initializer != null) { |
| 2945 _reportErrorForCurrentToken( | 2963 _reportErrorForCurrentToken( |
| 2946 ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH); | 2964 ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH); |
| 2947 } | 2965 } |
| 2948 Token keyword = variableList.keyword; | 2966 Token keyword = variableList.keyword; |
| 2949 TypeName type = variableList.type; | 2967 TypeName type = variableList.type; |
| 2950 if (keyword != null || type != null) { | 2968 if (keyword != null || type != null) { |
| 2951 loopVariable = new DeclaredIdentifier( | 2969 loopVariable = astFactory.declaredIdentifier( |
| 2952 commentAndMetadata.comment, | 2970 commentAndMetadata.comment, |
| 2953 commentAndMetadata.metadata, | 2971 commentAndMetadata.metadata, |
| 2954 keyword, | 2972 keyword, |
| 2955 type, | 2973 type, |
| 2956 new SimpleIdentifier(variable.name.token, | 2974 astFactory.simpleIdentifier(variable.name.token, |
| 2957 isDeclaration: true)); | 2975 isDeclaration: true)); |
| 2958 } else { | 2976 } else { |
| 2959 if (commentAndMetadata.hasMetadata) { | 2977 if (commentAndMetadata.hasMetadata) { |
| 2960 // TODO(jwren) metadata isn't allowed before the identifier in | 2978 // TODO(jwren) metadata isn't allowed before the identifier in |
| 2961 // "identifier in expression", add warning if commentAndMetadata | 2979 // "identifier in expression", add warning if commentAndMetadata |
| 2962 // has content | 2980 // has content |
| 2963 } | 2981 } |
| 2964 identifier = variable.name; | 2982 identifier = variable.name; |
| 2965 } | 2983 } |
| 2966 } | 2984 } |
| 2967 Token inKeyword = getAndAdvance(); | 2985 Token inKeyword = getAndAdvance(); |
| 2968 Expression iterator = parseExpression2(); | 2986 Expression iterator = parseExpression2(); |
| 2969 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 2987 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 2970 Statement body = parseStatement2(); | 2988 Statement body = parseStatement2(); |
| 2971 if (loopVariable == null) { | 2989 if (loopVariable == null) { |
| 2972 return new ForEachStatement.withReference( | 2990 return astFactory.forEachStatementWithReference( |
| 2973 awaitKeyword, | 2991 awaitKeyword, |
| 2974 forKeyword, | 2992 forKeyword, |
| 2975 leftParenthesis, | 2993 leftParenthesis, |
| 2976 identifier, | 2994 identifier, |
| 2977 inKeyword, | 2995 inKeyword, |
| 2978 iterator, | 2996 iterator, |
| 2979 rightParenthesis, | 2997 rightParenthesis, |
| 2980 body); | 2998 body); |
| 2981 } | 2999 } |
| 2982 return new ForEachStatement.withDeclaration( | 3000 return astFactory.forEachStatementWithDeclaration( |
| 2983 awaitKeyword, | 3001 awaitKeyword, |
| 2984 forKeyword, | 3002 forKeyword, |
| 2985 leftParenthesis, | 3003 leftParenthesis, |
| 2986 loopVariable, | 3004 loopVariable, |
| 2987 inKeyword, | 3005 inKeyword, |
| 2988 iterator, | 3006 iterator, |
| 2989 rightParenthesis, | 3007 rightParenthesis, |
| 2990 body); | 3008 body); |
| 2991 } | 3009 } |
| 2992 } | 3010 } |
| 2993 if (awaitKeyword != null) { | 3011 if (awaitKeyword != null) { |
| 2994 _reportErrorForToken( | 3012 _reportErrorForToken( |
| 2995 ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword); | 3013 ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword); |
| 2996 } | 3014 } |
| 2997 Token leftSeparator = _expect(TokenType.SEMICOLON); | 3015 Token leftSeparator = _expect(TokenType.SEMICOLON); |
| 2998 Expression condition = null; | 3016 Expression condition = null; |
| 2999 if (!_matches(TokenType.SEMICOLON)) { | 3017 if (!_matches(TokenType.SEMICOLON)) { |
| 3000 condition = parseExpression2(); | 3018 condition = parseExpression2(); |
| 3001 } | 3019 } |
| 3002 Token rightSeparator = _expect(TokenType.SEMICOLON); | 3020 Token rightSeparator = _expect(TokenType.SEMICOLON); |
| 3003 List<Expression> updaters = null; | 3021 List<Expression> updaters = null; |
| 3004 if (!_matches(TokenType.CLOSE_PAREN)) { | 3022 if (!_matches(TokenType.CLOSE_PAREN)) { |
| 3005 updaters = parseExpressionList(); | 3023 updaters = parseExpressionList(); |
| 3006 } | 3024 } |
| 3007 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 3025 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 3008 Statement body = parseStatement2(); | 3026 Statement body = parseStatement2(); |
| 3009 return new ForStatement( | 3027 return astFactory.forStatement( |
| 3010 forKeyword, | 3028 forKeyword, |
| 3011 leftParenthesis, | 3029 leftParenthesis, |
| 3012 variableList, | 3030 variableList, |
| 3013 initialization, | 3031 initialization, |
| 3014 leftSeparator, | 3032 leftSeparator, |
| 3015 condition, | 3033 condition, |
| 3016 rightSeparator, | 3034 rightSeparator, |
| 3017 updaters, | 3035 updaters, |
| 3018 rightParenthesis, | 3036 rightParenthesis, |
| 3019 body); | 3037 body); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3046 _inAsync = false; | 3064 _inAsync = false; |
| 3047 _inGenerator = false; | 3065 _inGenerator = false; |
| 3048 _inLoop = false; | 3066 _inLoop = false; |
| 3049 _inSwitch = false; | 3067 _inSwitch = false; |
| 3050 try { | 3068 try { |
| 3051 TokenType type = _currentToken.type; | 3069 TokenType type = _currentToken.type; |
| 3052 if (type == TokenType.SEMICOLON) { | 3070 if (type == TokenType.SEMICOLON) { |
| 3053 if (!mayBeEmpty) { | 3071 if (!mayBeEmpty) { |
| 3054 _reportErrorForCurrentToken(emptyErrorCode); | 3072 _reportErrorForCurrentToken(emptyErrorCode); |
| 3055 } | 3073 } |
| 3056 return new EmptyFunctionBody(getAndAdvance()); | 3074 return astFactory.emptyFunctionBody(getAndAdvance()); |
| 3057 } | 3075 } |
| 3058 Token keyword = null; | 3076 Token keyword = null; |
| 3059 Token star = null; | 3077 Token star = null; |
| 3060 bool foundAsync = false; | 3078 bool foundAsync = false; |
| 3061 bool foundSync = false; | 3079 bool foundSync = false; |
| 3062 if (type == TokenType.IDENTIFIER) { | 3080 if (type == TokenType.IDENTIFIER) { |
| 3063 String lexeme = _currentToken.lexeme; | 3081 String lexeme = _currentToken.lexeme; |
| 3064 if (lexeme == ASYNC) { | 3082 if (lexeme == ASYNC) { |
| 3065 foundAsync = true; | 3083 foundAsync = true; |
| 3066 keyword = getAndAdvance(); | 3084 keyword = getAndAdvance(); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 3095 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, | 3113 _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, |
| 3096 [_currentToken.lexeme]); | 3114 [_currentToken.lexeme]); |
| 3097 _advance(); | 3115 _advance(); |
| 3098 } | 3116 } |
| 3099 Expression expression = parseExpression2(); | 3117 Expression expression = parseExpression2(); |
| 3100 Token semicolon = null; | 3118 Token semicolon = null; |
| 3101 if (!inExpression) { | 3119 if (!inExpression) { |
| 3102 semicolon = _expect(TokenType.SEMICOLON); | 3120 semicolon = _expect(TokenType.SEMICOLON); |
| 3103 } | 3121 } |
| 3104 if (!_parseFunctionBodies) { | 3122 if (!_parseFunctionBodies) { |
| 3105 return new EmptyFunctionBody( | 3123 return astFactory |
| 3106 _createSyntheticToken(TokenType.SEMICOLON)); | 3124 .emptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)); |
| 3107 } | 3125 } |
| 3108 return new ExpressionFunctionBody( | 3126 return astFactory.expressionFunctionBody( |
| 3109 keyword, functionDefinition, expression, semicolon); | 3127 keyword, functionDefinition, expression, semicolon); |
| 3110 } else if (type == TokenType.OPEN_CURLY_BRACKET) { | 3128 } else if (type == TokenType.OPEN_CURLY_BRACKET) { |
| 3111 if (keyword != null) { | 3129 if (keyword != null) { |
| 3112 if (foundSync && star == null) { | 3130 if (foundSync && star == null) { |
| 3113 _reportErrorForToken( | 3131 _reportErrorForToken( |
| 3114 ParserErrorCode.MISSING_STAR_AFTER_SYNC, keyword); | 3132 ParserErrorCode.MISSING_STAR_AFTER_SYNC, keyword); |
| 3115 } | 3133 } |
| 3116 } | 3134 } |
| 3117 if (!_parseFunctionBodies) { | 3135 if (!_parseFunctionBodies) { |
| 3118 _skipBlock(); | 3136 _skipBlock(); |
| 3119 return new EmptyFunctionBody( | 3137 return astFactory |
| 3120 _createSyntheticToken(TokenType.SEMICOLON)); | 3138 .emptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)); |
| 3121 } | 3139 } |
| 3122 return new BlockFunctionBody(keyword, star, parseBlock()); | 3140 return astFactory.blockFunctionBody(keyword, star, parseBlock()); |
| 3123 } else if (_matchesString(_NATIVE)) { | 3141 } else if (_matchesString(_NATIVE)) { |
| 3124 Token nativeToken = getAndAdvance(); | 3142 Token nativeToken = getAndAdvance(); |
| 3125 StringLiteral stringLiteral = null; | 3143 StringLiteral stringLiteral = null; |
| 3126 if (_matches(TokenType.STRING)) { | 3144 if (_matches(TokenType.STRING)) { |
| 3127 stringLiteral = _parseStringLiteralUnchecked(); | 3145 stringLiteral = _parseStringLiteralUnchecked(); |
| 3128 } | 3146 } |
| 3129 return new NativeFunctionBody( | 3147 return astFactory.nativeFunctionBody( |
| 3130 nativeToken, stringLiteral, _expect(TokenType.SEMICOLON)); | 3148 nativeToken, stringLiteral, _expect(TokenType.SEMICOLON)); |
| 3131 } else { | 3149 } else { |
| 3132 // Invalid function body | 3150 // Invalid function body |
| 3133 _reportErrorForCurrentToken(emptyErrorCode); | 3151 _reportErrorForCurrentToken(emptyErrorCode); |
| 3134 return new EmptyFunctionBody( | 3152 return astFactory |
| 3135 _createSyntheticToken(TokenType.SEMICOLON)); | 3153 .emptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)); |
| 3136 } | 3154 } |
| 3137 } finally { | 3155 } finally { |
| 3138 _inAsync = wasInAsync; | 3156 _inAsync = wasInAsync; |
| 3139 _inGenerator = wasInGenerator; | 3157 _inGenerator = wasInGenerator; |
| 3140 _inLoop = wasInLoop; | 3158 _inLoop = wasInLoop; |
| 3141 _inSwitch = wasInSwitch; | 3159 _inSwitch = wasInSwitch; |
| 3142 } | 3160 } |
| 3143 } | 3161 } |
| 3144 | 3162 |
| 3145 /** | 3163 /** |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 3163 bool isGetter = false; | 3181 bool isGetter = false; |
| 3164 Keyword keyword = _currentToken.keyword; | 3182 Keyword keyword = _currentToken.keyword; |
| 3165 SimpleIdentifier name = null; | 3183 SimpleIdentifier name = null; |
| 3166 if (keyword == Keyword.GET) { | 3184 if (keyword == Keyword.GET) { |
| 3167 keywordToken = getAndAdvance(); | 3185 keywordToken = getAndAdvance(); |
| 3168 isGetter = true; | 3186 isGetter = true; |
| 3169 } else if (keyword == Keyword.SET) { | 3187 } else if (keyword == Keyword.SET) { |
| 3170 keywordToken = getAndAdvance(); | 3188 keywordToken = getAndAdvance(); |
| 3171 } | 3189 } |
| 3172 if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) { | 3190 if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) { |
| 3173 name = new SimpleIdentifier(keywordToken, isDeclaration: true); | 3191 name = astFactory.simpleIdentifier(keywordToken, isDeclaration: true); |
| 3174 keywordToken = null; | 3192 keywordToken = null; |
| 3175 isGetter = false; | 3193 isGetter = false; |
| 3176 } else { | 3194 } else { |
| 3177 name = parseSimpleIdentifier(isDeclaration: true); | 3195 name = parseSimpleIdentifier(isDeclaration: true); |
| 3178 } | 3196 } |
| 3179 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); | 3197 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); |
| 3180 FormalParameterList parameters = null; | 3198 FormalParameterList parameters = null; |
| 3181 if (!isGetter) { | 3199 if (!isGetter) { |
| 3182 if (_matches(TokenType.OPEN_PAREN)) { | 3200 if (_matches(TokenType.OPEN_PAREN)) { |
| 3183 parameters = _parseFormalParameterListUnchecked(); | 3201 parameters = _parseFormalParameterListUnchecked(); |
| 3184 _validateFormalParameterList(parameters); | 3202 _validateFormalParameterList(parameters); |
| 3185 } else { | 3203 } else { |
| 3186 _reportErrorForCurrentToken( | 3204 _reportErrorForCurrentToken( |
| 3187 ParserErrorCode.MISSING_FUNCTION_PARAMETERS); | 3205 ParserErrorCode.MISSING_FUNCTION_PARAMETERS); |
| 3188 parameters = new FormalParameterList( | 3206 parameters = astFactory.formalParameterList( |
| 3189 _createSyntheticToken(TokenType.OPEN_PAREN), | 3207 _createSyntheticToken(TokenType.OPEN_PAREN), |
| 3190 null, | 3208 null, |
| 3191 null, | 3209 null, |
| 3192 null, | 3210 null, |
| 3193 _createSyntheticToken(TokenType.CLOSE_PAREN)); | 3211 _createSyntheticToken(TokenType.CLOSE_PAREN)); |
| 3194 } | 3212 } |
| 3195 } else if (_matches(TokenType.OPEN_PAREN)) { | 3213 } else if (_matches(TokenType.OPEN_PAREN)) { |
| 3196 _reportErrorForCurrentToken(ParserErrorCode.GETTER_WITH_PARAMETERS); | 3214 _reportErrorForCurrentToken(ParserErrorCode.GETTER_WITH_PARAMETERS); |
| 3197 _parseFormalParameterListUnchecked(); | 3215 _parseFormalParameterListUnchecked(); |
| 3198 } | 3216 } |
| 3199 FunctionBody body; | 3217 FunctionBody body; |
| 3200 if (externalKeyword == null) { | 3218 if (externalKeyword == null) { |
| 3201 body = parseFunctionBody( | 3219 body = parseFunctionBody( |
| 3202 false, ParserErrorCode.MISSING_FUNCTION_BODY, false); | 3220 false, ParserErrorCode.MISSING_FUNCTION_BODY, false); |
| 3203 } else { | 3221 } else { |
| 3204 body = new EmptyFunctionBody(_expect(TokenType.SEMICOLON)); | 3222 body = astFactory.emptyFunctionBody(_expect(TokenType.SEMICOLON)); |
| 3205 } | 3223 } |
| 3206 // if (!isStatement && matches(TokenType.SEMICOLON)) { | 3224 // if (!isStatement && matches(TokenType.SEMICOLON)) { |
| 3207 // // TODO(brianwilkerson) Improve this error message. | 3225 // // TODO(brianwilkerson) Improve this error message. |
| 3208 // reportError(ParserErrorCode.UNEXPECTED_TOKEN, currentToken.getLexeme ()); | 3226 // reportError(ParserErrorCode.UNEXPECTED_TOKEN, currentToken.getLexeme ()); |
| 3209 // advance(); | 3227 // advance(); |
| 3210 // } | 3228 // } |
| 3211 return new FunctionDeclaration( | 3229 return astFactory.functionDeclaration( |
| 3212 commentAndMetadata.comment, | 3230 commentAndMetadata.comment, |
| 3213 commentAndMetadata.metadata, | 3231 commentAndMetadata.metadata, |
| 3214 externalKeyword, | 3232 externalKeyword, |
| 3215 returnType, | 3233 returnType, |
| 3216 keywordToken, | 3234 keywordToken, |
| 3217 name, | 3235 name, |
| 3218 new FunctionExpression(typeParameters, parameters, body)); | 3236 astFactory.functionExpression(typeParameters, parameters, body)); |
| 3219 } | 3237 } |
| 3220 | 3238 |
| 3221 /** | 3239 /** |
| 3222 * Parse a function declaration statement. Return the function declaration | 3240 * Parse a function declaration statement. Return the function declaration |
| 3223 * statement that was parsed. | 3241 * statement that was parsed. |
| 3224 * | 3242 * |
| 3225 * functionDeclarationStatement ::= | 3243 * functionDeclarationStatement ::= |
| 3226 * functionSignature functionBody | 3244 * functionSignature functionBody |
| 3227 */ | 3245 */ |
| 3228 Statement parseFunctionDeclarationStatement() { | 3246 Statement parseFunctionDeclarationStatement() { |
| 3229 Modifiers modifiers = parseModifiers(); | 3247 Modifiers modifiers = parseModifiers(); |
| 3230 _validateModifiersForFunctionDeclarationStatement(modifiers); | 3248 _validateModifiersForFunctionDeclarationStatement(modifiers); |
| 3231 return _parseFunctionDeclarationStatementAfterReturnType( | 3249 return _parseFunctionDeclarationStatementAfterReturnType( |
| 3232 parseCommentAndMetadata(), _parseOptionalReturnType()); | 3250 parseCommentAndMetadata(), _parseOptionalReturnType()); |
| 3233 } | 3251 } |
| 3234 | 3252 |
| 3235 /** | 3253 /** |
| 3236 * Parse a function expression. Return the function expression that was | 3254 * Parse a function expression. Return the function expression that was |
| 3237 * parsed. | 3255 * parsed. |
| 3238 * | 3256 * |
| 3239 * functionExpression ::= | 3257 * functionExpression ::= |
| 3240 * typeParameters? formalParameterList functionExpressionBody | 3258 * typeParameters? formalParameterList functionExpressionBody |
| 3241 */ | 3259 */ |
| 3242 FunctionExpression parseFunctionExpression() { | 3260 FunctionExpression parseFunctionExpression() { |
| 3243 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); | 3261 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); |
| 3244 FormalParameterList parameters = parseFormalParameterList(); | 3262 FormalParameterList parameters = parseFormalParameterList(); |
| 3245 _validateFormalParameterList(parameters); | 3263 _validateFormalParameterList(parameters); |
| 3246 FunctionBody body = | 3264 FunctionBody body = |
| 3247 parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, true); | 3265 parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, true); |
| 3248 return new FunctionExpression(typeParameters, parameters, body); | 3266 return astFactory.functionExpression(typeParameters, parameters, body); |
| 3249 } | 3267 } |
| 3250 | 3268 |
| 3251 /** | 3269 /** |
| 3252 * Parse a getter. The [commentAndMetadata] is the documentation comment and | 3270 * Parse a getter. The [commentAndMetadata] is the documentation comment and |
| 3253 * metadata to be associated with the declaration. The externalKeyword] is the | 3271 * metadata to be associated with the declaration. The externalKeyword] is the |
| 3254 * 'external' token. The staticKeyword] is the static keyword, or `null` if | 3272 * 'external' token. The staticKeyword] is the static keyword, or `null` if |
| 3255 * the getter is not static. The [returnType] the return type that has already | 3273 * the getter is not static. The [returnType] the return type that has already |
| 3256 * been parsed, or `null` if there was no return type. Return the getter that | 3274 * been parsed, or `null` if there was no return type. Return the getter that |
| 3257 * was parsed. | 3275 * was parsed. |
| 3258 * | 3276 * |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 3274 _advance(); | 3292 _advance(); |
| 3275 _advance(); | 3293 _advance(); |
| 3276 } | 3294 } |
| 3277 FunctionBody body = parseFunctionBody( | 3295 FunctionBody body = parseFunctionBody( |
| 3278 externalKeyword != null || staticKeyword == null, | 3296 externalKeyword != null || staticKeyword == null, |
| 3279 ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, | 3297 ParserErrorCode.STATIC_GETTER_WITHOUT_BODY, |
| 3280 false); | 3298 false); |
| 3281 if (externalKeyword != null && body is! EmptyFunctionBody) { | 3299 if (externalKeyword != null && body is! EmptyFunctionBody) { |
| 3282 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY); | 3300 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_GETTER_WITH_BODY); |
| 3283 } | 3301 } |
| 3284 return new MethodDeclaration( | 3302 return astFactory.methodDeclaration( |
| 3285 commentAndMetadata.comment, | 3303 commentAndMetadata.comment, |
| 3286 commentAndMetadata.metadata, | 3304 commentAndMetadata.metadata, |
| 3287 externalKeyword, | 3305 externalKeyword, |
| 3288 staticKeyword, | 3306 staticKeyword, |
| 3289 returnType, | 3307 returnType, |
| 3290 propertyKeyword, | 3308 propertyKeyword, |
| 3291 null, | 3309 null, |
| 3292 name, | 3310 name, |
| 3293 null, | 3311 null, |
| 3294 null, | 3312 null, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3314 | 3332 |
| 3315 /** | 3333 /** |
| 3316 * Parse an if-null expression. Return the if-null expression that was | 3334 * Parse an if-null expression. Return the if-null expression that was |
| 3317 * parsed. | 3335 * parsed. |
| 3318 * | 3336 * |
| 3319 * ifNullExpression ::= logicalOrExpression ('??' logicalOrExpression)* | 3337 * ifNullExpression ::= logicalOrExpression ('??' logicalOrExpression)* |
| 3320 */ | 3338 */ |
| 3321 Expression parseIfNullExpression() { | 3339 Expression parseIfNullExpression() { |
| 3322 Expression expression = parseLogicalOrExpression(); | 3340 Expression expression = parseLogicalOrExpression(); |
| 3323 while (_currentToken.type == TokenType.QUESTION_QUESTION) { | 3341 while (_currentToken.type == TokenType.QUESTION_QUESTION) { |
| 3324 expression = new BinaryExpression( | 3342 expression = astFactory.binaryExpression( |
| 3325 expression, getAndAdvance(), parseLogicalOrExpression()); | 3343 expression, getAndAdvance(), parseLogicalOrExpression()); |
| 3326 } | 3344 } |
| 3327 return expression; | 3345 return expression; |
| 3328 } | 3346 } |
| 3329 | 3347 |
| 3330 /** | 3348 /** |
| 3331 * Parse an if statement. Return the if statement that was parsed. | 3349 * Parse an if statement. Return the if statement that was parsed. |
| 3332 * | 3350 * |
| 3333 * This method assumes that the current token matches `Keyword.IF`. | 3351 * This method assumes that the current token matches `Keyword.IF`. |
| 3334 * | 3352 * |
| 3335 * ifStatement ::= | 3353 * ifStatement ::= |
| 3336 * 'if' '(' expression ')' statement ('else' statement)? | 3354 * 'if' '(' expression ')' statement ('else' statement)? |
| 3337 */ | 3355 */ |
| 3338 Statement parseIfStatement() { | 3356 Statement parseIfStatement() { |
| 3339 Token ifKeyword = getAndAdvance(); | 3357 Token ifKeyword = getAndAdvance(); |
| 3340 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); | 3358 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| 3341 Expression condition = parseExpression2(); | 3359 Expression condition = parseExpression2(); |
| 3342 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 3360 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 3343 Statement thenStatement = parseStatement2(); | 3361 Statement thenStatement = parseStatement2(); |
| 3344 Token elseKeyword = null; | 3362 Token elseKeyword = null; |
| 3345 Statement elseStatement = null; | 3363 Statement elseStatement = null; |
| 3346 if (_matchesKeyword(Keyword.ELSE)) { | 3364 if (_matchesKeyword(Keyword.ELSE)) { |
| 3347 elseKeyword = getAndAdvance(); | 3365 elseKeyword = getAndAdvance(); |
| 3348 elseStatement = parseStatement2(); | 3366 elseStatement = parseStatement2(); |
| 3349 } | 3367 } |
| 3350 return new IfStatement(ifKeyword, leftParenthesis, condition, | 3368 return astFactory.ifStatement(ifKeyword, leftParenthesis, condition, |
| 3351 rightParenthesis, thenStatement, elseKeyword, elseStatement); | 3369 rightParenthesis, thenStatement, elseKeyword, elseStatement); |
| 3352 } | 3370 } |
| 3353 | 3371 |
| 3354 /** | 3372 /** |
| 3355 * Parse an implements clause. Return the implements clause that was parsed. | 3373 * Parse an implements clause. Return the implements clause that was parsed. |
| 3356 * | 3374 * |
| 3357 * This method assumes that the current token matches `Keyword.IMPLEMENTS`. | 3375 * This method assumes that the current token matches `Keyword.IMPLEMENTS`. |
| 3358 * | 3376 * |
| 3359 * implementsClause ::= | 3377 * implementsClause ::= |
| 3360 * 'implements' type (',' type)* | 3378 * 'implements' type (',' type)* |
| 3361 */ | 3379 */ |
| 3362 ImplementsClause parseImplementsClause() { | 3380 ImplementsClause parseImplementsClause() { |
| 3363 Token keyword = getAndAdvance(); | 3381 Token keyword = getAndAdvance(); |
| 3364 List<TypeName> interfaces = <TypeName>[]; | 3382 List<TypeName> interfaces = <TypeName>[]; |
| 3365 do { | 3383 do { |
| 3366 TypeName typeName = parseTypeName(false); | 3384 TypeName typeName = parseTypeName(false); |
| 3367 _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS); | 3385 _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS); |
| 3368 interfaces.add(typeName); | 3386 interfaces.add(typeName); |
| 3369 } while (_optional(TokenType.COMMA)); | 3387 } while (_optional(TokenType.COMMA)); |
| 3370 return new ImplementsClause(keyword, interfaces); | 3388 return astFactory.implementsClause(keyword, interfaces); |
| 3371 } | 3389 } |
| 3372 | 3390 |
| 3373 /** | 3391 /** |
| 3374 * Parse an import directive. The [commentAndMetadata] is the metadata to be | 3392 * Parse an import directive. The [commentAndMetadata] is the metadata to be |
| 3375 * associated with the directive. Return the import directive that was parsed. | 3393 * associated with the directive. Return the import directive that was parsed. |
| 3376 * | 3394 * |
| 3377 * This method assumes that the current token matches `Keyword.IMPORT`. | 3395 * This method assumes that the current token matches `Keyword.IMPORT`. |
| 3378 * | 3396 * |
| 3379 * importDirective ::= | 3397 * importDirective ::= |
| 3380 * metadata 'import' stringLiteral configuration* (deferred)? ('as' id entifier)? combinator*';' | 3398 * metadata 'import' stringLiteral configuration* (deferred)? ('as' id entifier)? combinator*';' |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 3406 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken]); | 3424 ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken]); |
| 3407 _advance(); | 3425 _advance(); |
| 3408 if (_matchesKeyword(Keyword.AS)) { | 3426 if (_matchesKeyword(Keyword.AS)) { |
| 3409 asToken = getAndAdvance(); | 3427 asToken = getAndAdvance(); |
| 3410 prefix = parseSimpleIdentifier(isDeclaration: true); | 3428 prefix = parseSimpleIdentifier(isDeclaration: true); |
| 3411 } | 3429 } |
| 3412 } | 3430 } |
| 3413 } | 3431 } |
| 3414 List<Combinator> combinators = parseCombinators(); | 3432 List<Combinator> combinators = parseCombinators(); |
| 3415 Token semicolon = _expect(TokenType.SEMICOLON); | 3433 Token semicolon = _expect(TokenType.SEMICOLON); |
| 3416 return new ImportDirective( | 3434 return astFactory.importDirective( |
| 3417 commentAndMetadata.comment, | 3435 commentAndMetadata.comment, |
| 3418 commentAndMetadata.metadata, | 3436 commentAndMetadata.metadata, |
| 3419 importKeyword, | 3437 importKeyword, |
| 3420 libraryUri, | 3438 libraryUri, |
| 3421 configurations, | 3439 configurations, |
| 3422 deferredToken, | 3440 deferredToken, |
| 3423 asToken, | 3441 asToken, |
| 3424 prefix, | 3442 prefix, |
| 3425 combinators, | 3443 combinators, |
| 3426 semicolon); | 3444 semicolon); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3445 * initializedIdentifier ::= | 3463 * initializedIdentifier ::= |
| 3446 * identifier ('=' expression)? | 3464 * identifier ('=' expression)? |
| 3447 */ | 3465 */ |
| 3448 FieldDeclaration parseInitializedIdentifierList( | 3466 FieldDeclaration parseInitializedIdentifierList( |
| 3449 CommentAndMetadata commentAndMetadata, | 3467 CommentAndMetadata commentAndMetadata, |
| 3450 Token staticKeyword, | 3468 Token staticKeyword, |
| 3451 Token keyword, | 3469 Token keyword, |
| 3452 TypeName type) { | 3470 TypeName type) { |
| 3453 VariableDeclarationList fieldList = | 3471 VariableDeclarationList fieldList = |
| 3454 parseVariableDeclarationListAfterType(null, keyword, type); | 3472 parseVariableDeclarationListAfterType(null, keyword, type); |
| 3455 return new FieldDeclaration( | 3473 return astFactory.fieldDeclaration( |
| 3456 commentAndMetadata.comment, | 3474 commentAndMetadata.comment, |
| 3457 commentAndMetadata.metadata, | 3475 commentAndMetadata.metadata, |
| 3458 staticKeyword, | 3476 staticKeyword, |
| 3459 fieldList, | 3477 fieldList, |
| 3460 _expect(TokenType.SEMICOLON)); | 3478 _expect(TokenType.SEMICOLON)); |
| 3461 } | 3479 } |
| 3462 | 3480 |
| 3463 /** | 3481 /** |
| 3464 * Parse an instance creation expression. The [keyword] is the 'new' or | 3482 * Parse an instance creation expression. The [keyword] is the 'new' or |
| 3465 * 'const' keyword that introduces the expression. Return the instance | 3483 * 'const' keyword that introduces the expression. Return the instance |
| 3466 * creation expression that was parsed. | 3484 * creation expression that was parsed. |
| 3467 * | 3485 * |
| 3468 * instanceCreationExpression ::= | 3486 * instanceCreationExpression ::= |
| 3469 * ('new' | 'const') type ('.' identifier)? argumentList | 3487 * ('new' | 'const') type ('.' identifier)? argumentList |
| 3470 */ | 3488 */ |
| 3471 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) { | 3489 InstanceCreationExpression parseInstanceCreationExpression(Token keyword) { |
| 3472 ConstructorName constructorName = parseConstructorName(); | 3490 ConstructorName constructorName = parseConstructorName(); |
| 3473 ArgumentList argumentList = _parseArgumentListChecked(); | 3491 ArgumentList argumentList = _parseArgumentListChecked(); |
| 3474 return new InstanceCreationExpression( | 3492 return astFactory.instanceCreationExpression( |
| 3475 keyword, constructorName, argumentList); | 3493 keyword, constructorName, argumentList); |
| 3476 } | 3494 } |
| 3477 | 3495 |
| 3478 /** | 3496 /** |
| 3479 * Parse a label. Return the label that was parsed. | 3497 * Parse a label. Return the label that was parsed. |
| 3480 * | 3498 * |
| 3481 * This method assumes that the current token matches an identifier and that | 3499 * This method assumes that the current token matches an identifier and that |
| 3482 * the following token matches `TokenType.COLON`. | 3500 * the following token matches `TokenType.COLON`. |
| 3483 * | 3501 * |
| 3484 * label ::= | 3502 * label ::= |
| 3485 * identifier ':' | 3503 * identifier ':' |
| 3486 */ | 3504 */ |
| 3487 Label parseLabel({bool isDeclaration: false}) { | 3505 Label parseLabel({bool isDeclaration: false}) { |
| 3488 SimpleIdentifier label = | 3506 SimpleIdentifier label = |
| 3489 _parseSimpleIdentifierUnchecked(isDeclaration: isDeclaration); | 3507 _parseSimpleIdentifierUnchecked(isDeclaration: isDeclaration); |
| 3490 Token colon = getAndAdvance(); | 3508 Token colon = getAndAdvance(); |
| 3491 return new Label(label, colon); | 3509 return astFactory.label(label, colon); |
| 3492 } | 3510 } |
| 3493 | 3511 |
| 3494 /** | 3512 /** |
| 3495 * Parse a library directive. The [commentAndMetadata] is the metadata to be | 3513 * Parse a library directive. The [commentAndMetadata] is the metadata to be |
| 3496 * associated with the directive. Return the library directive that was | 3514 * associated with the directive. Return the library directive that was |
| 3497 * parsed. | 3515 * parsed. |
| 3498 * | 3516 * |
| 3499 * This method assumes that the current token matches `Keyword.LIBRARY`. | 3517 * This method assumes that the current token matches `Keyword.LIBRARY`. |
| 3500 * | 3518 * |
| 3501 * libraryDirective ::= | 3519 * libraryDirective ::= |
| 3502 * metadata 'library' identifier ';' | 3520 * metadata 'library' identifier ';' |
| 3503 */ | 3521 */ |
| 3504 LibraryDirective parseLibraryDirective( | 3522 LibraryDirective parseLibraryDirective( |
| 3505 CommentAndMetadata commentAndMetadata) { | 3523 CommentAndMetadata commentAndMetadata) { |
| 3506 Token keyword = getAndAdvance(); | 3524 Token keyword = getAndAdvance(); |
| 3507 LibraryIdentifier libraryName = _parseLibraryName( | 3525 LibraryIdentifier libraryName = _parseLibraryName( |
| 3508 ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE, keyword); | 3526 ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE, keyword); |
| 3509 Token semicolon = _expect(TokenType.SEMICOLON); | 3527 Token semicolon = _expect(TokenType.SEMICOLON); |
| 3510 return new LibraryDirective(commentAndMetadata.comment, | 3528 return astFactory.libraryDirective(commentAndMetadata.comment, |
| 3511 commentAndMetadata.metadata, keyword, libraryName, semicolon); | 3529 commentAndMetadata.metadata, keyword, libraryName, semicolon); |
| 3512 } | 3530 } |
| 3513 | 3531 |
| 3514 /** | 3532 /** |
| 3515 * Parse a library identifier. Return the library identifier that was parsed. | 3533 * Parse a library identifier. Return the library identifier that was parsed. |
| 3516 * | 3534 * |
| 3517 * libraryIdentifier ::= | 3535 * libraryIdentifier ::= |
| 3518 * identifier ('.' identifier)* | 3536 * identifier ('.' identifier)* |
| 3519 */ | 3537 */ |
| 3520 LibraryIdentifier parseLibraryIdentifier() { | 3538 LibraryIdentifier parseLibraryIdentifier() { |
| 3521 List<SimpleIdentifier> components = <SimpleIdentifier>[]; | 3539 List<SimpleIdentifier> components = <SimpleIdentifier>[]; |
| 3522 components.add(parseSimpleIdentifier()); | 3540 components.add(parseSimpleIdentifier()); |
| 3523 while (_optional(TokenType.PERIOD)) { | 3541 while (_optional(TokenType.PERIOD)) { |
| 3524 components.add(parseSimpleIdentifier()); | 3542 components.add(parseSimpleIdentifier()); |
| 3525 } | 3543 } |
| 3526 return new LibraryIdentifier(components); | 3544 return astFactory.libraryIdentifier(components); |
| 3527 } | 3545 } |
| 3528 | 3546 |
| 3529 /** | 3547 /** |
| 3530 * Parse a list literal. The [modifier] is the 'const' modifier appearing | 3548 * Parse a list literal. The [modifier] is the 'const' modifier appearing |
| 3531 * before the literal, or `null` if there is no modifier. The [typeArguments] | 3549 * before the literal, or `null` if there is no modifier. The [typeArguments] |
| 3532 * is the type arguments appearing before the literal, or `null` if there are | 3550 * is the type arguments appearing before the literal, or `null` if there are |
| 3533 * no type arguments. Return the list literal that was parsed. | 3551 * no type arguments. Return the list literal that was parsed. |
| 3534 * | 3552 * |
| 3535 * This method assumes that the current token matches either | 3553 * This method assumes that the current token matches either |
| 3536 * `TokenType.OPEN_SQUARE_BRACKET` or `TokenType.INDEX`. | 3554 * `TokenType.OPEN_SQUARE_BRACKET` or `TokenType.INDEX`. |
| 3537 * | 3555 * |
| 3538 * listLiteral ::= | 3556 * listLiteral ::= |
| 3539 * 'const'? typeArguments? '[' (expressionList ','?)? ']' | 3557 * 'const'? typeArguments? '[' (expressionList ','?)? ']' |
| 3540 */ | 3558 */ |
| 3541 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) { | 3559 ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) { |
| 3542 if (_matches(TokenType.INDEX)) { | 3560 if (_matches(TokenType.INDEX)) { |
| 3543 _splitIndex(); | 3561 _splitIndex(); |
| 3544 return new ListLiteral( | 3562 return astFactory.listLiteral( |
| 3545 modifier, typeArguments, getAndAdvance(), null, getAndAdvance()); | 3563 modifier, typeArguments, getAndAdvance(), null, getAndAdvance()); |
| 3546 } | 3564 } |
| 3547 Token leftBracket = getAndAdvance(); | 3565 Token leftBracket = getAndAdvance(); |
| 3548 if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) { | 3566 if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) { |
| 3549 return new ListLiteral( | 3567 return astFactory.listLiteral( |
| 3550 modifier, typeArguments, leftBracket, null, getAndAdvance()); | 3568 modifier, typeArguments, leftBracket, null, getAndAdvance()); |
| 3551 } | 3569 } |
| 3552 bool wasInInitializer = _inInitializer; | 3570 bool wasInInitializer = _inInitializer; |
| 3553 _inInitializer = false; | 3571 _inInitializer = false; |
| 3554 try { | 3572 try { |
| 3555 List<Expression> elements = <Expression>[parseExpression2()]; | 3573 List<Expression> elements = <Expression>[parseExpression2()]; |
| 3556 while (_optional(TokenType.COMMA)) { | 3574 while (_optional(TokenType.COMMA)) { |
| 3557 if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) { | 3575 if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) { |
| 3558 return new ListLiteral( | 3576 return astFactory.listLiteral( |
| 3559 modifier, typeArguments, leftBracket, elements, getAndAdvance()); | 3577 modifier, typeArguments, leftBracket, elements, getAndAdvance()); |
| 3560 } | 3578 } |
| 3561 elements.add(parseExpression2()); | 3579 elements.add(parseExpression2()); |
| 3562 } | 3580 } |
| 3563 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); | 3581 Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET); |
| 3564 return new ListLiteral( | 3582 return astFactory.listLiteral( |
| 3565 modifier, typeArguments, leftBracket, elements, rightBracket); | 3583 modifier, typeArguments, leftBracket, elements, rightBracket); |
| 3566 } finally { | 3584 } finally { |
| 3567 _inInitializer = wasInInitializer; | 3585 _inInitializer = wasInInitializer; |
| 3568 } | 3586 } |
| 3569 } | 3587 } |
| 3570 | 3588 |
| 3571 /** | 3589 /** |
| 3572 * Parse a list or map literal. The [modifier] is the 'const' modifier | 3590 * Parse a list or map literal. The [modifier] is the 'const' modifier |
| 3573 * appearing before the literal, or `null` if there is no modifier. Return the | 3591 * appearing before the literal, or `null` if there is no modifier. Return the |
| 3574 * list or map literal that was parsed. | 3592 * list or map literal that was parsed. |
| 3575 * | 3593 * |
| 3576 * listOrMapLiteral ::= | 3594 * listOrMapLiteral ::= |
| 3577 * listLiteral | 3595 * listLiteral |
| 3578 * | mapLiteral | 3596 * | mapLiteral |
| 3579 */ | 3597 */ |
| 3580 TypedLiteral parseListOrMapLiteral(Token modifier) { | 3598 TypedLiteral parseListOrMapLiteral(Token modifier) { |
| 3581 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 3599 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 3582 if (_matches(TokenType.OPEN_CURLY_BRACKET)) { | 3600 if (_matches(TokenType.OPEN_CURLY_BRACKET)) { |
| 3583 return parseMapLiteral(modifier, typeArguments); | 3601 return parseMapLiteral(modifier, typeArguments); |
| 3584 } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) || | 3602 } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) || |
| 3585 _matches(TokenType.INDEX)) { | 3603 _matches(TokenType.INDEX)) { |
| 3586 return parseListLiteral(modifier, typeArguments); | 3604 return parseListLiteral(modifier, typeArguments); |
| 3587 } | 3605 } |
| 3588 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL); | 3606 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL); |
| 3589 return new ListLiteral( | 3607 return astFactory.listLiteral( |
| 3590 modifier, | 3608 modifier, |
| 3591 typeArguments, | 3609 typeArguments, |
| 3592 _createSyntheticToken(TokenType.OPEN_SQUARE_BRACKET), | 3610 _createSyntheticToken(TokenType.OPEN_SQUARE_BRACKET), |
| 3593 null, | 3611 null, |
| 3594 _createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET)); | 3612 _createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET)); |
| 3595 } | 3613 } |
| 3596 | 3614 |
| 3597 /** | 3615 /** |
| 3598 * Parse a logical and expression. Return the logical and expression that was | 3616 * Parse a logical and expression. Return the logical and expression that was |
| 3599 * parsed. | 3617 * parsed. |
| 3600 * | 3618 * |
| 3601 * logicalAndExpression ::= | 3619 * logicalAndExpression ::= |
| 3602 * equalityExpression ('&&' equalityExpression)* | 3620 * equalityExpression ('&&' equalityExpression)* |
| 3603 */ | 3621 */ |
| 3604 Expression parseLogicalAndExpression() { | 3622 Expression parseLogicalAndExpression() { |
| 3605 Expression expression = parseEqualityExpression(); | 3623 Expression expression = parseEqualityExpression(); |
| 3606 while (_currentToken.type == TokenType.AMPERSAND_AMPERSAND) { | 3624 while (_currentToken.type == TokenType.AMPERSAND_AMPERSAND) { |
| 3607 expression = new BinaryExpression( | 3625 expression = astFactory.binaryExpression( |
| 3608 expression, getAndAdvance(), parseEqualityExpression()); | 3626 expression, getAndAdvance(), parseEqualityExpression()); |
| 3609 } | 3627 } |
| 3610 return expression; | 3628 return expression; |
| 3611 } | 3629 } |
| 3612 | 3630 |
| 3613 /** | 3631 /** |
| 3614 * Parse a logical or expression. Return the logical or expression that was | 3632 * Parse a logical or expression. Return the logical or expression that was |
| 3615 * parsed. | 3633 * parsed. |
| 3616 * | 3634 * |
| 3617 * logicalOrExpression ::= | 3635 * logicalOrExpression ::= |
| 3618 * logicalAndExpression ('||' logicalAndExpression)* | 3636 * logicalAndExpression ('||' logicalAndExpression)* |
| 3619 */ | 3637 */ |
| 3620 Expression parseLogicalOrExpression() { | 3638 Expression parseLogicalOrExpression() { |
| 3621 Expression expression = parseLogicalAndExpression(); | 3639 Expression expression = parseLogicalAndExpression(); |
| 3622 while (_currentToken.type == TokenType.BAR_BAR) { | 3640 while (_currentToken.type == TokenType.BAR_BAR) { |
| 3623 expression = new BinaryExpression( | 3641 expression = astFactory.binaryExpression( |
| 3624 expression, getAndAdvance(), parseLogicalAndExpression()); | 3642 expression, getAndAdvance(), parseLogicalAndExpression()); |
| 3625 } | 3643 } |
| 3626 return expression; | 3644 return expression; |
| 3627 } | 3645 } |
| 3628 | 3646 |
| 3629 /** | 3647 /** |
| 3630 * Parse a map literal. The [modifier] is the 'const' modifier appearing | 3648 * Parse a map literal. The [modifier] is the 'const' modifier appearing |
| 3631 * before the literal, or `null` if there is no modifier. The [typeArguments] | 3649 * before the literal, or `null` if there is no modifier. The [typeArguments] |
| 3632 * is the type arguments that were declared, or `null` if there are no type | 3650 * is the type arguments that were declared, or `null` if there are no type |
| 3633 * arguments. Return the map literal that was parsed. | 3651 * arguments. Return the map literal that was parsed. |
| 3634 * | 3652 * |
| 3635 * This method assumes that the current token matches | 3653 * This method assumes that the current token matches |
| 3636 * `TokenType.OPEN_CURLY_BRACKET`. | 3654 * `TokenType.OPEN_CURLY_BRACKET`. |
| 3637 * | 3655 * |
| 3638 * mapLiteral ::= | 3656 * mapLiteral ::= |
| 3639 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' | 3657 * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' |
| 3640 */ | 3658 */ |
| 3641 MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) { | 3659 MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) { |
| 3642 Token leftBracket = getAndAdvance(); | 3660 Token leftBracket = getAndAdvance(); |
| 3643 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | 3661 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 3644 return new MapLiteral( | 3662 return astFactory.mapLiteral( |
| 3645 modifier, typeArguments, leftBracket, null, getAndAdvance()); | 3663 modifier, typeArguments, leftBracket, null, getAndAdvance()); |
| 3646 } | 3664 } |
| 3647 bool wasInInitializer = _inInitializer; | 3665 bool wasInInitializer = _inInitializer; |
| 3648 _inInitializer = false; | 3666 _inInitializer = false; |
| 3649 try { | 3667 try { |
| 3650 List<MapLiteralEntry> entries = <MapLiteralEntry>[parseMapLiteralEntry()]; | 3668 List<MapLiteralEntry> entries = <MapLiteralEntry>[parseMapLiteralEntry()]; |
| 3651 while (_optional(TokenType.COMMA)) { | 3669 while (_optional(TokenType.COMMA)) { |
| 3652 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | 3670 if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 3653 return new MapLiteral( | 3671 return astFactory.mapLiteral( |
| 3654 modifier, typeArguments, leftBracket, entries, getAndAdvance()); | 3672 modifier, typeArguments, leftBracket, entries, getAndAdvance()); |
| 3655 } | 3673 } |
| 3656 entries.add(parseMapLiteralEntry()); | 3674 entries.add(parseMapLiteralEntry()); |
| 3657 } | 3675 } |
| 3658 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 3676 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 3659 return new MapLiteral( | 3677 return astFactory.mapLiteral( |
| 3660 modifier, typeArguments, leftBracket, entries, rightBracket); | 3678 modifier, typeArguments, leftBracket, entries, rightBracket); |
| 3661 } finally { | 3679 } finally { |
| 3662 _inInitializer = wasInInitializer; | 3680 _inInitializer = wasInInitializer; |
| 3663 } | 3681 } |
| 3664 } | 3682 } |
| 3665 | 3683 |
| 3666 /** | 3684 /** |
| 3667 * Parse a map literal entry. Return the map literal entry that was parsed. | 3685 * Parse a map literal entry. Return the map literal entry that was parsed. |
| 3668 * | 3686 * |
| 3669 * mapLiteralEntry ::= | 3687 * mapLiteralEntry ::= |
| 3670 * expression ':' expression | 3688 * expression ':' expression |
| 3671 */ | 3689 */ |
| 3672 MapLiteralEntry parseMapLiteralEntry() { | 3690 MapLiteralEntry parseMapLiteralEntry() { |
| 3673 Expression key = parseExpression2(); | 3691 Expression key = parseExpression2(); |
| 3674 Token separator = _expect(TokenType.COLON); | 3692 Token separator = _expect(TokenType.COLON); |
| 3675 Expression value = parseExpression2(); | 3693 Expression value = parseExpression2(); |
| 3676 return new MapLiteralEntry(key, separator, value); | 3694 return astFactory.mapLiteralEntry(key, separator, value); |
| 3677 } | 3695 } |
| 3678 | 3696 |
| 3679 /** | 3697 /** |
| 3680 * Parse the modifiers preceding a declaration. This method allows the | 3698 * Parse the modifiers preceding a declaration. This method allows the |
| 3681 * modifiers to appear in any order but does generate errors for duplicated | 3699 * modifiers to appear in any order but does generate errors for duplicated |
| 3682 * modifiers. Checks for other problems, such as having the modifiers appear | 3700 * modifiers. Checks for other problems, such as having the modifiers appear |
| 3683 * in the wrong order or specifying both 'const' and 'final', are reported in | 3701 * in the wrong order or specifying both 'const' and 'final', are reported in |
| 3684 * one of the methods whose name is prefixed with `validateModifiersFor`. | 3702 * one of the methods whose name is prefixed with `validateModifiersFor`. |
| 3685 * Return the modifiers that were parsed. | 3703 * Return the modifiers that were parsed. |
| 3686 * | 3704 * |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3766 * that was parsed. | 3784 * that was parsed. |
| 3767 * | 3785 * |
| 3768 * multiplicativeExpression ::= | 3786 * multiplicativeExpression ::= |
| 3769 * unaryExpression (multiplicativeOperator unaryExpression)* | 3787 * unaryExpression (multiplicativeOperator unaryExpression)* |
| 3770 * | 'super' (multiplicativeOperator unaryExpression)+ | 3788 * | 'super' (multiplicativeOperator unaryExpression)+ |
| 3771 */ | 3789 */ |
| 3772 Expression parseMultiplicativeExpression() { | 3790 Expression parseMultiplicativeExpression() { |
| 3773 Expression expression; | 3791 Expression expression; |
| 3774 if (_currentToken.keyword == Keyword.SUPER && | 3792 if (_currentToken.keyword == Keyword.SUPER && |
| 3775 _currentToken.next.type.isMultiplicativeOperator) { | 3793 _currentToken.next.type.isMultiplicativeOperator) { |
| 3776 expression = new SuperExpression(getAndAdvance()); | 3794 expression = astFactory.superExpression(getAndAdvance()); |
| 3777 } else { | 3795 } else { |
| 3778 expression = parseUnaryExpression(); | 3796 expression = parseUnaryExpression(); |
| 3779 } | 3797 } |
| 3780 while (_currentToken.type.isMultiplicativeOperator) { | 3798 while (_currentToken.type.isMultiplicativeOperator) { |
| 3781 expression = new BinaryExpression( | 3799 expression = astFactory.binaryExpression( |
| 3782 expression, getAndAdvance(), parseUnaryExpression()); | 3800 expression, getAndAdvance(), parseUnaryExpression()); |
| 3783 } | 3801 } |
| 3784 return expression; | 3802 return expression; |
| 3785 } | 3803 } |
| 3786 | 3804 |
| 3787 /** | 3805 /** |
| 3788 * Parse a new expression. Return the new expression that was parsed. | 3806 * Parse a new expression. Return the new expression that was parsed. |
| 3789 * | 3807 * |
| 3790 * This method assumes that the current token matches `Keyword.NEW`. | 3808 * This method assumes that the current token matches `Keyword.NEW`. |
| 3791 * | 3809 * |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3816 * | functionSignature functionBody | 3834 * | functionSignature functionBody |
| 3817 */ | 3835 */ |
| 3818 Statement parseNonLabeledStatement() { | 3836 Statement parseNonLabeledStatement() { |
| 3819 // TODO(brianwilkerson) Pass the comment and metadata on where appropriate. | 3837 // TODO(brianwilkerson) Pass the comment and metadata on where appropriate. |
| 3820 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 3838 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 3821 TokenType type = _currentToken.type; | 3839 TokenType type = _currentToken.type; |
| 3822 if (type == TokenType.OPEN_CURLY_BRACKET) { | 3840 if (type == TokenType.OPEN_CURLY_BRACKET) { |
| 3823 if (_tokenMatches(_peek(), TokenType.STRING)) { | 3841 if (_tokenMatches(_peek(), TokenType.STRING)) { |
| 3824 Token afterString = skipStringLiteral(_currentToken.next); | 3842 Token afterString = skipStringLiteral(_currentToken.next); |
| 3825 if (afterString != null && afterString.type == TokenType.COLON) { | 3843 if (afterString != null && afterString.type == TokenType.COLON) { |
| 3826 return new ExpressionStatement( | 3844 return astFactory.expressionStatement( |
| 3827 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3845 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3828 } | 3846 } |
| 3829 } | 3847 } |
| 3830 return parseBlock(); | 3848 return parseBlock(); |
| 3831 } else if (type == TokenType.KEYWORD && | 3849 } else if (type == TokenType.KEYWORD && |
| 3832 !_currentToken.keyword.isPseudoKeyword) { | 3850 !_currentToken.keyword.isPseudoKeyword) { |
| 3833 Keyword keyword = _currentToken.keyword; | 3851 Keyword keyword = _currentToken.keyword; |
| 3834 // TODO(jwren) compute some metrics to figure out a better order for this | 3852 // TODO(jwren) compute some metrics to figure out a better order for this |
| 3835 // if-then sequence to optimize performance | 3853 // if-then sequence to optimize performance |
| 3836 if (keyword == Keyword.ASSERT) { | 3854 if (keyword == Keyword.ASSERT) { |
| 3837 return parseAssertStatement(); | 3855 return parseAssertStatement(); |
| 3838 } else if (keyword == Keyword.BREAK) { | 3856 } else if (keyword == Keyword.BREAK) { |
| 3839 return parseBreakStatement(); | 3857 return parseBreakStatement(); |
| 3840 } else if (keyword == Keyword.CONTINUE) { | 3858 } else if (keyword == Keyword.CONTINUE) { |
| 3841 return parseContinueStatement(); | 3859 return parseContinueStatement(); |
| 3842 } else if (keyword == Keyword.DO) { | 3860 } else if (keyword == Keyword.DO) { |
| 3843 return parseDoStatement(); | 3861 return parseDoStatement(); |
| 3844 } else if (keyword == Keyword.FOR) { | 3862 } else if (keyword == Keyword.FOR) { |
| 3845 return parseForStatement(); | 3863 return parseForStatement(); |
| 3846 } else if (keyword == Keyword.IF) { | 3864 } else if (keyword == Keyword.IF) { |
| 3847 return parseIfStatement(); | 3865 return parseIfStatement(); |
| 3848 } else if (keyword == Keyword.RETHROW) { | 3866 } else if (keyword == Keyword.RETHROW) { |
| 3849 return new ExpressionStatement( | 3867 return astFactory.expressionStatement( |
| 3850 parseRethrowExpression(), _expect(TokenType.SEMICOLON)); | 3868 parseRethrowExpression(), _expect(TokenType.SEMICOLON)); |
| 3851 } else if (keyword == Keyword.RETURN) { | 3869 } else if (keyword == Keyword.RETURN) { |
| 3852 return parseReturnStatement(); | 3870 return parseReturnStatement(); |
| 3853 } else if (keyword == Keyword.SWITCH) { | 3871 } else if (keyword == Keyword.SWITCH) { |
| 3854 return parseSwitchStatement(); | 3872 return parseSwitchStatement(); |
| 3855 } else if (keyword == Keyword.THROW) { | 3873 } else if (keyword == Keyword.THROW) { |
| 3856 return new ExpressionStatement( | 3874 return astFactory.expressionStatement( |
| 3857 parseThrowExpression(), _expect(TokenType.SEMICOLON)); | 3875 parseThrowExpression(), _expect(TokenType.SEMICOLON)); |
| 3858 } else if (keyword == Keyword.TRY) { | 3876 } else if (keyword == Keyword.TRY) { |
| 3859 return parseTryStatement(); | 3877 return parseTryStatement(); |
| 3860 } else if (keyword == Keyword.WHILE) { | 3878 } else if (keyword == Keyword.WHILE) { |
| 3861 return parseWhileStatement(); | 3879 return parseWhileStatement(); |
| 3862 } else if (keyword == Keyword.VAR || keyword == Keyword.FINAL) { | 3880 } else if (keyword == Keyword.VAR || keyword == Keyword.FINAL) { |
| 3863 return parseVariableDeclarationStatementAfterMetadata( | 3881 return parseVariableDeclarationStatementAfterMetadata( |
| 3864 commentAndMetadata); | 3882 commentAndMetadata); |
| 3865 } else if (keyword == Keyword.VOID) { | 3883 } else if (keyword == Keyword.VOID) { |
| 3866 TypeName returnType = | 3884 TypeName returnType = astFactory.typeName( |
| 3867 new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 3885 astFactory.simpleIdentifier(getAndAdvance()), null); |
| 3868 Token next = _currentToken.next; | 3886 Token next = _currentToken.next; |
| 3869 if (_matchesIdentifier() && | 3887 if (_matchesIdentifier() && |
| 3870 next.matchesAny(const <TokenType>[ | 3888 next.matchesAny(const <TokenType>[ |
| 3871 TokenType.OPEN_PAREN, | 3889 TokenType.OPEN_PAREN, |
| 3872 TokenType.OPEN_CURLY_BRACKET, | 3890 TokenType.OPEN_CURLY_BRACKET, |
| 3873 TokenType.FUNCTION, | 3891 TokenType.FUNCTION, |
| 3874 TokenType.LT | 3892 TokenType.LT |
| 3875 ])) { | 3893 ])) { |
| 3876 return _parseFunctionDeclarationStatementAfterReturnType( | 3894 return _parseFunctionDeclarationStatementAfterReturnType( |
| 3877 commentAndMetadata, returnType); | 3895 commentAndMetadata, returnType); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 3895 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { | 3913 } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) { |
| 3896 // | 3914 // |
| 3897 // We appear to have found an incomplete statement at the end of a | 3915 // We appear to have found an incomplete statement at the end of a |
| 3898 // block. Parse it as a variable declaration. | 3916 // block. Parse it as a variable declaration. |
| 3899 // | 3917 // |
| 3900 return _parseVariableDeclarationStatementAfterType( | 3918 return _parseVariableDeclarationStatementAfterType( |
| 3901 commentAndMetadata, null, returnType); | 3919 commentAndMetadata, null, returnType); |
| 3902 } | 3920 } |
| 3903 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); | 3921 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); |
| 3904 // TODO(brianwilkerson) Recover from this error. | 3922 // TODO(brianwilkerson) Recover from this error. |
| 3905 return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | 3923 return astFactory |
| 3924 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | |
| 3906 } | 3925 } |
| 3907 } else if (keyword == Keyword.CONST) { | 3926 } else if (keyword == Keyword.CONST) { |
| 3908 Token next = _currentToken.next; | 3927 Token next = _currentToken.next; |
| 3909 if (next.matchesAny(const <TokenType>[ | 3928 if (next.matchesAny(const <TokenType>[ |
| 3910 TokenType.LT, | 3929 TokenType.LT, |
| 3911 TokenType.OPEN_CURLY_BRACKET, | 3930 TokenType.OPEN_CURLY_BRACKET, |
| 3912 TokenType.OPEN_SQUARE_BRACKET, | 3931 TokenType.OPEN_SQUARE_BRACKET, |
| 3913 TokenType.INDEX | 3932 TokenType.INDEX |
| 3914 ])) { | 3933 ])) { |
| 3915 return new ExpressionStatement( | 3934 return astFactory.expressionStatement( |
| 3916 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3935 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3917 } else if (_tokenMatches(next, TokenType.IDENTIFIER)) { | 3936 } else if (_tokenMatches(next, TokenType.IDENTIFIER)) { |
| 3918 Token afterType = skipTypeName(next); | 3937 Token afterType = skipTypeName(next); |
| 3919 if (afterType != null) { | 3938 if (afterType != null) { |
| 3920 if (_tokenMatches(afterType, TokenType.OPEN_PAREN) || | 3939 if (_tokenMatches(afterType, TokenType.OPEN_PAREN) || |
| 3921 (_tokenMatches(afterType, TokenType.PERIOD) && | 3940 (_tokenMatches(afterType, TokenType.PERIOD) && |
| 3922 _tokenMatches(afterType.next, TokenType.IDENTIFIER) && | 3941 _tokenMatches(afterType.next, TokenType.IDENTIFIER) && |
| 3923 _tokenMatches(afterType.next.next, TokenType.OPEN_PAREN))) { | 3942 _tokenMatches(afterType.next.next, TokenType.OPEN_PAREN))) { |
| 3924 return new ExpressionStatement( | 3943 return astFactory.expressionStatement( |
| 3925 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3944 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3926 } | 3945 } |
| 3927 } | 3946 } |
| 3928 } | 3947 } |
| 3929 return parseVariableDeclarationStatementAfterMetadata( | 3948 return parseVariableDeclarationStatementAfterMetadata( |
| 3930 commentAndMetadata); | 3949 commentAndMetadata); |
| 3931 } else if (keyword == Keyword.NEW || | 3950 } else if (keyword == Keyword.NEW || |
| 3932 keyword == Keyword.TRUE || | 3951 keyword == Keyword.TRUE || |
| 3933 keyword == Keyword.FALSE || | 3952 keyword == Keyword.FALSE || |
| 3934 keyword == Keyword.NULL || | 3953 keyword == Keyword.NULL || |
| 3935 keyword == Keyword.SUPER || | 3954 keyword == Keyword.SUPER || |
| 3936 keyword == Keyword.THIS) { | 3955 keyword == Keyword.THIS) { |
| 3937 return new ExpressionStatement( | 3956 return astFactory.expressionStatement( |
| 3938 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3957 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3939 } else { | 3958 } else { |
| 3940 // | 3959 // |
| 3941 // We have found an error of some kind. Try to recover. | 3960 // We have found an error of some kind. Try to recover. |
| 3942 // | 3961 // |
| 3943 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); | 3962 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); |
| 3944 return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | 3963 return astFactory |
| 3964 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | |
| 3945 } | 3965 } |
| 3946 } else if (_inGenerator && _matchesString(_YIELD)) { | 3966 } else if (_inGenerator && _matchesString(_YIELD)) { |
| 3947 return parseYieldStatement(); | 3967 return parseYieldStatement(); |
| 3948 } else if (_inAsync && _matchesString(_AWAIT)) { | 3968 } else if (_inAsync && _matchesString(_AWAIT)) { |
| 3949 if (_tokenMatchesKeyword(_peek(), Keyword.FOR)) { | 3969 if (_tokenMatchesKeyword(_peek(), Keyword.FOR)) { |
| 3950 return parseForStatement(); | 3970 return parseForStatement(); |
| 3951 } | 3971 } |
| 3952 return new ExpressionStatement( | 3972 return astFactory.expressionStatement( |
| 3953 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3973 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3954 } else if (_matchesString(_AWAIT) && | 3974 } else if (_matchesString(_AWAIT) && |
| 3955 _tokenMatchesKeyword(_peek(), Keyword.FOR)) { | 3975 _tokenMatchesKeyword(_peek(), Keyword.FOR)) { |
| 3956 Token awaitToken = _currentToken; | 3976 Token awaitToken = _currentToken; |
| 3957 Statement statement = parseForStatement(); | 3977 Statement statement = parseForStatement(); |
| 3958 if (statement is! ForStatement) { | 3978 if (statement is! ForStatement) { |
| 3959 _reportErrorForToken( | 3979 _reportErrorForToken( |
| 3960 CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, awaitToken); | 3980 CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, awaitToken); |
| 3961 } | 3981 } |
| 3962 return statement; | 3982 return statement; |
| 3963 } else if (type == TokenType.SEMICOLON) { | 3983 } else if (type == TokenType.SEMICOLON) { |
| 3964 return parseEmptyStatement(); | 3984 return parseEmptyStatement(); |
| 3965 } else if (isInitializedVariableDeclaration()) { | 3985 } else if (isInitializedVariableDeclaration()) { |
| 3966 return parseVariableDeclarationStatementAfterMetadata(commentAndMetadata); | 3986 return parseVariableDeclarationStatementAfterMetadata(commentAndMetadata); |
| 3967 } else if (isFunctionDeclaration()) { | 3987 } else if (isFunctionDeclaration()) { |
| 3968 return parseFunctionDeclarationStatement(); | 3988 return parseFunctionDeclarationStatement(); |
| 3969 } else if (type == TokenType.CLOSE_CURLY_BRACKET) { | 3989 } else if (type == TokenType.CLOSE_CURLY_BRACKET) { |
| 3970 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); | 3990 _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT); |
| 3971 return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | 3991 return astFactory |
| 3992 .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON)); | |
| 3972 } else { | 3993 } else { |
| 3973 return new ExpressionStatement( | 3994 return astFactory.expressionStatement( |
| 3974 parseExpression2(), _expect(TokenType.SEMICOLON)); | 3995 parseExpression2(), _expect(TokenType.SEMICOLON)); |
| 3975 } | 3996 } |
| 3976 } | 3997 } |
| 3977 | 3998 |
| 3978 /** | 3999 /** |
| 3979 * Parse a normal formal parameter. Return the normal formal parameter that | 4000 * Parse a normal formal parameter. Return the normal formal parameter that |
| 3980 * was parsed. | 4001 * was parsed. |
| 3981 * | 4002 * |
| 3982 * normalFormalParameter ::= | 4003 * normalFormalParameter ::= |
| 3983 * functionSignature | 4004 * functionSignature |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 4009 FormalParameterList parameters = _parseFormalParameterListUnchecked(); | 4030 FormalParameterList parameters = _parseFormalParameterListUnchecked(); |
| 4010 if (thisKeyword == null) { | 4031 if (thisKeyword == null) { |
| 4011 if (holder.keyword != null) { | 4032 if (holder.keyword != null) { |
| 4012 _reportErrorForToken( | 4033 _reportErrorForToken( |
| 4013 ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword); | 4034 ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword); |
| 4014 } | 4035 } |
| 4015 Token question = null; | 4036 Token question = null; |
| 4016 if (enableNnbd && _matches(TokenType.QUESTION)) { | 4037 if (enableNnbd && _matches(TokenType.QUESTION)) { |
| 4017 question = getAndAdvance(); | 4038 question = getAndAdvance(); |
| 4018 } | 4039 } |
| 4019 return new FunctionTypedFormalParameter( | 4040 return astFactory.functionTypedFormalParameter( |
| 4020 commentAndMetadata.comment, | 4041 commentAndMetadata.comment, |
| 4021 commentAndMetadata.metadata, | 4042 commentAndMetadata.metadata, |
| 4022 holder.type, | 4043 holder.type, |
| 4023 new SimpleIdentifier(identifier.token, isDeclaration: true), | 4044 astFactory.simpleIdentifier(identifier.token, isDeclaration: true), |
| 4024 typeParameters, | 4045 typeParameters, |
| 4025 parameters, | 4046 parameters, |
| 4026 question: question); | 4047 question: question); |
| 4027 } else { | 4048 } else { |
| 4028 return new FieldFormalParameter( | 4049 return astFactory.fieldFormalParameter( |
| 4029 commentAndMetadata.comment, | 4050 commentAndMetadata.comment, |
| 4030 commentAndMetadata.metadata, | 4051 commentAndMetadata.metadata, |
| 4031 holder.keyword, | 4052 holder.keyword, |
| 4032 holder.type, | 4053 holder.type, |
| 4033 thisKeyword, | 4054 thisKeyword, |
| 4034 period, | 4055 period, |
| 4035 identifier, | 4056 identifier, |
| 4036 typeParameters, | 4057 typeParameters, |
| 4037 parameters); | 4058 parameters); |
| 4038 } | 4059 } |
| 4039 } else if (typeParameters != null) { | 4060 } else if (typeParameters != null) { |
| 4040 // TODO(brianwilkerson) Report an error. It looks like a function-typed | 4061 // TODO(brianwilkerson) Report an error. It looks like a function-typed |
| 4041 // parameter with no parameter list. | 4062 // parameter with no parameter list. |
| 4042 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters. endToken); | 4063 //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters. endToken); |
| 4043 } | 4064 } |
| 4044 TypeName type = holder.type; | 4065 TypeName type = holder.type; |
| 4045 if (type != null) { | 4066 if (type != null) { |
| 4046 if (_tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) { | 4067 if (_tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) { |
| 4047 _reportErrorForToken( | 4068 _reportErrorForToken( |
| 4048 ParserErrorCode.VOID_PARAMETER, type.name.beginToken); | 4069 ParserErrorCode.VOID_PARAMETER, type.name.beginToken); |
| 4049 } else if (holder.keyword != null && | 4070 } else if (holder.keyword != null && |
| 4050 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { | 4071 _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) { |
| 4051 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); | 4072 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword); |
| 4052 } | 4073 } |
| 4053 } | 4074 } |
| 4054 if (thisKeyword != null) { | 4075 if (thisKeyword != null) { |
| 4055 // TODO(brianwilkerson) If there are type parameters but no parameters, | 4076 // TODO(brianwilkerson) If there are type parameters but no parameters, |
| 4056 // should we create a synthetic empty parameter list here so we can | 4077 // should we create a synthetic empty parameter list here so we can |
| 4057 // capture the type parameters? | 4078 // capture the type parameters? |
| 4058 return new FieldFormalParameter( | 4079 return astFactory.fieldFormalParameter( |
| 4059 commentAndMetadata.comment, | 4080 commentAndMetadata.comment, |
| 4060 commentAndMetadata.metadata, | 4081 commentAndMetadata.metadata, |
| 4061 holder.keyword, | 4082 holder.keyword, |
| 4062 holder.type, | 4083 holder.type, |
| 4063 thisKeyword, | 4084 thisKeyword, |
| 4064 period, | 4085 period, |
| 4065 identifier, | 4086 identifier, |
| 4066 null, | 4087 null, |
| 4067 null); | 4088 null); |
| 4068 } | 4089 } |
| 4069 return new SimpleFormalParameter( | 4090 return astFactory.simpleFormalParameter( |
| 4070 commentAndMetadata.comment, | 4091 commentAndMetadata.comment, |
| 4071 commentAndMetadata.metadata, | 4092 commentAndMetadata.metadata, |
| 4072 holder.keyword, | 4093 holder.keyword, |
| 4073 holder.type, | 4094 holder.type, |
| 4074 new SimpleIdentifier(identifier.token, isDeclaration: true)); | 4095 astFactory.simpleIdentifier(identifier.token, isDeclaration: true)); |
| 4075 } | 4096 } |
| 4076 | 4097 |
| 4077 /** | 4098 /** |
| 4078 * Parse an operator declaration. The [commentAndMetadata] is the | 4099 * Parse an operator declaration. The [commentAndMetadata] is the |
| 4079 * documentation comment and metadata to be associated with the declaration. | 4100 * documentation comment and metadata to be associated with the declaration. |
| 4080 * The [externalKeyword] is the 'external' token. The [returnType] is the | 4101 * The [externalKeyword] is the 'external' token. The [returnType] is the |
| 4081 * return type that has already been parsed, or `null` if there was no return | 4102 * return type that has already been parsed, or `null` if there was no return |
| 4082 * type. Return the operator declaration that was parsed. | 4103 * type. Return the operator declaration that was parsed. |
| 4083 * | 4104 * |
| 4084 * operatorDeclaration ::= | 4105 * operatorDeclaration ::= |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4140 type == TokenType.QUESTION_PERIOD || | 4161 type == TokenType.QUESTION_PERIOD || |
| 4141 type == TokenType.OPEN_PAREN || | 4162 type == TokenType.OPEN_PAREN || |
| 4142 type == TokenType.LT || | 4163 type == TokenType.LT || |
| 4143 type == TokenType.INDEX) { | 4164 type == TokenType.INDEX) { |
| 4144 do { | 4165 do { |
| 4145 if (_isLikelyArgumentList()) { | 4166 if (_isLikelyArgumentList()) { |
| 4146 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 4167 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 4147 ArgumentList argumentList = parseArgumentList(); | 4168 ArgumentList argumentList = parseArgumentList(); |
| 4148 Expression currentOperand = operand; | 4169 Expression currentOperand = operand; |
| 4149 if (currentOperand is PropertyAccess) { | 4170 if (currentOperand is PropertyAccess) { |
| 4150 operand = new MethodInvocation( | 4171 operand = astFactory.methodInvocation( |
| 4151 currentOperand.target, | 4172 currentOperand.target, |
| 4152 currentOperand.operator, | 4173 currentOperand.operator, |
| 4153 currentOperand.propertyName, | 4174 currentOperand.propertyName, |
| 4154 typeArguments, | 4175 typeArguments, |
| 4155 argumentList); | 4176 argumentList); |
| 4156 } else { | 4177 } else { |
| 4157 operand = new FunctionExpressionInvocation( | 4178 operand = astFactory.functionExpressionInvocation( |
| 4158 operand, typeArguments, argumentList); | 4179 operand, typeArguments, argumentList); |
| 4159 } | 4180 } |
| 4160 } else { | 4181 } else { |
| 4161 operand = parseAssignableSelector(operand, true); | 4182 operand = parseAssignableSelector(operand, true); |
| 4162 } | 4183 } |
| 4163 type = _currentToken.type; | 4184 type = _currentToken.type; |
| 4164 } while (type == TokenType.OPEN_SQUARE_BRACKET || | 4185 } while (type == TokenType.OPEN_SQUARE_BRACKET || |
| 4165 type == TokenType.PERIOD || | 4186 type == TokenType.PERIOD || |
| 4166 type == TokenType.QUESTION_PERIOD || | 4187 type == TokenType.QUESTION_PERIOD || |
| 4167 type == TokenType.OPEN_PAREN || | 4188 type == TokenType.OPEN_PAREN || |
| 4168 type == TokenType.INDEX); | 4189 type == TokenType.INDEX); |
| 4169 return operand; | 4190 return operand; |
| 4170 } | 4191 } |
| 4171 if (!_currentToken.type.isIncrementOperator) { | 4192 if (!_currentToken.type.isIncrementOperator) { |
| 4172 return operand; | 4193 return operand; |
| 4173 } | 4194 } |
| 4174 _ensureAssignable(operand); | 4195 _ensureAssignable(operand); |
| 4175 Token operator = getAndAdvance(); | 4196 Token operator = getAndAdvance(); |
| 4176 return new PostfixExpression(operand, operator); | 4197 return astFactory.postfixExpression(operand, operator); |
| 4177 } | 4198 } |
| 4178 | 4199 |
| 4179 /** | 4200 /** |
| 4180 * Parse a prefixed identifier. Return the prefixed identifier that was | 4201 * Parse a prefixed identifier. Return the prefixed identifier that was |
| 4181 * parsed. | 4202 * parsed. |
| 4182 * | 4203 * |
| 4183 * prefixedIdentifier ::= | 4204 * prefixedIdentifier ::= |
| 4184 * identifier ('.' identifier)? | 4205 * identifier ('.' identifier)? |
| 4185 */ | 4206 */ |
| 4186 Identifier parsePrefixedIdentifier() { | 4207 Identifier parsePrefixedIdentifier() { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4229 if (type == TokenType.STRING) { | 4250 if (type == TokenType.STRING) { |
| 4230 return parseStringLiteral(); | 4251 return parseStringLiteral(); |
| 4231 } else if (type == TokenType.INT) { | 4252 } else if (type == TokenType.INT) { |
| 4232 Token token = getAndAdvance(); | 4253 Token token = getAndAdvance(); |
| 4233 int value = null; | 4254 int value = null; |
| 4234 try { | 4255 try { |
| 4235 value = int.parse(token.lexeme); | 4256 value = int.parse(token.lexeme); |
| 4236 } on FormatException { | 4257 } on FormatException { |
| 4237 // The invalid format should have been reported by the scanner. | 4258 // The invalid format should have been reported by the scanner. |
| 4238 } | 4259 } |
| 4239 return new IntegerLiteral(token, value); | 4260 return astFactory.integerLiteral(token, value); |
| 4240 } | 4261 } |
| 4241 Keyword keyword = _currentToken.keyword; | 4262 Keyword keyword = _currentToken.keyword; |
| 4242 if (keyword == Keyword.NULL) { | 4263 if (keyword == Keyword.NULL) { |
| 4243 return new NullLiteral(getAndAdvance()); | 4264 return astFactory.nullLiteral(getAndAdvance()); |
| 4244 } else if (keyword == Keyword.NEW) { | 4265 } else if (keyword == Keyword.NEW) { |
| 4245 return parseNewExpression(); | 4266 return parseNewExpression(); |
| 4246 } else if (keyword == Keyword.THIS) { | 4267 } else if (keyword == Keyword.THIS) { |
| 4247 return new ThisExpression(getAndAdvance()); | 4268 return astFactory.thisExpression(getAndAdvance()); |
| 4248 } else if (keyword == Keyword.SUPER) { | 4269 } else if (keyword == Keyword.SUPER) { |
| 4249 // TODO(paulberry): verify with Gilad that "super" must be followed by | 4270 // TODO(paulberry): verify with Gilad that "super" must be followed by |
| 4250 // unconditionalAssignableSelector in this case. | 4271 // unconditionalAssignableSelector in this case. |
| 4251 return parseAssignableSelector( | 4272 return parseAssignableSelector( |
| 4252 new SuperExpression(getAndAdvance()), false, | 4273 astFactory.superExpression(getAndAdvance()), false, |
| 4253 allowConditional: false); | 4274 allowConditional: false); |
| 4254 } else if (keyword == Keyword.FALSE) { | 4275 } else if (keyword == Keyword.FALSE) { |
| 4255 return new BooleanLiteral(getAndAdvance(), false); | 4276 return astFactory.booleanLiteral(getAndAdvance(), false); |
| 4256 } else if (keyword == Keyword.TRUE) { | 4277 } else if (keyword == Keyword.TRUE) { |
| 4257 return new BooleanLiteral(getAndAdvance(), true); | 4278 return astFactory.booleanLiteral(getAndAdvance(), true); |
| 4258 } | 4279 } |
| 4259 if (type == TokenType.DOUBLE) { | 4280 if (type == TokenType.DOUBLE) { |
| 4260 Token token = getAndAdvance(); | 4281 Token token = getAndAdvance(); |
| 4261 double value = 0.0; | 4282 double value = 0.0; |
| 4262 try { | 4283 try { |
| 4263 value = double.parse(token.lexeme); | 4284 value = double.parse(token.lexeme); |
| 4264 } on FormatException { | 4285 } on FormatException { |
| 4265 // The invalid format should have been reported by the scanner. | 4286 // The invalid format should have been reported by the scanner. |
| 4266 } | 4287 } |
| 4267 return new DoubleLiteral(token, value); | 4288 return astFactory.doubleLiteral(token, value); |
| 4268 } else if (type == TokenType.HEXADECIMAL) { | 4289 } else if (type == TokenType.HEXADECIMAL) { |
| 4269 Token token = getAndAdvance(); | 4290 Token token = getAndAdvance(); |
| 4270 int value = null; | 4291 int value = null; |
| 4271 try { | 4292 try { |
| 4272 value = int.parse(token.lexeme.substring(2), radix: 16); | 4293 value = int.parse(token.lexeme.substring(2), radix: 16); |
| 4273 } on FormatException { | 4294 } on FormatException { |
| 4274 // The invalid format should have been reported by the scanner. | 4295 // The invalid format should have been reported by the scanner. |
| 4275 } | 4296 } |
| 4276 return new IntegerLiteral(token, value); | 4297 return astFactory.integerLiteral(token, value); |
| 4277 } else if (keyword == Keyword.CONST) { | 4298 } else if (keyword == Keyword.CONST) { |
| 4278 return parseConstExpression(); | 4299 return parseConstExpression(); |
| 4279 } else if (type == TokenType.OPEN_PAREN) { | 4300 } else if (type == TokenType.OPEN_PAREN) { |
| 4280 if (isFunctionExpression(_currentToken)) { | 4301 if (isFunctionExpression(_currentToken)) { |
| 4281 return parseFunctionExpression(); | 4302 return parseFunctionExpression(); |
| 4282 } | 4303 } |
| 4283 Token leftParenthesis = getAndAdvance(); | 4304 Token leftParenthesis = getAndAdvance(); |
| 4284 bool wasInInitializer = _inInitializer; | 4305 bool wasInInitializer = _inInitializer; |
| 4285 _inInitializer = false; | 4306 _inInitializer = false; |
| 4286 try { | 4307 try { |
| 4287 Expression expression = parseExpression2(); | 4308 Expression expression = parseExpression2(); |
| 4288 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 4309 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 4289 return new ParenthesizedExpression( | 4310 return astFactory.parenthesizedExpression( |
| 4290 leftParenthesis, expression, rightParenthesis); | 4311 leftParenthesis, expression, rightParenthesis); |
| 4291 } finally { | 4312 } finally { |
| 4292 _inInitializer = wasInInitializer; | 4313 _inInitializer = wasInInitializer; |
| 4293 } | 4314 } |
| 4294 } else if (type == TokenType.LT || _injectGenericCommentTypeList()) { | 4315 } else if (type == TokenType.LT || _injectGenericCommentTypeList()) { |
| 4295 if (isFunctionExpression(currentToken)) { | 4316 if (isFunctionExpression(currentToken)) { |
| 4296 return parseFunctionExpression(); | 4317 return parseFunctionExpression(); |
| 4297 } | 4318 } |
| 4298 return parseListOrMapLiteral(null); | 4319 return parseListOrMapLiteral(null); |
| 4299 } else if (type == TokenType.OPEN_CURLY_BRACKET) { | 4320 } else if (type == TokenType.OPEN_CURLY_BRACKET) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4344 period = getAndAdvance(); | 4365 period = getAndAdvance(); |
| 4345 if (_matchesIdentifier()) { | 4366 if (_matchesIdentifier()) { |
| 4346 constructorName = _parseSimpleIdentifierUnchecked(isDeclaration: false); | 4367 constructorName = _parseSimpleIdentifierUnchecked(isDeclaration: false); |
| 4347 } else { | 4368 } else { |
| 4348 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); | 4369 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); |
| 4349 constructorName = createSyntheticIdentifier(isDeclaration: false); | 4370 constructorName = createSyntheticIdentifier(isDeclaration: false); |
| 4350 _advance(); | 4371 _advance(); |
| 4351 } | 4372 } |
| 4352 } | 4373 } |
| 4353 ArgumentList argumentList = _parseArgumentListChecked(); | 4374 ArgumentList argumentList = _parseArgumentListChecked(); |
| 4354 return new RedirectingConstructorInvocation( | 4375 return astFactory.redirectingConstructorInvocation( |
| 4355 keyword, period, constructorName, argumentList); | 4376 keyword, period, constructorName, argumentList); |
| 4356 } | 4377 } |
| 4357 | 4378 |
| 4358 /** | 4379 /** |
| 4359 * Parse a relational expression. Return the relational expression that was | 4380 * Parse a relational expression. Return the relational expression that was |
| 4360 * parsed. | 4381 * parsed. |
| 4361 * | 4382 * |
| 4362 * relationalExpression ::= | 4383 * relationalExpression ::= |
| 4363 * bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperato r bitwiseOrExpression)? | 4384 * bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperato r bitwiseOrExpression)? |
| 4364 * | 'super' relationalOperator bitwiseOrExpression | 4385 * | 'super' relationalOperator bitwiseOrExpression |
| 4365 */ | 4386 */ |
| 4366 Expression parseRelationalExpression() { | 4387 Expression parseRelationalExpression() { |
| 4367 if (_currentToken.keyword == Keyword.SUPER && | 4388 if (_currentToken.keyword == Keyword.SUPER && |
| 4368 _currentToken.next.type.isRelationalOperator) { | 4389 _currentToken.next.type.isRelationalOperator) { |
| 4369 Expression expression = new SuperExpression(getAndAdvance()); | 4390 Expression expression = astFactory.superExpression(getAndAdvance()); |
| 4370 Token operator = getAndAdvance(); | 4391 Token operator = getAndAdvance(); |
| 4371 return new BinaryExpression( | 4392 return astFactory.binaryExpression( |
| 4372 expression, operator, parseBitwiseOrExpression()); | 4393 expression, operator, parseBitwiseOrExpression()); |
| 4373 } | 4394 } |
| 4374 Expression expression = parseBitwiseOrExpression(); | 4395 Expression expression = parseBitwiseOrExpression(); |
| 4375 Keyword keyword = _currentToken.keyword; | 4396 Keyword keyword = _currentToken.keyword; |
| 4376 if (keyword == Keyword.AS) { | 4397 if (keyword == Keyword.AS) { |
| 4377 Token asOperator = getAndAdvance(); | 4398 Token asOperator = getAndAdvance(); |
| 4378 return new AsExpression(expression, asOperator, parseTypeName(true)); | 4399 return astFactory.asExpression( |
| 4400 expression, asOperator, parseTypeName(true)); | |
| 4379 } else if (keyword == Keyword.IS) { | 4401 } else if (keyword == Keyword.IS) { |
| 4380 Token isOperator = getAndAdvance(); | 4402 Token isOperator = getAndAdvance(); |
| 4381 Token notOperator = null; | 4403 Token notOperator = null; |
| 4382 if (_matches(TokenType.BANG)) { | 4404 if (_matches(TokenType.BANG)) { |
| 4383 notOperator = getAndAdvance(); | 4405 notOperator = getAndAdvance(); |
| 4384 } | 4406 } |
| 4385 return new IsExpression( | 4407 return astFactory.isExpression( |
| 4386 expression, isOperator, notOperator, parseTypeName(true)); | 4408 expression, isOperator, notOperator, parseTypeName(true)); |
| 4387 } else if (_currentToken.type.isRelationalOperator) { | 4409 } else if (_currentToken.type.isRelationalOperator) { |
| 4388 Token operator = getAndAdvance(); | 4410 Token operator = getAndAdvance(); |
| 4389 return new BinaryExpression( | 4411 return astFactory.binaryExpression( |
| 4390 expression, operator, parseBitwiseOrExpression()); | 4412 expression, operator, parseBitwiseOrExpression()); |
| 4391 } | 4413 } |
| 4392 return expression; | 4414 return expression; |
| 4393 } | 4415 } |
| 4394 | 4416 |
| 4395 /** | 4417 /** |
| 4396 * Parse a rethrow expression. Return the rethrow expression that was parsed. | 4418 * Parse a rethrow expression. Return the rethrow expression that was parsed. |
| 4397 * | 4419 * |
| 4398 * This method assumes that the current token matches `Keyword.RETHROW`. | 4420 * This method assumes that the current token matches `Keyword.RETHROW`. |
| 4399 * | 4421 * |
| 4400 * rethrowExpression ::= | 4422 * rethrowExpression ::= |
| 4401 * 'rethrow' | 4423 * 'rethrow' |
| 4402 */ | 4424 */ |
| 4403 Expression parseRethrowExpression() => new RethrowExpression(getAndAdvance()); | 4425 Expression parseRethrowExpression() => |
| 4426 astFactory.rethrowExpression(getAndAdvance()); | |
| 4404 | 4427 |
| 4405 /** | 4428 /** |
| 4406 * Parse a return statement. Return the return statement that was parsed. | 4429 * Parse a return statement. Return the return statement that was parsed. |
| 4407 * | 4430 * |
| 4408 * This method assumes that the current token matches `Keyword.RETURN`. | 4431 * This method assumes that the current token matches `Keyword.RETURN`. |
| 4409 * | 4432 * |
| 4410 * returnStatement ::= | 4433 * returnStatement ::= |
| 4411 * 'return' expression? ';' | 4434 * 'return' expression? ';' |
| 4412 */ | 4435 */ |
| 4413 Statement parseReturnStatement() { | 4436 Statement parseReturnStatement() { |
| 4414 Token returnKeyword = getAndAdvance(); | 4437 Token returnKeyword = getAndAdvance(); |
| 4415 if (_matches(TokenType.SEMICOLON)) { | 4438 if (_matches(TokenType.SEMICOLON)) { |
| 4416 return new ReturnStatement(returnKeyword, null, getAndAdvance()); | 4439 return astFactory.returnStatement(returnKeyword, null, getAndAdvance()); |
| 4417 } | 4440 } |
| 4418 Expression expression = parseExpression2(); | 4441 Expression expression = parseExpression2(); |
| 4419 Token semicolon = _expect(TokenType.SEMICOLON); | 4442 Token semicolon = _expect(TokenType.SEMICOLON); |
| 4420 return new ReturnStatement(returnKeyword, expression, semicolon); | 4443 return astFactory.returnStatement(returnKeyword, expression, semicolon); |
| 4421 } | 4444 } |
| 4422 | 4445 |
| 4423 /** | 4446 /** |
| 4424 * Parse a return type. Return the return type that was parsed. | 4447 * Parse a return type. Return the return type that was parsed. |
| 4425 * | 4448 * |
| 4426 * returnType ::= | 4449 * returnType ::= |
| 4427 * 'void' | 4450 * 'void' |
| 4428 * | type | 4451 * | type |
| 4429 */ | 4452 */ |
| 4430 TypeName parseReturnType() { | 4453 TypeName parseReturnType() { |
| 4431 if (_currentToken.keyword == Keyword.VOID) { | 4454 if (_currentToken.keyword == Keyword.VOID) { |
| 4432 return new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 4455 return astFactory.typeName( |
| 4456 astFactory.simpleIdentifier(getAndAdvance()), null); | |
| 4433 } else { | 4457 } else { |
| 4434 return parseTypeName(false); | 4458 return parseTypeName(false); |
| 4435 } | 4459 } |
| 4436 } | 4460 } |
| 4437 | 4461 |
| 4438 /** | 4462 /** |
| 4439 * Parse a setter. The [commentAndMetadata] is the documentation comment and | 4463 * Parse a setter. The [commentAndMetadata] is the documentation comment and |
| 4440 * metadata to be associated with the declaration. The [externalKeyword] is | 4464 * metadata to be associated with the declaration. The [externalKeyword] is |
| 4441 * the 'external' token. The [staticKeyword] is the static keyword, or `null` | 4465 * the 'external' token. The [staticKeyword] is the static keyword, or `null` |
| 4442 * if the setter is not static. The [returnType] is the return type that has | 4466 * if the setter is not static. The [returnType] is the return type that has |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 4457 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 4481 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 4458 FormalParameterList parameters = parseFormalParameterList(); | 4482 FormalParameterList parameters = parseFormalParameterList(); |
| 4459 _validateFormalParameterList(parameters); | 4483 _validateFormalParameterList(parameters); |
| 4460 FunctionBody body = parseFunctionBody( | 4484 FunctionBody body = parseFunctionBody( |
| 4461 externalKeyword != null || staticKeyword == null, | 4485 externalKeyword != null || staticKeyword == null, |
| 4462 ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, | 4486 ParserErrorCode.STATIC_SETTER_WITHOUT_BODY, |
| 4463 false); | 4487 false); |
| 4464 if (externalKeyword != null && body is! EmptyFunctionBody) { | 4488 if (externalKeyword != null && body is! EmptyFunctionBody) { |
| 4465 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY); | 4489 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_SETTER_WITH_BODY); |
| 4466 } | 4490 } |
| 4467 return new MethodDeclaration( | 4491 return astFactory.methodDeclaration( |
| 4468 commentAndMetadata.comment, | 4492 commentAndMetadata.comment, |
| 4469 commentAndMetadata.metadata, | 4493 commentAndMetadata.metadata, |
| 4470 externalKeyword, | 4494 externalKeyword, |
| 4471 staticKeyword, | 4495 staticKeyword, |
| 4472 returnType, | 4496 returnType, |
| 4473 propertyKeyword, | 4497 propertyKeyword, |
| 4474 null, | 4498 null, |
| 4475 name, | 4499 name, |
| 4476 null, | 4500 null, |
| 4477 parameters, | 4501 parameters, |
| 4478 body); | 4502 body); |
| 4479 } | 4503 } |
| 4480 | 4504 |
| 4481 /** | 4505 /** |
| 4482 * Parse a shift expression. Return the shift expression that was parsed. | 4506 * Parse a shift expression. Return the shift expression that was parsed. |
| 4483 * | 4507 * |
| 4484 * shiftExpression ::= | 4508 * shiftExpression ::= |
| 4485 * additiveExpression (shiftOperator additiveExpression)* | 4509 * additiveExpression (shiftOperator additiveExpression)* |
| 4486 * | 'super' (shiftOperator additiveExpression)+ | 4510 * | 'super' (shiftOperator additiveExpression)+ |
| 4487 */ | 4511 */ |
| 4488 Expression parseShiftExpression() { | 4512 Expression parseShiftExpression() { |
| 4489 Expression expression; | 4513 Expression expression; |
| 4490 if (_currentToken.keyword == Keyword.SUPER && | 4514 if (_currentToken.keyword == Keyword.SUPER && |
| 4491 _currentToken.next.type.isShiftOperator) { | 4515 _currentToken.next.type.isShiftOperator) { |
| 4492 expression = new SuperExpression(getAndAdvance()); | 4516 expression = astFactory.superExpression(getAndAdvance()); |
| 4493 } else { | 4517 } else { |
| 4494 expression = parseAdditiveExpression(); | 4518 expression = parseAdditiveExpression(); |
| 4495 } | 4519 } |
| 4496 while (_currentToken.type.isShiftOperator) { | 4520 while (_currentToken.type.isShiftOperator) { |
| 4497 expression = new BinaryExpression( | 4521 expression = astFactory.binaryExpression( |
| 4498 expression, getAndAdvance(), parseAdditiveExpression()); | 4522 expression, getAndAdvance(), parseAdditiveExpression()); |
| 4499 } | 4523 } |
| 4500 return expression; | 4524 return expression; |
| 4501 } | 4525 } |
| 4502 | 4526 |
| 4503 /** | 4527 /** |
| 4504 * Parse a simple identifier. Return the simple identifier that was parsed. | 4528 * Parse a simple identifier. Return the simple identifier that was parsed. |
| 4505 * | 4529 * |
| 4506 * identifier ::= | 4530 * identifier ::= |
| 4507 * IDENTIFIER | 4531 * IDENTIFIER |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 4537 if (labels == null) { | 4561 if (labels == null) { |
| 4538 labels = <Label>[label]; | 4562 labels = <Label>[label]; |
| 4539 } else { | 4563 } else { |
| 4540 labels.add(label); | 4564 labels.add(label); |
| 4541 } | 4565 } |
| 4542 } | 4566 } |
| 4543 Statement statement = parseNonLabeledStatement(); | 4567 Statement statement = parseNonLabeledStatement(); |
| 4544 if (labels == null) { | 4568 if (labels == null) { |
| 4545 return statement; | 4569 return statement; |
| 4546 } | 4570 } |
| 4547 return new LabeledStatement(labels, statement); | 4571 return astFactory.labeledStatement(labels, statement); |
| 4548 } | 4572 } |
| 4549 | 4573 |
| 4550 /** | 4574 /** |
| 4551 * Parse a sequence of statements, starting with the given [token]. Return the | 4575 * Parse a sequence of statements, starting with the given [token]. Return the |
| 4552 * statements that were parsed, or `null` if the tokens do not represent a | 4576 * statements that were parsed, or `null` if the tokens do not represent a |
| 4553 * recognizable sequence of statements. | 4577 * recognizable sequence of statements. |
| 4554 */ | 4578 */ |
| 4555 List<Statement> parseStatements(Token token) { | 4579 List<Statement> parseStatements(Token token) { |
| 4556 _currentToken = token; | 4580 _currentToken = token; |
| 4557 return _parseStatementList(); | 4581 return _parseStatementList(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 4583 */ | 4607 */ |
| 4584 SuperConstructorInvocation parseSuperConstructorInvocation() { | 4608 SuperConstructorInvocation parseSuperConstructorInvocation() { |
| 4585 Token keyword = getAndAdvance(); | 4609 Token keyword = getAndAdvance(); |
| 4586 Token period = null; | 4610 Token period = null; |
| 4587 SimpleIdentifier constructorName = null; | 4611 SimpleIdentifier constructorName = null; |
| 4588 if (_matches(TokenType.PERIOD)) { | 4612 if (_matches(TokenType.PERIOD)) { |
| 4589 period = getAndAdvance(); | 4613 period = getAndAdvance(); |
| 4590 constructorName = parseSimpleIdentifier(); | 4614 constructorName = parseSimpleIdentifier(); |
| 4591 } | 4615 } |
| 4592 ArgumentList argumentList = _parseArgumentListChecked(); | 4616 ArgumentList argumentList = _parseArgumentListChecked(); |
| 4593 return new SuperConstructorInvocation( | 4617 return astFactory.superConstructorInvocation( |
| 4594 keyword, period, constructorName, argumentList); | 4618 keyword, period, constructorName, argumentList); |
| 4595 } | 4619 } |
| 4596 | 4620 |
| 4597 /** | 4621 /** |
| 4598 * Parse a switch statement. Return the switch statement that was parsed. | 4622 * Parse a switch statement. Return the switch statement that was parsed. |
| 4599 * | 4623 * |
| 4600 * switchStatement ::= | 4624 * switchStatement ::= |
| 4601 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}' | 4625 * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}' |
| 4602 * | 4626 * |
| 4603 * switchCase ::= | 4627 * switchCase ::= |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 4628 String label = identifier.token.lexeme; | 4652 String label = identifier.token.lexeme; |
| 4629 if (definedLabels.contains(label)) { | 4653 if (definedLabels.contains(label)) { |
| 4630 _reportErrorForToken( | 4654 _reportErrorForToken( |
| 4631 ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, | 4655 ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, |
| 4632 identifier.token, | 4656 identifier.token, |
| 4633 [label]); | 4657 [label]); |
| 4634 } else { | 4658 } else { |
| 4635 definedLabels.add(label); | 4659 definedLabels.add(label); |
| 4636 } | 4660 } |
| 4637 Token colon = getAndAdvance(); | 4661 Token colon = getAndAdvance(); |
| 4638 labels.add(new Label(identifier, colon)); | 4662 labels.add(astFactory.label(identifier, colon)); |
| 4639 } | 4663 } |
| 4640 Keyword keyword = _currentToken.keyword; | 4664 Keyword keyword = _currentToken.keyword; |
| 4641 if (keyword == Keyword.CASE) { | 4665 if (keyword == Keyword.CASE) { |
| 4642 Token caseKeyword = getAndAdvance(); | 4666 Token caseKeyword = getAndAdvance(); |
| 4643 Expression caseExpression = parseExpression2(); | 4667 Expression caseExpression = parseExpression2(); |
| 4644 Token colon = _expect(TokenType.COLON); | 4668 Token colon = _expect(TokenType.COLON); |
| 4645 members.add(new SwitchCase(labels, caseKeyword, caseExpression, colon, | 4669 members.add(astFactory.switchCase(labels, caseKeyword, caseExpression, |
| 4646 _parseStatementList())); | 4670 colon, _parseStatementList())); |
| 4647 if (defaultKeyword != null) { | 4671 if (defaultKeyword != null) { |
| 4648 _reportErrorForToken( | 4672 _reportErrorForToken( |
| 4649 ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, | 4673 ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE, |
| 4650 caseKeyword); | 4674 caseKeyword); |
| 4651 } | 4675 } |
| 4652 } else if (keyword == Keyword.DEFAULT) { | 4676 } else if (keyword == Keyword.DEFAULT) { |
| 4653 if (defaultKeyword != null) { | 4677 if (defaultKeyword != null) { |
| 4654 _reportErrorForToken( | 4678 _reportErrorForToken( |
| 4655 ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, _peek()); | 4679 ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, _peek()); |
| 4656 } | 4680 } |
| 4657 defaultKeyword = getAndAdvance(); | 4681 defaultKeyword = getAndAdvance(); |
| 4658 Token colon = _expect(TokenType.COLON); | 4682 Token colon = _expect(TokenType.COLON); |
| 4659 members.add(new SwitchDefault( | 4683 members.add(astFactory.switchDefault( |
| 4660 labels, defaultKeyword, colon, _parseStatementList())); | 4684 labels, defaultKeyword, colon, _parseStatementList())); |
| 4661 } else { | 4685 } else { |
| 4662 // We need to advance, otherwise we could end up in an infinite loop, | 4686 // We need to advance, otherwise we could end up in an infinite loop, |
| 4663 // but this could be a lot smarter about recovering from the error. | 4687 // but this could be a lot smarter about recovering from the error. |
| 4664 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT); | 4688 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT); |
| 4665 bool atEndOrNextMember() { | 4689 bool atEndOrNextMember() { |
| 4666 TokenType type = _currentToken.type; | 4690 TokenType type = _currentToken.type; |
| 4667 if (type == TokenType.EOF || | 4691 if (type == TokenType.EOF || |
| 4668 type == TokenType.CLOSE_CURLY_BRACKET) { | 4692 type == TokenType.CLOSE_CURLY_BRACKET) { |
| 4669 return true; | 4693 return true; |
| 4670 } | 4694 } |
| 4671 Keyword keyword = _currentToken.keyword; | 4695 Keyword keyword = _currentToken.keyword; |
| 4672 return keyword == Keyword.CASE || keyword == Keyword.DEFAULT; | 4696 return keyword == Keyword.CASE || keyword == Keyword.DEFAULT; |
| 4673 } | 4697 } |
| 4674 | 4698 |
| 4675 while (!atEndOrNextMember()) { | 4699 while (!atEndOrNextMember()) { |
| 4676 _advance(); | 4700 _advance(); |
| 4677 } | 4701 } |
| 4678 } | 4702 } |
| 4679 type = _currentToken.type; | 4703 type = _currentToken.type; |
| 4680 } | 4704 } |
| 4681 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 4705 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 4682 return new SwitchStatement(keyword, leftParenthesis, expression, | 4706 return astFactory.switchStatement(keyword, leftParenthesis, expression, |
| 4683 rightParenthesis, leftBracket, members, rightBracket); | 4707 rightParenthesis, leftBracket, members, rightBracket); |
| 4684 } finally { | 4708 } finally { |
| 4685 _inSwitch = wasInSwitch; | 4709 _inSwitch = wasInSwitch; |
| 4686 } | 4710 } |
| 4687 } | 4711 } |
| 4688 | 4712 |
| 4689 /** | 4713 /** |
| 4690 * Parse a symbol literal. Return the symbol literal that was parsed. | 4714 * Parse a symbol literal. Return the symbol literal that was parsed. |
| 4691 * | 4715 * |
| 4692 * This method assumes that the current token matches [TokenType.HASH]. | 4716 * This method assumes that the current token matches [TokenType.HASH]. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 4709 } | 4733 } |
| 4710 } | 4734 } |
| 4711 } else if (_currentToken.isOperator) { | 4735 } else if (_currentToken.isOperator) { |
| 4712 components.add(getAndAdvance()); | 4736 components.add(getAndAdvance()); |
| 4713 } else if (_matchesKeyword(Keyword.VOID)) { | 4737 } else if (_matchesKeyword(Keyword.VOID)) { |
| 4714 components.add(getAndAdvance()); | 4738 components.add(getAndAdvance()); |
| 4715 } else { | 4739 } else { |
| 4716 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); | 4740 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); |
| 4717 components.add(_createSyntheticToken(TokenType.IDENTIFIER)); | 4741 components.add(_createSyntheticToken(TokenType.IDENTIFIER)); |
| 4718 } | 4742 } |
| 4719 return new SymbolLiteral(poundSign, components); | 4743 return astFactory.symbolLiteral(poundSign, components); |
| 4720 } | 4744 } |
| 4721 | 4745 |
| 4722 /** | 4746 /** |
| 4723 * Parse a throw expression. Return the throw expression that was parsed. | 4747 * Parse a throw expression. Return the throw expression that was parsed. |
| 4724 * | 4748 * |
| 4725 * This method assumes that the current token matches [Keyword.THROW]. | 4749 * This method assumes that the current token matches [Keyword.THROW]. |
| 4726 * | 4750 * |
| 4727 * throwExpression ::= | 4751 * throwExpression ::= |
| 4728 * 'throw' expression | 4752 * 'throw' expression |
| 4729 */ | 4753 */ |
| 4730 Expression parseThrowExpression() { | 4754 Expression parseThrowExpression() { |
| 4731 Token keyword = getAndAdvance(); | 4755 Token keyword = getAndAdvance(); |
| 4732 TokenType type = _currentToken.type; | 4756 TokenType type = _currentToken.type; |
| 4733 if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) { | 4757 if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) { |
| 4734 _reportErrorForToken( | 4758 _reportErrorForToken( |
| 4735 ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken); | 4759 ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken); |
| 4736 return new ThrowExpression(keyword, createSyntheticIdentifier()); | 4760 return astFactory.throwExpression(keyword, createSyntheticIdentifier()); |
| 4737 } | 4761 } |
| 4738 Expression expression = parseExpression2(); | 4762 Expression expression = parseExpression2(); |
| 4739 return new ThrowExpression(keyword, expression); | 4763 return astFactory.throwExpression(keyword, expression); |
| 4740 } | 4764 } |
| 4741 | 4765 |
| 4742 /** | 4766 /** |
| 4743 * Parse a throw expression. Return the throw expression that was parsed. | 4767 * Parse a throw expression. Return the throw expression that was parsed. |
| 4744 * | 4768 * |
| 4745 * This method assumes that the current token matches [Keyword.THROW]. | 4769 * This method assumes that the current token matches [Keyword.THROW]. |
| 4746 * | 4770 * |
| 4747 * throwExpressionWithoutCascade ::= | 4771 * throwExpressionWithoutCascade ::= |
| 4748 * 'throw' expressionWithoutCascade | 4772 * 'throw' expressionWithoutCascade |
| 4749 */ | 4773 */ |
| 4750 Expression parseThrowExpressionWithoutCascade() { | 4774 Expression parseThrowExpressionWithoutCascade() { |
| 4751 Token keyword = getAndAdvance(); | 4775 Token keyword = getAndAdvance(); |
| 4752 TokenType type = _currentToken.type; | 4776 TokenType type = _currentToken.type; |
| 4753 if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) { | 4777 if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) { |
| 4754 _reportErrorForToken( | 4778 _reportErrorForToken( |
| 4755 ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken); | 4779 ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken); |
| 4756 return new ThrowExpression(keyword, createSyntheticIdentifier()); | 4780 return astFactory.throwExpression(keyword, createSyntheticIdentifier()); |
| 4757 } | 4781 } |
| 4758 Expression expression = parseExpressionWithoutCascade(); | 4782 Expression expression = parseExpressionWithoutCascade(); |
| 4759 return new ThrowExpression(keyword, expression); | 4783 return astFactory.throwExpression(keyword, expression); |
| 4760 } | 4784 } |
| 4761 | 4785 |
| 4762 /** | 4786 /** |
| 4763 * Parse a try statement. Return the try statement that was parsed. | 4787 * Parse a try statement. Return the try statement that was parsed. |
| 4764 * | 4788 * |
| 4765 * This method assumes that the current token matches [Keyword.TRY]. | 4789 * This method assumes that the current token matches [Keyword.TRY]. |
| 4766 * | 4790 * |
| 4767 * tryStatement ::= | 4791 * tryStatement ::= |
| 4768 * 'try' block (onPart+ finallyPart? | finallyPart) | 4792 * 'try' block (onPart+ finallyPart? | finallyPart) |
| 4769 * | 4793 * |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 4799 catchKeyword = getAndAdvance(); | 4823 catchKeyword = getAndAdvance(); |
| 4800 leftParenthesis = _expect(TokenType.OPEN_PAREN); | 4824 leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| 4801 exceptionParameter = parseSimpleIdentifier(isDeclaration: true); | 4825 exceptionParameter = parseSimpleIdentifier(isDeclaration: true); |
| 4802 if (_matches(TokenType.COMMA)) { | 4826 if (_matches(TokenType.COMMA)) { |
| 4803 comma = getAndAdvance(); | 4827 comma = getAndAdvance(); |
| 4804 stackTraceParameter = parseSimpleIdentifier(isDeclaration: true); | 4828 stackTraceParameter = parseSimpleIdentifier(isDeclaration: true); |
| 4805 } | 4829 } |
| 4806 rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 4830 rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 4807 } | 4831 } |
| 4808 Block catchBody = _parseBlockChecked(); | 4832 Block catchBody = _parseBlockChecked(); |
| 4809 catchClauses.add(new CatchClause( | 4833 catchClauses.add(astFactory.catchClause( |
| 4810 onKeyword, | 4834 onKeyword, |
| 4811 exceptionType, | 4835 exceptionType, |
| 4812 catchKeyword, | 4836 catchKeyword, |
| 4813 leftParenthesis, | 4837 leftParenthesis, |
| 4814 exceptionParameter, | 4838 exceptionParameter, |
| 4815 comma, | 4839 comma, |
| 4816 stackTraceParameter, | 4840 stackTraceParameter, |
| 4817 rightParenthesis, | 4841 rightParenthesis, |
| 4818 catchBody)); | 4842 catchBody)); |
| 4819 } | 4843 } |
| 4820 Token finallyKeyword = null; | 4844 Token finallyKeyword = null; |
| 4821 if (_matchesKeyword(Keyword.FINALLY)) { | 4845 if (_matchesKeyword(Keyword.FINALLY)) { |
| 4822 finallyKeyword = getAndAdvance(); | 4846 finallyKeyword = getAndAdvance(); |
| 4823 finallyClause = _parseBlockChecked(); | 4847 finallyClause = _parseBlockChecked(); |
| 4824 } else if (catchClauses.isEmpty) { | 4848 } else if (catchClauses.isEmpty) { |
| 4825 _reportErrorForCurrentToken(ParserErrorCode.MISSING_CATCH_OR_FINALLY); | 4849 _reportErrorForCurrentToken(ParserErrorCode.MISSING_CATCH_OR_FINALLY); |
| 4826 } | 4850 } |
| 4827 return new TryStatement( | 4851 return astFactory.tryStatement( |
| 4828 tryKeyword, body, catchClauses, finallyKeyword, finallyClause); | 4852 tryKeyword, body, catchClauses, finallyKeyword, finallyClause); |
| 4829 } | 4853 } |
| 4830 | 4854 |
| 4831 /** | 4855 /** |
| 4832 * Parse a type alias. The [commentAndMetadata] is the metadata to be | 4856 * Parse a type alias. The [commentAndMetadata] is the metadata to be |
| 4833 * associated with the member. Return the type alias that was parsed. | 4857 * associated with the member. Return the type alias that was parsed. |
| 4834 * | 4858 * |
| 4835 * This method assumes that the current token matches [Keyword.TYPEDEF]. | 4859 * This method assumes that the current token matches [Keyword.TYPEDEF]. |
| 4836 * | 4860 * |
| 4837 * typeAlias ::= | 4861 * typeAlias ::= |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4889 * typeList ::= | 4913 * typeList ::= |
| 4890 * type (',' type)* | 4914 * type (',' type)* |
| 4891 */ | 4915 */ |
| 4892 TypeArgumentList parseTypeArgumentList() { | 4916 TypeArgumentList parseTypeArgumentList() { |
| 4893 Token leftBracket = getAndAdvance(); | 4917 Token leftBracket = getAndAdvance(); |
| 4894 List<TypeName> arguments = <TypeName>[parseTypeName(false)]; | 4918 List<TypeName> arguments = <TypeName>[parseTypeName(false)]; |
| 4895 while (_optional(TokenType.COMMA)) { | 4919 while (_optional(TokenType.COMMA)) { |
| 4896 arguments.add(parseTypeName(false)); | 4920 arguments.add(parseTypeName(false)); |
| 4897 } | 4921 } |
| 4898 Token rightBracket = _expectGt(); | 4922 Token rightBracket = _expectGt(); |
| 4899 return new TypeArgumentList(leftBracket, arguments, rightBracket); | 4923 return astFactory.typeArgumentList(leftBracket, arguments, rightBracket); |
| 4900 } | 4924 } |
| 4901 | 4925 |
| 4902 /** | 4926 /** |
| 4903 * Parse a type name. Return the type name that was parsed. | 4927 * Parse a type name. Return the type name that was parsed. |
| 4904 * | 4928 * |
| 4905 * type ::= | 4929 * type ::= |
| 4906 * qualified typeArguments? | 4930 * qualified typeArguments? |
| 4907 */ | 4931 */ |
| 4908 TypeName parseTypeName(bool inExpression) { | 4932 TypeName parseTypeName(bool inExpression) { |
| 4909 TypeName realType = _parseTypeName(inExpression); | 4933 TypeName realType = _parseTypeName(inExpression); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 4924 TypeParameter parseTypeParameter() { | 4948 TypeParameter parseTypeParameter() { |
| 4925 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); | 4949 CommentAndMetadata commentAndMetadata = parseCommentAndMetadata(); |
| 4926 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 4950 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 4927 if (_matches(TokenType.QUESTION)) { | 4951 if (_matches(TokenType.QUESTION)) { |
| 4928 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); | 4952 _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER); |
| 4929 _advance(); | 4953 _advance(); |
| 4930 } | 4954 } |
| 4931 if (_matchesKeyword(Keyword.EXTENDS)) { | 4955 if (_matchesKeyword(Keyword.EXTENDS)) { |
| 4932 Token keyword = getAndAdvance(); | 4956 Token keyword = getAndAdvance(); |
| 4933 TypeName bound = parseTypeName(false); | 4957 TypeName bound = parseTypeName(false); |
| 4934 return new TypeParameter(commentAndMetadata.comment, | 4958 return astFactory.typeParameter(commentAndMetadata.comment, |
| 4935 commentAndMetadata.metadata, name, keyword, bound); | 4959 commentAndMetadata.metadata, name, keyword, bound); |
| 4936 } | 4960 } |
| 4937 return new TypeParameter(commentAndMetadata.comment, | 4961 return astFactory.typeParameter(commentAndMetadata.comment, |
| 4938 commentAndMetadata.metadata, name, null, null); | 4962 commentAndMetadata.metadata, name, null, null); |
| 4939 } | 4963 } |
| 4940 | 4964 |
| 4941 /** | 4965 /** |
| 4942 * Parse a list of type parameters. Return the list of type parameters that | 4966 * Parse a list of type parameters. Return the list of type parameters that |
| 4943 * were parsed. | 4967 * were parsed. |
| 4944 * | 4968 * |
| 4945 * This method assumes that the current token matches `TokenType.LT`. | 4969 * This method assumes that the current token matches `TokenType.LT`. |
| 4946 * | 4970 * |
| 4947 * typeParameterList ::= | 4971 * typeParameterList ::= |
| 4948 * '<' typeParameter (',' typeParameter)* '>' | 4972 * '<' typeParameter (',' typeParameter)* '>' |
| 4949 */ | 4973 */ |
| 4950 TypeParameterList parseTypeParameterList() { | 4974 TypeParameterList parseTypeParameterList() { |
| 4951 Token leftBracket = getAndAdvance(); | 4975 Token leftBracket = getAndAdvance(); |
| 4952 List<TypeParameter> typeParameters = <TypeParameter>[parseTypeParameter()]; | 4976 List<TypeParameter> typeParameters = <TypeParameter>[parseTypeParameter()]; |
| 4953 while (_optional(TokenType.COMMA)) { | 4977 while (_optional(TokenType.COMMA)) { |
| 4954 typeParameters.add(parseTypeParameter()); | 4978 typeParameters.add(parseTypeParameter()); |
| 4955 } | 4979 } |
| 4956 Token rightBracket = _expectGt(); | 4980 Token rightBracket = _expectGt(); |
| 4957 return new TypeParameterList(leftBracket, typeParameters, rightBracket); | 4981 return astFactory.typeParameterList( |
| 4982 leftBracket, typeParameters, rightBracket); | |
| 4958 } | 4983 } |
| 4959 | 4984 |
| 4960 /** | 4985 /** |
| 4961 * Parse a unary expression. Return the unary expression that was parsed. | 4986 * Parse a unary expression. Return the unary expression that was parsed. |
| 4962 * | 4987 * |
| 4963 * unaryExpression ::= | 4988 * unaryExpression ::= |
| 4964 * prefixOperator unaryExpression | 4989 * prefixOperator unaryExpression |
| 4965 * | awaitExpression | 4990 * | awaitExpression |
| 4966 * | postfixExpression | 4991 * | postfixExpression |
| 4967 * | unaryOperator 'super' | 4992 * | unaryOperator 'super' |
| 4968 * | '-' 'super' | 4993 * | '-' 'super' |
| 4969 * | incrementOperator assignableExpression | 4994 * | incrementOperator assignableExpression |
| 4970 */ | 4995 */ |
| 4971 Expression parseUnaryExpression() { | 4996 Expression parseUnaryExpression() { |
| 4972 TokenType type = _currentToken.type; | 4997 TokenType type = _currentToken.type; |
| 4973 if (type == TokenType.MINUS || | 4998 if (type == TokenType.MINUS || |
| 4974 type == TokenType.BANG || | 4999 type == TokenType.BANG || |
| 4975 type == TokenType.TILDE) { | 5000 type == TokenType.TILDE) { |
| 4976 Token operator = getAndAdvance(); | 5001 Token operator = getAndAdvance(); |
| 4977 if (_matchesKeyword(Keyword.SUPER)) { | 5002 if (_matchesKeyword(Keyword.SUPER)) { |
| 4978 TokenType nextType = _peek().type; | 5003 TokenType nextType = _peek().type; |
| 4979 if (nextType == TokenType.OPEN_SQUARE_BRACKET || | 5004 if (nextType == TokenType.OPEN_SQUARE_BRACKET || |
| 4980 nextType == TokenType.PERIOD) { | 5005 nextType == TokenType.PERIOD) { |
| 4981 // "prefixOperator unaryExpression" | 5006 // "prefixOperator unaryExpression" |
| 4982 // --> "prefixOperator postfixExpression" | 5007 // --> "prefixOperator postfixExpression" |
| 4983 // --> "prefixOperator primary selector*" | 5008 // --> "prefixOperator primary selector*" |
| 4984 // --> "prefixOperator 'super' assignableSelector selector*" | 5009 // --> "prefixOperator 'super' assignableSelector selector*" |
| 4985 return new PrefixExpression(operator, parseUnaryExpression()); | 5010 return astFactory.prefixExpression(operator, parseUnaryExpression()); |
| 4986 } | 5011 } |
| 4987 return new PrefixExpression( | 5012 return astFactory.prefixExpression( |
| 4988 operator, new SuperExpression(getAndAdvance())); | 5013 operator, astFactory.superExpression(getAndAdvance())); |
| 4989 } | 5014 } |
| 4990 return new PrefixExpression(operator, parseUnaryExpression()); | 5015 return astFactory.prefixExpression(operator, parseUnaryExpression()); |
| 4991 } else if (_currentToken.type.isIncrementOperator) { | 5016 } else if (_currentToken.type.isIncrementOperator) { |
| 4992 Token operator = getAndAdvance(); | 5017 Token operator = getAndAdvance(); |
| 4993 if (_matchesKeyword(Keyword.SUPER)) { | 5018 if (_matchesKeyword(Keyword.SUPER)) { |
| 4994 TokenType nextType = _peek().type; | 5019 TokenType nextType = _peek().type; |
| 4995 if (nextType == TokenType.OPEN_SQUARE_BRACKET || | 5020 if (nextType == TokenType.OPEN_SQUARE_BRACKET || |
| 4996 nextType == TokenType.PERIOD) { | 5021 nextType == TokenType.PERIOD) { |
| 4997 // --> "prefixOperator 'super' assignableSelector selector*" | 5022 // --> "prefixOperator 'super' assignableSelector selector*" |
| 4998 return new PrefixExpression(operator, parseUnaryExpression()); | 5023 return astFactory.prefixExpression(operator, parseUnaryExpression()); |
| 4999 } | 5024 } |
| 5000 // | 5025 // |
| 5001 // Even though it is not valid to use an incrementing operator | 5026 // Even though it is not valid to use an incrementing operator |
| 5002 // ('++' or '--') before 'super', we can (and therefore must) interpret | 5027 // ('++' or '--') before 'super', we can (and therefore must) interpret |
| 5003 // "--super" as semantically equivalent to "-(-super)". Unfortunately, | 5028 // "--super" as semantically equivalent to "-(-super)". Unfortunately, |
| 5004 // we cannot do the same for "++super" because "+super" is also not | 5029 // we cannot do the same for "++super" because "+super" is also not |
| 5005 // valid. | 5030 // valid. |
| 5006 // | 5031 // |
| 5007 if (type == TokenType.MINUS_MINUS) { | 5032 if (type == TokenType.MINUS_MINUS) { |
| 5008 Token firstOperator = _createToken(operator, TokenType.MINUS); | 5033 Token firstOperator = _createToken(operator, TokenType.MINUS); |
| 5009 Token secondOperator = | 5034 Token secondOperator = |
| 5010 new Token(TokenType.MINUS, operator.offset + 1); | 5035 new Token(TokenType.MINUS, operator.offset + 1); |
| 5011 secondOperator.setNext(_currentToken); | 5036 secondOperator.setNext(_currentToken); |
| 5012 firstOperator.setNext(secondOperator); | 5037 firstOperator.setNext(secondOperator); |
| 5013 operator.previous.setNext(firstOperator); | 5038 operator.previous.setNext(firstOperator); |
| 5014 return new PrefixExpression( | 5039 return astFactory.prefixExpression( |
| 5015 firstOperator, | 5040 firstOperator, |
| 5016 new PrefixExpression( | 5041 astFactory.prefixExpression( |
| 5017 secondOperator, new SuperExpression(getAndAdvance()))); | 5042 secondOperator, astFactory.superExpression(getAndAdvance()))); |
| 5018 } | 5043 } |
| 5019 // Invalid operator before 'super' | 5044 // Invalid operator before 'super' |
| 5020 _reportErrorForCurrentToken( | 5045 _reportErrorForCurrentToken( |
| 5021 ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]); | 5046 ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]); |
| 5022 return new PrefixExpression( | 5047 return astFactory.prefixExpression( |
| 5023 operator, new SuperExpression(getAndAdvance())); | 5048 operator, astFactory.superExpression(getAndAdvance())); |
| 5024 } | 5049 } |
| 5025 return new PrefixExpression( | 5050 return astFactory.prefixExpression( |
| 5026 operator, _parseAssignableExpressionNotStartingWithSuper(false)); | 5051 operator, _parseAssignableExpressionNotStartingWithSuper(false)); |
| 5027 } else if (type == TokenType.PLUS) { | 5052 } else if (type == TokenType.PLUS) { |
| 5028 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); | 5053 _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER); |
| 5029 return createSyntheticIdentifier(); | 5054 return createSyntheticIdentifier(); |
| 5030 } else if (_inAsync && _matchesString(_AWAIT)) { | 5055 } else if (_inAsync && _matchesString(_AWAIT)) { |
| 5031 return parseAwaitExpression(); | 5056 return parseAwaitExpression(); |
| 5032 } | 5057 } |
| 5033 return parsePostfixExpression(); | 5058 return parsePostfixExpression(); |
| 5034 } | 5059 } |
| 5035 | 5060 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 5050 // of a construct like "class C { int @deprecated foo() {} }" (i.e. the | 5075 // of a construct like "class C { int @deprecated foo() {} }" (i.e. the |
| 5051 // user is in the middle of inserting "int bar;" prior to | 5076 // user is in the middle of inserting "int bar;" prior to |
| 5052 // "@deprecated foo() {}"). | 5077 // "@deprecated foo() {}"). |
| 5053 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 5078 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 5054 Token equals = null; | 5079 Token equals = null; |
| 5055 Expression initializer = null; | 5080 Expression initializer = null; |
| 5056 if (_matches(TokenType.EQ)) { | 5081 if (_matches(TokenType.EQ)) { |
| 5057 equals = getAndAdvance(); | 5082 equals = getAndAdvance(); |
| 5058 initializer = parseExpression2(); | 5083 initializer = parseExpression2(); |
| 5059 } | 5084 } |
| 5060 return new VariableDeclaration(name, equals, initializer); | 5085 return astFactory.variableDeclaration(name, equals, initializer); |
| 5061 } | 5086 } |
| 5062 | 5087 |
| 5063 /** | 5088 /** |
| 5064 * Parse a variable declaration list. The [commentAndMetadata] is the metadata | 5089 * Parse a variable declaration list. The [commentAndMetadata] is the metadata |
| 5065 * to be associated with the variable declaration list. Return the variable | 5090 * to be associated with the variable declaration list. Return the variable |
| 5066 * declaration list that was parsed. | 5091 * declaration list that was parsed. |
| 5067 * | 5092 * |
| 5068 * variableDeclarationList ::= | 5093 * variableDeclarationList ::= |
| 5069 * finalConstVarOrType variableDeclaration (',' variableDeclaration)* | 5094 * finalConstVarOrType variableDeclaration (',' variableDeclaration)* |
| 5070 */ | 5095 */ |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 5092 keyword != null && | 5117 keyword != null && |
| 5093 _tokenMatchesKeyword(keyword, Keyword.VAR)) { | 5118 _tokenMatchesKeyword(keyword, Keyword.VAR)) { |
| 5094 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, keyword); | 5119 _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, keyword); |
| 5095 } | 5120 } |
| 5096 List<VariableDeclaration> variables = <VariableDeclaration>[ | 5121 List<VariableDeclaration> variables = <VariableDeclaration>[ |
| 5097 parseVariableDeclaration() | 5122 parseVariableDeclaration() |
| 5098 ]; | 5123 ]; |
| 5099 while (_optional(TokenType.COMMA)) { | 5124 while (_optional(TokenType.COMMA)) { |
| 5100 variables.add(parseVariableDeclaration()); | 5125 variables.add(parseVariableDeclaration()); |
| 5101 } | 5126 } |
| 5102 return new VariableDeclarationList(commentAndMetadata?.comment, | 5127 return astFactory.variableDeclarationList(commentAndMetadata?.comment, |
| 5103 commentAndMetadata?.metadata, keyword, type, variables); | 5128 commentAndMetadata?.metadata, keyword, type, variables); |
| 5104 } | 5129 } |
| 5105 | 5130 |
| 5106 /** | 5131 /** |
| 5107 * Parse a variable declaration statement. The [commentAndMetadata] is the | 5132 * Parse a variable declaration statement. The [commentAndMetadata] is the |
| 5108 * metadata to be associated with the variable declaration statement, or | 5133 * metadata to be associated with the variable declaration statement, or |
| 5109 * `null` if there is no attempt at parsing the comment and metadata. Return | 5134 * `null` if there is no attempt at parsing the comment and metadata. Return |
| 5110 * the variable declaration statement that was parsed. | 5135 * the variable declaration statement that was parsed. |
| 5111 * | 5136 * |
| 5112 * variableDeclarationStatement ::= | 5137 * variableDeclarationStatement ::= |
| 5113 * variableDeclarationList ';' | 5138 * variableDeclarationList ';' |
| 5114 */ | 5139 */ |
| 5115 VariableDeclarationStatement parseVariableDeclarationStatementAfterMetadata( | 5140 VariableDeclarationStatement parseVariableDeclarationStatementAfterMetadata( |
| 5116 CommentAndMetadata commentAndMetadata) { | 5141 CommentAndMetadata commentAndMetadata) { |
| 5117 // Token startToken = currentToken; | 5142 // Token startToken = currentToken; |
| 5118 VariableDeclarationList variableList = | 5143 VariableDeclarationList variableList = |
| 5119 parseVariableDeclarationListAfterMetadata(commentAndMetadata); | 5144 parseVariableDeclarationListAfterMetadata(commentAndMetadata); |
| 5120 // if (!matches(TokenType.SEMICOLON)) { | 5145 // if (!matches(TokenType.SEMICOLON)) { |
| 5121 // if (matches(startToken, Keyword.VAR) && isTypedIdentifier(startToken .getNext())) { | 5146 // if (matches(startToken, Keyword.VAR) && isTypedIdentifier(startToken .getNext())) { |
| 5122 // // TODO(brianwilkerson) This appears to be of the form "var type v ariable". We should do | 5147 // // TODO(brianwilkerson) This appears to be of the form "var type v ariable". We should do |
| 5123 // // a better job of recovering in this case. | 5148 // // a better job of recovering in this case. |
| 5124 // } | 5149 // } |
| 5125 // } | 5150 // } |
| 5126 Token semicolon = _expect(TokenType.SEMICOLON); | 5151 Token semicolon = _expect(TokenType.SEMICOLON); |
| 5127 return new VariableDeclarationStatement(variableList, semicolon); | 5152 return astFactory.variableDeclarationStatement(variableList, semicolon); |
| 5128 } | 5153 } |
| 5129 | 5154 |
| 5130 /** | 5155 /** |
| 5131 * Parse a while statement. Return the while statement that was parsed. | 5156 * Parse a while statement. Return the while statement that was parsed. |
| 5132 * | 5157 * |
| 5133 * This method assumes that the current token matches [Keyword.WHILE]. | 5158 * This method assumes that the current token matches [Keyword.WHILE]. |
| 5134 * | 5159 * |
| 5135 * whileStatement ::= | 5160 * whileStatement ::= |
| 5136 * 'while' '(' expression ')' statement | 5161 * 'while' '(' expression ')' statement |
| 5137 */ | 5162 */ |
| 5138 Statement parseWhileStatement() { | 5163 Statement parseWhileStatement() { |
| 5139 bool wasInLoop = _inLoop; | 5164 bool wasInLoop = _inLoop; |
| 5140 _inLoop = true; | 5165 _inLoop = true; |
| 5141 try { | 5166 try { |
| 5142 Token keyword = getAndAdvance(); | 5167 Token keyword = getAndAdvance(); |
| 5143 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); | 5168 Token leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| 5144 Expression condition = parseExpression2(); | 5169 Expression condition = parseExpression2(); |
| 5145 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); | 5170 Token rightParenthesis = _expect(TokenType.CLOSE_PAREN); |
| 5146 Statement body = parseStatement2(); | 5171 Statement body = parseStatement2(); |
| 5147 return new WhileStatement( | 5172 return astFactory.whileStatement( |
| 5148 keyword, leftParenthesis, condition, rightParenthesis, body); | 5173 keyword, leftParenthesis, condition, rightParenthesis, body); |
| 5149 } finally { | 5174 } finally { |
| 5150 _inLoop = wasInLoop; | 5175 _inLoop = wasInLoop; |
| 5151 } | 5176 } |
| 5152 } | 5177 } |
| 5153 | 5178 |
| 5154 /** | 5179 /** |
| 5155 * Parse a with clause. Return the with clause that was parsed. | 5180 * Parse a with clause. Return the with clause that was parsed. |
| 5156 * | 5181 * |
| 5157 * This method assumes that the current token matches `Keyword.WITH`. | 5182 * This method assumes that the current token matches `Keyword.WITH`. |
| 5158 * | 5183 * |
| 5159 * withClause ::= | 5184 * withClause ::= |
| 5160 * 'with' typeName (',' typeName)* | 5185 * 'with' typeName (',' typeName)* |
| 5161 */ | 5186 */ |
| 5162 WithClause parseWithClause() { | 5187 WithClause parseWithClause() { |
| 5163 Token withKeyword = getAndAdvance(); | 5188 Token withKeyword = getAndAdvance(); |
| 5164 List<TypeName> types = <TypeName>[]; | 5189 List<TypeName> types = <TypeName>[]; |
| 5165 do { | 5190 do { |
| 5166 TypeName typeName = parseTypeName(false); | 5191 TypeName typeName = parseTypeName(false); |
| 5167 _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_WITH); | 5192 _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_WITH); |
| 5168 types.add(typeName); | 5193 types.add(typeName); |
| 5169 } while (_optional(TokenType.COMMA)); | 5194 } while (_optional(TokenType.COMMA)); |
| 5170 return new WithClause(withKeyword, types); | 5195 return astFactory.withClause(withKeyword, types); |
| 5171 } | 5196 } |
| 5172 | 5197 |
| 5173 /** | 5198 /** |
| 5174 * Parse a yield statement. Return the yield statement that was parsed. | 5199 * Parse a yield statement. Return the yield statement that was parsed. |
| 5175 * | 5200 * |
| 5176 * This method assumes that the current token matches [Keyword.YIELD]. | 5201 * This method assumes that the current token matches [Keyword.YIELD]. |
| 5177 * | 5202 * |
| 5178 * yieldStatement ::= | 5203 * yieldStatement ::= |
| 5179 * 'yield' '*'? expression ';' | 5204 * 'yield' '*'? expression ';' |
| 5180 */ | 5205 */ |
| 5181 YieldStatement parseYieldStatement() { | 5206 YieldStatement parseYieldStatement() { |
| 5182 Token yieldToken = getAndAdvance(); | 5207 Token yieldToken = getAndAdvance(); |
| 5183 Token star = null; | 5208 Token star = null; |
| 5184 if (_matches(TokenType.STAR)) { | 5209 if (_matches(TokenType.STAR)) { |
| 5185 star = getAndAdvance(); | 5210 star = getAndAdvance(); |
| 5186 } | 5211 } |
| 5187 Expression expression = parseExpression2(); | 5212 Expression expression = parseExpression2(); |
| 5188 Token semicolon = _expect(TokenType.SEMICOLON); | 5213 Token semicolon = _expect(TokenType.SEMICOLON); |
| 5189 return new YieldStatement(yieldToken, star, expression, semicolon); | 5214 return astFactory.yieldStatement(yieldToken, star, expression, semicolon); |
| 5190 } | 5215 } |
| 5191 | 5216 |
| 5192 /** | 5217 /** |
| 5193 * Parse a prefixed identifier, starting at the [startToken], without actually | 5218 * Parse a prefixed identifier, starting at the [startToken], without actually |
| 5194 * creating a prefixed identifier or changing the current token. Return the | 5219 * creating a prefixed identifier or changing the current token. Return the |
| 5195 * token following the prefixed identifier that was parsed, or `null` if the | 5220 * token following the prefixed identifier that was parsed, or `null` if the |
| 5196 * given token is not the first token in a valid prefixed identifier. | 5221 * given token is not the first token in a valid prefixed identifier. |
| 5197 * | 5222 * |
| 5198 * This method must be kept in sync with [parsePrefixedIdentifier]. | 5223 * This method must be kept in sync with [parsePrefixedIdentifier]. |
| 5199 * | 5224 * |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5409 current.setNext(tail); | 5434 current.setNext(tail); |
| 5410 return head.next; | 5435 return head.next; |
| 5411 } | 5436 } |
| 5412 | 5437 |
| 5413 /** | 5438 /** |
| 5414 * Convert the given [method] declaration into the nearest valid top-level | 5439 * Convert the given [method] declaration into the nearest valid top-level |
| 5415 * function declaration (that is, the function declaration that most closely | 5440 * function declaration (that is, the function declaration that most closely |
| 5416 * captures the components of the given method declaration). | 5441 * captures the components of the given method declaration). |
| 5417 */ | 5442 */ |
| 5418 FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) => | 5443 FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) => |
| 5419 new FunctionDeclaration( | 5444 astFactory.functionDeclaration( |
| 5420 method.documentationComment, | 5445 method.documentationComment, |
| 5421 method.metadata, | 5446 method.metadata, |
| 5422 method.externalKeyword, | 5447 method.externalKeyword, |
| 5423 method.returnType, | 5448 method.returnType, |
| 5424 method.propertyKeyword, | 5449 method.propertyKeyword, |
| 5425 method.name, | 5450 method.name, |
| 5426 new FunctionExpression( | 5451 astFactory.functionExpression( |
| 5427 method.typeParameters, method.parameters, method.body)); | 5452 method.typeParameters, method.parameters, method.body)); |
| 5428 | 5453 |
| 5429 /** | 5454 /** |
| 5430 * Return `true` if the current token could be the start of a compilation unit | 5455 * Return `true` if the current token could be the start of a compilation unit |
| 5431 * member. This method is used for recovery purposes to decide when to stop | 5456 * member. This method is used for recovery purposes to decide when to stop |
| 5432 * skipping tokens after finding an error while parsing a compilation unit | 5457 * skipping tokens after finding an error while parsing a compilation unit |
| 5433 * member. | 5458 * member. |
| 5434 */ | 5459 */ |
| 5435 bool _couldBeStartOfCompilationUnitMember() { | 5460 bool _couldBeStartOfCompilationUnitMember() { |
| 5436 Keyword keyword = _currentToken.keyword; | 5461 Keyword keyword = _currentToken.keyword; |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5977 * when there isn't one. Return the argument list that was parsed. | 6002 * when there isn't one. Return the argument list that was parsed. |
| 5978 */ | 6003 */ |
| 5979 ArgumentList _parseArgumentListChecked() { | 6004 ArgumentList _parseArgumentListChecked() { |
| 5980 if (_matches(TokenType.OPEN_PAREN)) { | 6005 if (_matches(TokenType.OPEN_PAREN)) { |
| 5981 return parseArgumentList(); | 6006 return parseArgumentList(); |
| 5982 } | 6007 } |
| 5983 _reportErrorForCurrentToken( | 6008 _reportErrorForCurrentToken( |
| 5984 ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_PAREN.lexeme]); | 6009 ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_PAREN.lexeme]); |
| 5985 // Recovery: Look to see whether there is a close paren that isn't matched | 6010 // Recovery: Look to see whether there is a close paren that isn't matched |
| 5986 // to an open paren and if so parse the list of arguments as normal. | 6011 // to an open paren and if so parse the list of arguments as normal. |
| 5987 return new ArgumentList(_createSyntheticToken(TokenType.OPEN_PAREN), null, | 6012 return astFactory.argumentList(_createSyntheticToken(TokenType.OPEN_PAREN), |
| 5988 _createSyntheticToken(TokenType.CLOSE_PAREN)); | 6013 null, _createSyntheticToken(TokenType.CLOSE_PAREN)); |
| 5989 } | 6014 } |
| 5990 | 6015 |
| 5991 /** | 6016 /** |
| 5992 * Parse an assert within a constructor's initializer list. Return the assert. | 6017 * Parse an assert within a constructor's initializer list. Return the assert. |
| 5993 * | 6018 * |
| 5994 * This method assumes that the current token matches `Keyword.ASSERT`. | 6019 * This method assumes that the current token matches `Keyword.ASSERT`. |
| 5995 * | 6020 * |
| 5996 * assertInitializer ::= | 6021 * assertInitializer ::= |
| 5997 * 'assert' '(' expression [',' expression] ')' | 6022 * 'assert' '(' expression [',' expression] ')' |
| 5998 */ | 6023 */ |
| 5999 AssertInitializer _parseAssertInitializer() { | 6024 AssertInitializer _parseAssertInitializer() { |
| 6000 Token keyword = getAndAdvance(); | 6025 Token keyword = getAndAdvance(); |
| 6001 Token leftParen = _expect(TokenType.OPEN_PAREN); | 6026 Token leftParen = _expect(TokenType.OPEN_PAREN); |
| 6002 Expression expression = parseExpression2(); | 6027 Expression expression = parseExpression2(); |
| 6003 Token comma; | 6028 Token comma; |
| 6004 Expression message; | 6029 Expression message; |
| 6005 if (_matches(TokenType.COMMA)) { | 6030 if (_matches(TokenType.COMMA)) { |
| 6006 comma = getAndAdvance(); | 6031 comma = getAndAdvance(); |
| 6007 message = parseExpression2(); | 6032 message = parseExpression2(); |
| 6008 } | 6033 } |
| 6009 Token rightParen = _expect(TokenType.CLOSE_PAREN); | 6034 Token rightParen = _expect(TokenType.CLOSE_PAREN); |
| 6010 return new AssertInitializer( | 6035 return astFactory.assertInitializer( |
| 6011 keyword, leftParen, expression, comma, message, rightParen); | 6036 keyword, leftParen, expression, comma, message, rightParen); |
| 6012 } | 6037 } |
| 6013 | 6038 |
| 6014 /** | 6039 /** |
| 6015 * Parse an assignable expression given that the current token is not 'super'. | 6040 * Parse an assignable expression given that the current token is not 'super'. |
| 6016 * The [primaryAllowed] is `true` if the expression is allowed to be a primary | 6041 * The [primaryAllowed] is `true` if the expression is allowed to be a primary |
| 6017 * without any assignable selector. Return the assignable expression that was | 6042 * without any assignable selector. Return the assignable expression that was |
| 6018 * parsed. | 6043 * parsed. |
| 6019 */ | 6044 */ |
| 6020 Expression _parseAssignableExpressionNotStartingWithSuper( | 6045 Expression _parseAssignableExpressionNotStartingWithSuper( |
| 6021 bool primaryAllowed) { | 6046 bool primaryAllowed) { |
| 6022 // | 6047 // |
| 6023 // A primary expression can start with an identifier. We resolve the | 6048 // A primary expression can start with an identifier. We resolve the |
| 6024 // ambiguity by determining whether the primary consists of anything other | 6049 // ambiguity by determining whether the primary consists of anything other |
| 6025 // than an identifier and/or is followed by an assignableSelector. | 6050 // than an identifier and/or is followed by an assignableSelector. |
| 6026 // | 6051 // |
| 6027 Expression expression = parsePrimaryExpression(); | 6052 Expression expression = parsePrimaryExpression(); |
| 6028 bool isOptional = primaryAllowed || expression is SimpleIdentifier; | 6053 bool isOptional = primaryAllowed || expression is SimpleIdentifier; |
| 6029 while (true) { | 6054 while (true) { |
| 6030 while (_isLikelyArgumentList()) { | 6055 while (_isLikelyArgumentList()) { |
| 6031 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 6056 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 6032 ArgumentList argumentList = parseArgumentList(); | 6057 ArgumentList argumentList = parseArgumentList(); |
| 6033 Expression currentExpression = expression; | 6058 Expression currentExpression = expression; |
| 6034 if (currentExpression is SimpleIdentifier) { | 6059 if (currentExpression is SimpleIdentifier) { |
| 6035 expression = new MethodInvocation( | 6060 expression = astFactory.methodInvocation( |
| 6036 null, null, currentExpression, typeArguments, argumentList); | 6061 null, null, currentExpression, typeArguments, argumentList); |
| 6037 } else if (currentExpression is PrefixedIdentifier) { | 6062 } else if (currentExpression is PrefixedIdentifier) { |
| 6038 expression = new MethodInvocation( | 6063 expression = astFactory.methodInvocation( |
| 6039 currentExpression.prefix, | 6064 currentExpression.prefix, |
| 6040 currentExpression.period, | 6065 currentExpression.period, |
| 6041 currentExpression.identifier, | 6066 currentExpression.identifier, |
| 6042 typeArguments, | 6067 typeArguments, |
| 6043 argumentList); | 6068 argumentList); |
| 6044 } else if (currentExpression is PropertyAccess) { | 6069 } else if (currentExpression is PropertyAccess) { |
| 6045 expression = new MethodInvocation( | 6070 expression = astFactory.methodInvocation( |
| 6046 currentExpression.target, | 6071 currentExpression.target, |
| 6047 currentExpression.operator, | 6072 currentExpression.operator, |
| 6048 currentExpression.propertyName, | 6073 currentExpression.propertyName, |
| 6049 typeArguments, | 6074 typeArguments, |
| 6050 argumentList); | 6075 argumentList); |
| 6051 } else { | 6076 } else { |
| 6052 expression = new FunctionExpressionInvocation( | 6077 expression = astFactory.functionExpressionInvocation( |
| 6053 expression, typeArguments, argumentList); | 6078 expression, typeArguments, argumentList); |
| 6054 } | 6079 } |
| 6055 if (!primaryAllowed) { | 6080 if (!primaryAllowed) { |
| 6056 isOptional = false; | 6081 isOptional = false; |
| 6057 } | 6082 } |
| 6058 } | 6083 } |
| 6059 Expression selectorExpression = parseAssignableSelector( | 6084 Expression selectorExpression = parseAssignableSelector( |
| 6060 expression, isOptional || (expression is PrefixedIdentifier)); | 6085 expression, isOptional || (expression is PrefixedIdentifier)); |
| 6061 if (identical(selectorExpression, expression)) { | 6086 if (identical(selectorExpression, expression)) { |
| 6062 if (!isOptional && (expression is PrefixedIdentifier)) { | 6087 if (!isOptional && (expression is PrefixedIdentifier)) { |
| 6063 PrefixedIdentifier identifier = expression as PrefixedIdentifier; | 6088 PrefixedIdentifier identifier = expression as PrefixedIdentifier; |
| 6064 expression = new PropertyAccess( | 6089 expression = astFactory.propertyAccess( |
| 6065 identifier.prefix, identifier.period, identifier.identifier); | 6090 identifier.prefix, identifier.period, identifier.identifier); |
| 6066 } | 6091 } |
| 6067 return expression; | 6092 return expression; |
| 6068 } | 6093 } |
| 6069 expression = selectorExpression; | 6094 expression = selectorExpression; |
| 6070 isOptional = true; | 6095 isOptional = true; |
| 6071 } | 6096 } |
| 6072 } | 6097 } |
| 6073 | 6098 |
| 6074 /** | 6099 /** |
| 6075 * Parse a block when we need to check for an open curly brace and recover | 6100 * Parse a block when we need to check for an open curly brace and recover |
| 6076 * when there isn't one. Return the block that was parsed. | 6101 * when there isn't one. Return the block that was parsed. |
| 6077 * | 6102 * |
| 6078 * block ::= | 6103 * block ::= |
| 6079 * '{' statements '}' | 6104 * '{' statements '}' |
| 6080 */ | 6105 */ |
| 6081 Block _parseBlockChecked() { | 6106 Block _parseBlockChecked() { |
| 6082 if (_matches(TokenType.OPEN_CURLY_BRACKET)) { | 6107 if (_matches(TokenType.OPEN_CURLY_BRACKET)) { |
| 6083 return parseBlock(); | 6108 return parseBlock(); |
| 6084 } | 6109 } |
| 6085 // TODO(brianwilkerson) Improve the error message. | 6110 // TODO(brianwilkerson) Improve the error message. |
| 6086 _reportErrorForCurrentToken( | 6111 _reportErrorForCurrentToken( |
| 6087 ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_CURLY_BRACKET.lexeme]); | 6112 ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_CURLY_BRACKET.lexeme]); |
| 6088 // Recovery: Check for an unmatched closing curly bracket and parse | 6113 // Recovery: Check for an unmatched closing curly bracket and parse |
| 6089 // statements until it is reached. | 6114 // statements until it is reached. |
| 6090 return new Block(_createSyntheticToken(TokenType.OPEN_CURLY_BRACKET), null, | 6115 return astFactory.block(_createSyntheticToken(TokenType.OPEN_CURLY_BRACKET), |
| 6091 _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET)); | 6116 null, _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET)); |
| 6092 } | 6117 } |
| 6093 | 6118 |
| 6094 /** | 6119 /** |
| 6095 * Parse a list of class members. The [className] is the name of the class | 6120 * Parse a list of class members. The [className] is the name of the class |
| 6096 * whose members are being parsed. The [closingBracket] is the closing bracket | 6121 * whose members are being parsed. The [closingBracket] is the closing bracket |
| 6097 * for the class, or `null` if the closing bracket is missing. Return the list | 6122 * for the class, or `null` if the closing bracket is missing. Return the list |
| 6098 * of class members that were parsed. | 6123 * of class members that were parsed. |
| 6099 * | 6124 * |
| 6100 * classMembers ::= | 6125 * classMembers ::= |
| 6101 * (metadata memberDefinition)* | 6126 * (metadata memberDefinition)* |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6173 ParserErrorCode.EXPECTED_TOKEN, [TokenType.SEMICOLON.lexeme]); | 6198 ParserErrorCode.EXPECTED_TOKEN, [TokenType.SEMICOLON.lexeme]); |
| 6174 Token leftBracket = getAndAdvance(); | 6199 Token leftBracket = getAndAdvance(); |
| 6175 _parseClassMembers(className.name, _getEndToken(leftBracket)); | 6200 _parseClassMembers(className.name, _getEndToken(leftBracket)); |
| 6176 _expect(TokenType.CLOSE_CURLY_BRACKET); | 6201 _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 6177 } else { | 6202 } else { |
| 6178 _reportErrorForToken(ParserErrorCode.EXPECTED_TOKEN, | 6203 _reportErrorForToken(ParserErrorCode.EXPECTED_TOKEN, |
| 6179 _currentToken.previous, [TokenType.SEMICOLON.lexeme]); | 6204 _currentToken.previous, [TokenType.SEMICOLON.lexeme]); |
| 6180 } | 6205 } |
| 6181 semicolon = _createSyntheticToken(TokenType.SEMICOLON); | 6206 semicolon = _createSyntheticToken(TokenType.SEMICOLON); |
| 6182 } | 6207 } |
| 6183 return new ClassTypeAlias( | 6208 return astFactory.classTypeAlias( |
| 6184 commentAndMetadata.comment, | 6209 commentAndMetadata.comment, |
| 6185 commentAndMetadata.metadata, | 6210 commentAndMetadata.metadata, |
| 6186 classKeyword, | 6211 classKeyword, |
| 6187 className, | 6212 className, |
| 6188 typeParameters, | 6213 typeParameters, |
| 6189 equals, | 6214 equals, |
| 6190 abstractKeyword, | 6215 abstractKeyword, |
| 6191 superclass, | 6216 superclass, |
| 6192 withClause, | 6217 withClause, |
| 6193 implementsClause, | 6218 implementsClause, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6251 if (factoryKeyword != null) { | 6276 if (factoryKeyword != null) { |
| 6252 _reportErrorForToken( | 6277 _reportErrorForToken( |
| 6253 ParserErrorCode.FACTORY_WITH_INITIALIZERS, factoryKeyword); | 6278 ParserErrorCode.FACTORY_WITH_INITIALIZERS, factoryKeyword); |
| 6254 } | 6279 } |
| 6255 } | 6280 } |
| 6256 ConstructorName redirectedConstructor = null; | 6281 ConstructorName redirectedConstructor = null; |
| 6257 FunctionBody body; | 6282 FunctionBody body; |
| 6258 if (_matches(TokenType.EQ)) { | 6283 if (_matches(TokenType.EQ)) { |
| 6259 separator = getAndAdvance(); | 6284 separator = getAndAdvance(); |
| 6260 redirectedConstructor = parseConstructorName(); | 6285 redirectedConstructor = parseConstructorName(); |
| 6261 body = new EmptyFunctionBody(_expect(TokenType.SEMICOLON)); | 6286 body = astFactory.emptyFunctionBody(_expect(TokenType.SEMICOLON)); |
| 6262 if (factoryKeyword == null) { | 6287 if (factoryKeyword == null) { |
| 6263 _reportErrorForNode( | 6288 _reportErrorForNode( |
| 6264 ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR, | 6289 ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR, |
| 6265 redirectedConstructor); | 6290 redirectedConstructor); |
| 6266 } | 6291 } |
| 6267 } else { | 6292 } else { |
| 6268 body = | 6293 body = |
| 6269 parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false); | 6294 parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false); |
| 6270 if (constKeyword != null && | 6295 if (constKeyword != null && |
| 6271 factoryKeyword != null && | 6296 factoryKeyword != null && |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 6285 ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body); | 6310 ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body); |
| 6286 } else if (externalKeyword != null) { | 6311 } else if (externalKeyword != null) { |
| 6287 _reportErrorForNode( | 6312 _reportErrorForNode( |
| 6288 ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body); | 6313 ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body); |
| 6289 } else if (!bodyAllowed) { | 6314 } else if (!bodyAllowed) { |
| 6290 _reportErrorForNode( | 6315 _reportErrorForNode( |
| 6291 ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY, body); | 6316 ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY, body); |
| 6292 } | 6317 } |
| 6293 } | 6318 } |
| 6294 } | 6319 } |
| 6295 return new ConstructorDeclaration( | 6320 return astFactory.constructorDeclaration( |
| 6296 commentAndMetadata.comment, | 6321 commentAndMetadata.comment, |
| 6297 commentAndMetadata.metadata, | 6322 commentAndMetadata.metadata, |
| 6298 externalKeyword, | 6323 externalKeyword, |
| 6299 constKeyword, | 6324 constKeyword, |
| 6300 factoryKeyword, | 6325 factoryKeyword, |
| 6301 returnType, | 6326 returnType, |
| 6302 period, | 6327 period, |
| 6303 name, | 6328 name, |
| 6304 parameters, | 6329 parameters, |
| 6305 separator, | 6330 separator, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 6327 SimpleIdentifier name; | 6352 SimpleIdentifier name; |
| 6328 if (_matchesIdentifier()) { | 6353 if (_matchesIdentifier()) { |
| 6329 name = _parseSimpleIdentifierUnchecked(isDeclaration: true); | 6354 name = _parseSimpleIdentifierUnchecked(isDeclaration: true); |
| 6330 } else { | 6355 } else { |
| 6331 name = createSyntheticIdentifier(); | 6356 name = createSyntheticIdentifier(); |
| 6332 } | 6357 } |
| 6333 if (commentAndMetadata.hasMetadata) { | 6358 if (commentAndMetadata.hasMetadata) { |
| 6334 _reportErrorForNode(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, | 6359 _reportErrorForNode(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT, |
| 6335 commentAndMetadata.metadata[0]); | 6360 commentAndMetadata.metadata[0]); |
| 6336 } | 6361 } |
| 6337 return new EnumConstantDeclaration( | 6362 return astFactory.enumConstantDeclaration( |
| 6338 commentAndMetadata.comment, commentAndMetadata.metadata, name); | 6363 commentAndMetadata.comment, commentAndMetadata.metadata, name); |
| 6339 } | 6364 } |
| 6340 | 6365 |
| 6341 /** | 6366 /** |
| 6342 * Parse a list of formal parameters given that the list starts with the given | 6367 * Parse a list of formal parameters given that the list starts with the given |
| 6343 * [leftParenthesis]. Return the formal parameters that were parsed. | 6368 * [leftParenthesis]. Return the formal parameters that were parsed. |
| 6344 */ | 6369 */ |
| 6345 FormalParameterList _parseFormalParameterListAfterParen( | 6370 FormalParameterList _parseFormalParameterListAfterParen( |
| 6346 Token leftParenthesis) { | 6371 Token leftParenthesis) { |
| 6347 if (_matches(TokenType.CLOSE_PAREN)) { | 6372 if (_matches(TokenType.CLOSE_PAREN)) { |
| 6348 return new FormalParameterList( | 6373 return astFactory.formalParameterList( |
| 6349 leftParenthesis, null, null, null, getAndAdvance()); | 6374 leftParenthesis, null, null, null, getAndAdvance()); |
| 6350 } | 6375 } |
| 6351 // | 6376 // |
| 6352 // Even though it is invalid to have default parameters outside of brackets, | 6377 // Even though it is invalid to have default parameters outside of brackets, |
| 6353 // required parameters inside of brackets, or multiple groups of default and | 6378 // required parameters inside of brackets, or multiple groups of default and |
| 6354 // named parameters, we allow all of these cases so that we can recover | 6379 // named parameters, we allow all of these cases so that we can recover |
| 6355 // better. | 6380 // better. |
| 6356 // | 6381 // |
| 6357 List<FormalParameter> parameters = <FormalParameter>[]; | 6382 List<FormalParameter> parameters = <FormalParameter>[]; |
| 6358 Token leftSquareBracket = null; | 6383 Token leftSquareBracket = null; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6488 } | 6513 } |
| 6489 if (leftCurlyBracket != null && rightCurlyBracket == null) { | 6514 if (leftCurlyBracket != null && rightCurlyBracket == null) { |
| 6490 _reportErrorForCurrentToken( | 6515 _reportErrorForCurrentToken( |
| 6491 ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]); | 6516 ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]); |
| 6492 } | 6517 } |
| 6493 // | 6518 // |
| 6494 // Build the parameter list. | 6519 // Build the parameter list. |
| 6495 // | 6520 // |
| 6496 leftSquareBracket ??= leftCurlyBracket; | 6521 leftSquareBracket ??= leftCurlyBracket; |
| 6497 rightSquareBracket ??= rightCurlyBracket; | 6522 rightSquareBracket ??= rightCurlyBracket; |
| 6498 return new FormalParameterList(leftParenthesis, parameters, | 6523 return astFactory.formalParameterList(leftParenthesis, parameters, |
| 6499 leftSquareBracket, rightSquareBracket, rightParenthesis); | 6524 leftSquareBracket, rightSquareBracket, rightParenthesis); |
| 6500 } | 6525 } |
| 6501 | 6526 |
| 6502 /** | 6527 /** |
| 6503 * Parse a list of formal parameters. Return the formal parameters that were | 6528 * Parse a list of formal parameters. Return the formal parameters that were |
| 6504 * parsed. | 6529 * parsed. |
| 6505 * | 6530 * |
| 6506 * This method assumes that the current token matches `TokenType.OPEN_PAREN`. | 6531 * This method assumes that the current token matches `TokenType.OPEN_PAREN`. |
| 6507 */ | 6532 */ |
| 6508 FormalParameterList _parseFormalParameterListUnchecked() { | 6533 FormalParameterList _parseFormalParameterListUnchecked() { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 6525 Token propertyKeyword = declaration.propertyKeyword; | 6550 Token propertyKeyword = declaration.propertyKeyword; |
| 6526 if (propertyKeyword != null) { | 6551 if (propertyKeyword != null) { |
| 6527 if (propertyKeyword.keyword == Keyword.GET) { | 6552 if (propertyKeyword.keyword == Keyword.GET) { |
| 6528 _reportErrorForToken( | 6553 _reportErrorForToken( |
| 6529 ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword); | 6554 ParserErrorCode.GETTER_IN_FUNCTION, propertyKeyword); |
| 6530 } else { | 6555 } else { |
| 6531 _reportErrorForToken( | 6556 _reportErrorForToken( |
| 6532 ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword); | 6557 ParserErrorCode.SETTER_IN_FUNCTION, propertyKeyword); |
| 6533 } | 6558 } |
| 6534 } | 6559 } |
| 6535 return new FunctionDeclarationStatement(declaration); | 6560 return astFactory.functionDeclarationStatement(declaration); |
| 6536 } | 6561 } |
| 6537 | 6562 |
| 6538 /** | 6563 /** |
| 6539 * Parse a function type alias. The [commentAndMetadata] is the metadata to be | 6564 * Parse a function type alias. The [commentAndMetadata] is the metadata to be |
| 6540 * associated with the member. The [keyword] is the token representing the | 6565 * associated with the member. The [keyword] is the token representing the |
| 6541 * 'typedef' keyword. Return the function type alias that was parsed. | 6566 * 'typedef' keyword. Return the function type alias that was parsed. |
| 6542 * | 6567 * |
| 6543 * functionTypeAlias ::= | 6568 * functionTypeAlias ::= |
| 6544 * functionPrefix typeParameterList? formalParameterList ';' | 6569 * functionPrefix typeParameterList? formalParameterList ';' |
| 6545 * | 6570 * |
| 6546 * functionPrefix ::= | 6571 * functionPrefix ::= |
| 6547 * returnType? name | 6572 * returnType? name |
| 6548 */ | 6573 */ |
| 6549 FunctionTypeAlias _parseFunctionTypeAlias( | 6574 FunctionTypeAlias _parseFunctionTypeAlias( |
| 6550 CommentAndMetadata commentAndMetadata, Token keyword) { | 6575 CommentAndMetadata commentAndMetadata, Token keyword) { |
| 6551 TypeName returnType = null; | 6576 TypeName returnType = null; |
| 6552 if (hasReturnTypeInTypeAlias) { | 6577 if (hasReturnTypeInTypeAlias) { |
| 6553 returnType = parseReturnType(); | 6578 returnType = parseReturnType(); |
| 6554 } | 6579 } |
| 6555 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 6580 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
| 6556 TypeParameterList typeParameters = null; | 6581 TypeParameterList typeParameters = null; |
| 6557 if (_matches(TokenType.LT)) { | 6582 if (_matches(TokenType.LT)) { |
| 6558 typeParameters = parseTypeParameterList(); | 6583 typeParameters = parseTypeParameterList(); |
| 6559 } | 6584 } |
| 6560 TokenType type = _currentToken.type; | 6585 TokenType type = _currentToken.type; |
| 6561 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { | 6586 if (type == TokenType.SEMICOLON || type == TokenType.EOF) { |
| 6562 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); | 6587 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); |
| 6563 FormalParameterList parameters = new FormalParameterList( | 6588 FormalParameterList parameters = astFactory.formalParameterList( |
| 6564 _createSyntheticToken(TokenType.OPEN_PAREN), | 6589 _createSyntheticToken(TokenType.OPEN_PAREN), |
| 6565 null, | 6590 null, |
| 6566 null, | 6591 null, |
| 6567 null, | 6592 null, |
| 6568 _createSyntheticToken(TokenType.CLOSE_PAREN)); | 6593 _createSyntheticToken(TokenType.CLOSE_PAREN)); |
| 6569 Token semicolon = _expect(TokenType.SEMICOLON); | 6594 Token semicolon = _expect(TokenType.SEMICOLON); |
| 6570 return new FunctionTypeAlias( | 6595 return astFactory.functionTypeAlias( |
| 6571 commentAndMetadata.comment, | 6596 commentAndMetadata.comment, |
| 6572 commentAndMetadata.metadata, | 6597 commentAndMetadata.metadata, |
| 6573 keyword, | 6598 keyword, |
| 6574 returnType, | 6599 returnType, |
| 6575 name, | 6600 name, |
| 6576 typeParameters, | 6601 typeParameters, |
| 6577 parameters, | 6602 parameters, |
| 6578 semicolon); | 6603 semicolon); |
| 6579 } else if (type == TokenType.OPEN_PAREN) { | 6604 } else if (type == TokenType.OPEN_PAREN) { |
| 6580 FormalParameterList parameters = _parseFormalParameterListUnchecked(); | 6605 FormalParameterList parameters = _parseFormalParameterListUnchecked(); |
| 6581 _validateFormalParameterList(parameters); | 6606 _validateFormalParameterList(parameters); |
| 6582 Token semicolon = _expect(TokenType.SEMICOLON); | 6607 Token semicolon = _expect(TokenType.SEMICOLON); |
| 6583 return new FunctionTypeAlias( | 6608 return astFactory.functionTypeAlias( |
| 6584 commentAndMetadata.comment, | 6609 commentAndMetadata.comment, |
| 6585 commentAndMetadata.metadata, | 6610 commentAndMetadata.metadata, |
| 6586 keyword, | 6611 keyword, |
| 6587 returnType, | 6612 returnType, |
| 6588 name, | 6613 name, |
| 6589 typeParameters, | 6614 typeParameters, |
| 6590 parameters, | 6615 parameters, |
| 6591 semicolon); | 6616 semicolon); |
| 6592 } else { | 6617 } else { |
| 6593 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); | 6618 _reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS); |
| 6594 // Recovery: At the very least we should skip to the start of the next | 6619 // Recovery: At the very least we should skip to the start of the next |
| 6595 // valid compilation unit member, allowing for the possibility of finding | 6620 // valid compilation unit member, allowing for the possibility of finding |
| 6596 // the typedef parameters before that point. | 6621 // the typedef parameters before that point. |
| 6597 return new FunctionTypeAlias( | 6622 return astFactory.functionTypeAlias( |
| 6598 commentAndMetadata.comment, | 6623 commentAndMetadata.comment, |
| 6599 commentAndMetadata.metadata, | 6624 commentAndMetadata.metadata, |
| 6600 keyword, | 6625 keyword, |
| 6601 returnType, | 6626 returnType, |
| 6602 name, | 6627 name, |
| 6603 typeParameters, | 6628 typeParameters, |
| 6604 new FormalParameterList(_createSyntheticToken(TokenType.OPEN_PAREN), | 6629 astFactory.formalParameterList( |
| 6605 null, null, null, _createSyntheticToken(TokenType.CLOSE_PAREN)), | 6630 _createSyntheticToken(TokenType.OPEN_PAREN), |
| 6631 null, | |
| 6632 null, | |
| 6633 null, | |
| 6634 _createSyntheticToken(TokenType.CLOSE_PAREN)), | |
| 6606 _createSyntheticToken(TokenType.SEMICOLON)); | 6635 _createSyntheticToken(TokenType.SEMICOLON)); |
| 6607 } | 6636 } |
| 6608 } | 6637 } |
| 6609 | 6638 |
| 6610 /** | 6639 /** |
| 6611 * Parses generic type parameters from a comment. | 6640 * Parses generic type parameters from a comment. |
| 6612 * | 6641 * |
| 6613 * Normally this is handled by [_parseGenericMethodTypeParameters], but if the | 6642 * Normally this is handled by [_parseGenericMethodTypeParameters], but if the |
| 6614 * code already handles the normal generic type parameters, the comment | 6643 * code already handles the normal generic type parameters, the comment |
| 6615 * matcher can be called directly. For example, we may have already tried | 6644 * matcher can be called directly. For example, we may have already tried |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6651 if (_matchesIdentifier()) { | 6680 if (_matchesIdentifier()) { |
| 6652 return parseLibraryIdentifier(); | 6681 return parseLibraryIdentifier(); |
| 6653 } else if (_matches(TokenType.STRING)) { | 6682 } else if (_matches(TokenType.STRING)) { |
| 6654 // Recovery: This should be extended to handle arbitrary tokens until we | 6683 // Recovery: This should be extended to handle arbitrary tokens until we |
| 6655 // can find a token that can start a compilation unit member. | 6684 // can find a token that can start a compilation unit member. |
| 6656 StringLiteral string = parseStringLiteral(); | 6685 StringLiteral string = parseStringLiteral(); |
| 6657 _reportErrorForNode(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string); | 6686 _reportErrorForNode(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string); |
| 6658 } else { | 6687 } else { |
| 6659 _reportErrorForToken(missingNameError, missingNameToken); | 6688 _reportErrorForToken(missingNameError, missingNameToken); |
| 6660 } | 6689 } |
| 6661 return new LibraryIdentifier( | 6690 return astFactory |
| 6662 <SimpleIdentifier>[createSyntheticIdentifier()]); | 6691 .libraryIdentifier(<SimpleIdentifier>[createSyntheticIdentifier()]); |
| 6663 } | 6692 } |
| 6664 | 6693 |
| 6665 /** | 6694 /** |
| 6666 * Parse a method declaration. The [commentAndMetadata] is the documentation | 6695 * Parse a method declaration. The [commentAndMetadata] is the documentation |
| 6667 * comment and metadata to be associated with the declaration. The | 6696 * comment and metadata to be associated with the declaration. The |
| 6668 * [externalKeyword] is the 'external' token. The [staticKeyword] is the | 6697 * [externalKeyword] is the 'external' token. The [staticKeyword] is the |
| 6669 * static keyword, or `null` if the getter is not static. The [returnType] is | 6698 * static keyword, or `null` if the getter is not static. The [returnType] is |
| 6670 * the return type of the method. The [name] is the name of the method. The | 6699 * the return type of the method. The [name] is the name of the method. The |
| 6671 * [parameters] is the parameters to the method. Return the method declaration | 6700 * [parameters] is the parameters to the method. Return the method declaration |
| 6672 * that was parsed. | 6701 * that was parsed. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 6689 false); | 6718 false); |
| 6690 if (externalKeyword != null) { | 6719 if (externalKeyword != null) { |
| 6691 if (body is! EmptyFunctionBody) { | 6720 if (body is! EmptyFunctionBody) { |
| 6692 _reportErrorForNode(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body); | 6721 _reportErrorForNode(ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, body); |
| 6693 } | 6722 } |
| 6694 } else if (staticKeyword != null) { | 6723 } else if (staticKeyword != null) { |
| 6695 if (body is EmptyFunctionBody && _parseFunctionBodies) { | 6724 if (body is EmptyFunctionBody && _parseFunctionBodies) { |
| 6696 _reportErrorForNode(ParserErrorCode.ABSTRACT_STATIC_METHOD, body); | 6725 _reportErrorForNode(ParserErrorCode.ABSTRACT_STATIC_METHOD, body); |
| 6697 } | 6726 } |
| 6698 } | 6727 } |
| 6699 return new MethodDeclaration( | 6728 return astFactory.methodDeclaration( |
| 6700 commentAndMetadata.comment, | 6729 commentAndMetadata.comment, |
| 6701 commentAndMetadata.metadata, | 6730 commentAndMetadata.metadata, |
| 6702 externalKeyword, | 6731 externalKeyword, |
| 6703 staticKeyword, | 6732 staticKeyword, |
| 6704 returnType, | 6733 returnType, |
| 6705 null, | 6734 null, |
| 6706 null, | 6735 null, |
| 6707 name, | 6736 name, |
| 6708 typeParameters, | 6737 typeParameters, |
| 6709 parameters, | 6738 parameters, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 6730 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); | 6759 SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true); |
| 6731 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); | 6760 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); |
| 6732 FormalParameterList parameters; | 6761 FormalParameterList parameters; |
| 6733 TokenType type = _currentToken.type; | 6762 TokenType type = _currentToken.type; |
| 6734 // TODO(brianwilkerson) Figure out why we care what the current token is if | 6763 // TODO(brianwilkerson) Figure out why we care what the current token is if |
| 6735 // it isn't a paren. | 6764 // it isn't a paren. |
| 6736 if (type != TokenType.OPEN_PAREN && | 6765 if (type != TokenType.OPEN_PAREN && |
| 6737 (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.FUNCTION)) { | 6766 (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.FUNCTION)) { |
| 6738 _reportErrorForToken( | 6767 _reportErrorForToken( |
| 6739 ParserErrorCode.MISSING_METHOD_PARAMETERS, _currentToken.previous); | 6768 ParserErrorCode.MISSING_METHOD_PARAMETERS, _currentToken.previous); |
| 6740 parameters = new FormalParameterList( | 6769 parameters = astFactory.formalParameterList( |
| 6741 _createSyntheticToken(TokenType.OPEN_PAREN), | 6770 _createSyntheticToken(TokenType.OPEN_PAREN), |
| 6742 null, | 6771 null, |
| 6743 null, | 6772 null, |
| 6744 null, | 6773 null, |
| 6745 _createSyntheticToken(TokenType.CLOSE_PAREN)); | 6774 _createSyntheticToken(TokenType.CLOSE_PAREN)); |
| 6746 } else { | 6775 } else { |
| 6747 parameters = parseFormalParameterList(); | 6776 parameters = parseFormalParameterList(); |
| 6748 } | 6777 } |
| 6749 _validateFormalParameterList(parameters); | 6778 _validateFormalParameterList(parameters); |
| 6750 return _parseMethodDeclarationAfterParameters( | 6779 return _parseMethodDeclarationAfterParameters( |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 6761 * Parse a class native clause. Return the native clause that was parsed. | 6790 * Parse a class native clause. Return the native clause that was parsed. |
| 6762 * | 6791 * |
| 6763 * This method assumes that the current token matches `_NATIVE`. | 6792 * This method assumes that the current token matches `_NATIVE`. |
| 6764 * | 6793 * |
| 6765 * classNativeClause ::= | 6794 * classNativeClause ::= |
| 6766 * 'native' name | 6795 * 'native' name |
| 6767 */ | 6796 */ |
| 6768 NativeClause _parseNativeClause() { | 6797 NativeClause _parseNativeClause() { |
| 6769 Token keyword = getAndAdvance(); | 6798 Token keyword = getAndAdvance(); |
| 6770 StringLiteral name = parseStringLiteral(); | 6799 StringLiteral name = parseStringLiteral(); |
| 6771 return new NativeClause(keyword, name); | 6800 return astFactory.nativeClause(keyword, name); |
| 6772 } | 6801 } |
| 6773 | 6802 |
| 6774 /** | 6803 /** |
| 6775 * Parse an operator declaration starting after the 'operator' keyword. The | 6804 * Parse an operator declaration starting after the 'operator' keyword. The |
| 6776 * [commentAndMetadata] is the documentation comment and metadata to be | 6805 * [commentAndMetadata] is the documentation comment and metadata to be |
| 6777 * associated with the declaration. The [externalKeyword] is the 'external' | 6806 * associated with the declaration. The [externalKeyword] is the 'external' |
| 6778 * token. The [returnType] is the return type that has already been parsed, or | 6807 * token. The [returnType] is the return type that has already been parsed, or |
| 6779 * `null` if there was no return type. The [operatorKeyword] is the 'operator' | 6808 * `null` if there was no return type. The [operatorKeyword] is the 'operator' |
| 6780 * keyword. Return the operator declaration that was parsed. | 6809 * keyword. Return the operator declaration that was parsed. |
| 6781 * | 6810 * |
| 6782 * operatorDeclaration ::= | 6811 * operatorDeclaration ::= |
| 6783 * operatorSignature (';' | functionBody) | 6812 * operatorSignature (';' | functionBody) |
| 6784 * | 6813 * |
| 6785 * operatorSignature ::= | 6814 * operatorSignature ::= |
| 6786 * 'external'? returnType? 'operator' operator formalParameterList | 6815 * 'external'? returnType? 'operator' operator formalParameterList |
| 6787 */ | 6816 */ |
| 6788 MethodDeclaration _parseOperatorAfterKeyword( | 6817 MethodDeclaration _parseOperatorAfterKeyword( |
| 6789 CommentAndMetadata commentAndMetadata, | 6818 CommentAndMetadata commentAndMetadata, |
| 6790 Token externalKeyword, | 6819 Token externalKeyword, |
| 6791 TypeName returnType, | 6820 TypeName returnType, |
| 6792 Token operatorKeyword) { | 6821 Token operatorKeyword) { |
| 6793 if (!_currentToken.isUserDefinableOperator) { | 6822 if (!_currentToken.isUserDefinableOperator) { |
| 6794 _reportErrorForCurrentToken( | 6823 _reportErrorForCurrentToken( |
| 6795 ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]); | 6824 ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]); |
| 6796 } | 6825 } |
| 6797 SimpleIdentifier name = | 6826 SimpleIdentifier name = |
| 6798 new SimpleIdentifier(getAndAdvance(), isDeclaration: true); | 6827 astFactory.simpleIdentifier(getAndAdvance(), isDeclaration: true); |
| 6799 if (_matches(TokenType.EQ)) { | 6828 if (_matches(TokenType.EQ)) { |
| 6800 Token previous = _currentToken.previous; | 6829 Token previous = _currentToken.previous; |
| 6801 if ((_tokenMatches(previous, TokenType.EQ_EQ) || | 6830 if ((_tokenMatches(previous, TokenType.EQ_EQ) || |
| 6802 _tokenMatches(previous, TokenType.BANG_EQ)) && | 6831 _tokenMatches(previous, TokenType.BANG_EQ)) && |
| 6803 _currentToken.offset == previous.offset + 2) { | 6832 _currentToken.offset == previous.offset + 2) { |
| 6804 _reportErrorForCurrentToken(ParserErrorCode.INVALID_OPERATOR, | 6833 _reportErrorForCurrentToken(ParserErrorCode.INVALID_OPERATOR, |
| 6805 ["${previous.lexeme}${_currentToken.lexeme}"]); | 6834 ["${previous.lexeme}${_currentToken.lexeme}"]); |
| 6806 _advance(); | 6835 _advance(); |
| 6807 } | 6836 } |
| 6808 } | 6837 } |
| 6809 FormalParameterList parameters = parseFormalParameterList(); | 6838 FormalParameterList parameters = parseFormalParameterList(); |
| 6810 _validateFormalParameterList(parameters); | 6839 _validateFormalParameterList(parameters); |
| 6811 FunctionBody body = | 6840 FunctionBody body = |
| 6812 parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false); | 6841 parseFunctionBody(true, ParserErrorCode.MISSING_FUNCTION_BODY, false); |
| 6813 if (externalKeyword != null && body is! EmptyFunctionBody) { | 6842 if (externalKeyword != null && body is! EmptyFunctionBody) { |
| 6814 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY); | 6843 _reportErrorForCurrentToken(ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY); |
| 6815 } | 6844 } |
| 6816 return new MethodDeclaration( | 6845 return astFactory.methodDeclaration( |
| 6817 commentAndMetadata.comment, | 6846 commentAndMetadata.comment, |
| 6818 commentAndMetadata.metadata, | 6847 commentAndMetadata.metadata, |
| 6819 externalKeyword, | 6848 externalKeyword, |
| 6820 null, | 6849 null, |
| 6821 returnType, | 6850 returnType, |
| 6822 null, | 6851 null, |
| 6823 operatorKeyword, | 6852 operatorKeyword, |
| 6824 name, | 6853 name, |
| 6825 null, | 6854 null, |
| 6826 parameters, | 6855 parameters, |
| 6827 body); | 6856 body); |
| 6828 } | 6857 } |
| 6829 | 6858 |
| 6830 /** | 6859 /** |
| 6831 * Parse a return type if one is given, otherwise return `null` without | 6860 * Parse a return type if one is given, otherwise return `null` without |
| 6832 * advancing. Return the return type that was parsed. | 6861 * advancing. Return the return type that was parsed. |
| 6833 */ | 6862 */ |
| 6834 TypeName _parseOptionalReturnType() { | 6863 TypeName _parseOptionalReturnType() { |
| 6835 TypeName typeComment = _parseOptionalTypeNameComment(); | 6864 TypeName typeComment = _parseOptionalTypeNameComment(); |
| 6836 if (typeComment != null) { | 6865 if (typeComment != null) { |
| 6837 return typeComment; | 6866 return typeComment; |
| 6838 } | 6867 } |
| 6839 Keyword keyword = _currentToken.keyword; | 6868 Keyword keyword = _currentToken.keyword; |
| 6840 if (keyword == Keyword.VOID) { | 6869 if (keyword == Keyword.VOID) { |
| 6841 return new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 6870 return astFactory.typeName( |
| 6871 astFactory.simpleIdentifier(getAndAdvance()), null); | |
| 6842 } else if (_matchesIdentifier()) { | 6872 } else if (_matchesIdentifier()) { |
| 6843 Token next = _peek(); | 6873 Token next = _peek(); |
| 6844 if (keyword != Keyword.GET && | 6874 if (keyword != Keyword.GET && |
| 6845 keyword != Keyword.SET && | 6875 keyword != Keyword.SET && |
| 6846 keyword != Keyword.OPERATOR && | 6876 keyword != Keyword.OPERATOR && |
| 6847 (_tokenMatchesIdentifier(next) || | 6877 (_tokenMatchesIdentifier(next) || |
| 6848 _tokenMatches(next, TokenType.LT))) { | 6878 _tokenMatches(next, TokenType.LT))) { |
| 6849 return parseReturnType(); | 6879 return parseReturnType(); |
| 6850 } | 6880 } |
| 6851 Token next2 = next.next; | 6881 Token next2 = next.next; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6885 * | 6915 * |
| 6886 * This method assumes that the current token matches `Keyword.PART`. | 6916 * This method assumes that the current token matches `Keyword.PART`. |
| 6887 * | 6917 * |
| 6888 * partDirective ::= | 6918 * partDirective ::= |
| 6889 * metadata 'part' stringLiteral ';' | 6919 * metadata 'part' stringLiteral ';' |
| 6890 */ | 6920 */ |
| 6891 Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) { | 6921 Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) { |
| 6892 Token partKeyword = getAndAdvance(); | 6922 Token partKeyword = getAndAdvance(); |
| 6893 StringLiteral partUri = _parseUri(); | 6923 StringLiteral partUri = _parseUri(); |
| 6894 Token semicolon = _expect(TokenType.SEMICOLON); | 6924 Token semicolon = _expect(TokenType.SEMICOLON); |
| 6895 return new PartDirective(commentAndMetadata.comment, | 6925 return astFactory.partDirective(commentAndMetadata.comment, |
| 6896 commentAndMetadata.metadata, partKeyword, partUri, semicolon); | 6926 commentAndMetadata.metadata, partKeyword, partUri, semicolon); |
| 6897 } | 6927 } |
| 6898 | 6928 |
| 6899 /** | 6929 /** |
| 6900 * Parse a part-of directive. The [commentAndMetadata] is the metadata to be | 6930 * Parse a part-of directive. The [commentAndMetadata] is the metadata to be |
| 6901 * associated with the directive. Return the part or part-of directive that | 6931 * associated with the directive. Return the part or part-of directive that |
| 6902 * was parsed. | 6932 * was parsed. |
| 6903 * | 6933 * |
| 6904 * This method assumes that the current token matches [Keyword.PART] and that | 6934 * This method assumes that the current token matches [Keyword.PART] and that |
| 6905 * the following token matches the identifier 'of'. | 6935 * the following token matches the identifier 'of'. |
| 6906 * | 6936 * |
| 6907 * partOfDirective ::= | 6937 * partOfDirective ::= |
| 6908 * metadata 'part' 'of' identifier ';' | 6938 * metadata 'part' 'of' identifier ';' |
| 6909 */ | 6939 */ |
| 6910 Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) { | 6940 Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) { |
| 6911 Token partKeyword = getAndAdvance(); | 6941 Token partKeyword = getAndAdvance(); |
| 6912 Token ofKeyword = getAndAdvance(); | 6942 Token ofKeyword = getAndAdvance(); |
| 6913 if (enableUriInPartOf && _matches(TokenType.STRING)) { | 6943 if (enableUriInPartOf && _matches(TokenType.STRING)) { |
| 6914 StringLiteral libraryUri = _parseUri(); | 6944 StringLiteral libraryUri = _parseUri(); |
| 6915 Token semicolon = _expect(TokenType.SEMICOLON); | 6945 Token semicolon = _expect(TokenType.SEMICOLON); |
| 6916 return new PartOfDirective( | 6946 return astFactory.partOfDirective( |
| 6917 commentAndMetadata.comment, | 6947 commentAndMetadata.comment, |
| 6918 commentAndMetadata.metadata, | 6948 commentAndMetadata.metadata, |
| 6919 partKeyword, | 6949 partKeyword, |
| 6920 ofKeyword, | 6950 ofKeyword, |
| 6921 libraryUri, | 6951 libraryUri, |
| 6922 null, | 6952 null, |
| 6923 semicolon); | 6953 semicolon); |
| 6924 } | 6954 } |
| 6925 LibraryIdentifier libraryName = _parseLibraryName( | 6955 LibraryIdentifier libraryName = _parseLibraryName( |
| 6926 ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword); | 6956 ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword); |
| 6927 Token semicolon = _expect(TokenType.SEMICOLON); | 6957 Token semicolon = _expect(TokenType.SEMICOLON); |
| 6928 return new PartOfDirective( | 6958 return astFactory.partOfDirective( |
| 6929 commentAndMetadata.comment, | 6959 commentAndMetadata.comment, |
| 6930 commentAndMetadata.metadata, | 6960 commentAndMetadata.metadata, |
| 6931 partKeyword, | 6961 partKeyword, |
| 6932 ofKeyword, | 6962 ofKeyword, |
| 6933 null, | 6963 null, |
| 6934 libraryName, | 6964 libraryName, |
| 6935 semicolon); | 6965 semicolon); |
| 6936 } | 6966 } |
| 6937 | 6967 |
| 6938 /** | 6968 /** |
| 6939 * Parse a prefixed identifier given that the given [qualifier] was already | 6969 * Parse a prefixed identifier given that the given [qualifier] was already |
| 6940 * parsed. Return the prefixed identifier that was parsed. | 6970 * parsed. Return the prefixed identifier that was parsed. |
| 6941 * | 6971 * |
| 6942 * prefixedIdentifier ::= | 6972 * prefixedIdentifier ::= |
| 6943 * identifier ('.' identifier)? | 6973 * identifier ('.' identifier)? |
| 6944 */ | 6974 */ |
| 6945 Identifier _parsePrefixedIdentifierAfterIdentifier( | 6975 Identifier _parsePrefixedIdentifierAfterIdentifier( |
| 6946 SimpleIdentifier qualifier) { | 6976 SimpleIdentifier qualifier) { |
| 6947 if (!_matches(TokenType.PERIOD) || _injectGenericCommentTypeList()) { | 6977 if (!_matches(TokenType.PERIOD) || _injectGenericCommentTypeList()) { |
| 6948 return qualifier; | 6978 return qualifier; |
| 6949 } | 6979 } |
| 6950 Token period = getAndAdvance(); | 6980 Token period = getAndAdvance(); |
| 6951 SimpleIdentifier qualified = parseSimpleIdentifier(); | 6981 SimpleIdentifier qualified = parseSimpleIdentifier(); |
| 6952 return new PrefixedIdentifier(qualifier, period, qualified); | 6982 return astFactory.prefixedIdentifier(qualifier, period, qualified); |
| 6953 } | 6983 } |
| 6954 | 6984 |
| 6955 /** | 6985 /** |
| 6956 * Parse a prefixed identifier. Return the prefixed identifier that was | 6986 * Parse a prefixed identifier. Return the prefixed identifier that was |
| 6957 * parsed. | 6987 * parsed. |
| 6958 * | 6988 * |
| 6959 * This method assumes that the current token matches an identifier. | 6989 * This method assumes that the current token matches an identifier. |
| 6960 * | 6990 * |
| 6961 * prefixedIdentifier ::= | 6991 * prefixedIdentifier ::= |
| 6962 * identifier ('.' identifier)? | 6992 * identifier ('.' identifier)? |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 6975 * IDENTIFIER | 7005 * IDENTIFIER |
| 6976 */ | 7006 */ |
| 6977 SimpleIdentifier _parseSimpleIdentifierUnchecked( | 7007 SimpleIdentifier _parseSimpleIdentifierUnchecked( |
| 6978 {bool isDeclaration: false}) { | 7008 {bool isDeclaration: false}) { |
| 6979 String lexeme = _currentToken.lexeme; | 7009 String lexeme = _currentToken.lexeme; |
| 6980 if ((_inAsync || _inGenerator) && | 7010 if ((_inAsync || _inGenerator) && |
| 6981 (lexeme == ASYNC || lexeme == _AWAIT || lexeme == _YIELD)) { | 7011 (lexeme == ASYNC || lexeme == _AWAIT || lexeme == _YIELD)) { |
| 6982 _reportErrorForCurrentToken( | 7012 _reportErrorForCurrentToken( |
| 6983 ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER); | 7013 ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER); |
| 6984 } | 7014 } |
| 6985 return new SimpleIdentifier(getAndAdvance(), isDeclaration: isDeclaration); | 7015 return astFactory.simpleIdentifier(getAndAdvance(), |
| 7016 isDeclaration: isDeclaration); | |
| 6986 } | 7017 } |
| 6987 | 7018 |
| 6988 /** | 7019 /** |
| 6989 * Parse a list of statements within a switch statement. Return the statements | 7020 * Parse a list of statements within a switch statement. Return the statements |
| 6990 * that were parsed. | 7021 * that were parsed. |
| 6991 * | 7022 * |
| 6992 * statements ::= | 7023 * statements ::= |
| 6993 * statement* | 7024 * statement* |
| 6994 */ | 7025 */ |
| 6995 List<Statement> _parseStatementList() { | 7026 List<Statement> _parseStatementList() { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 7014 /** | 7045 /** |
| 7015 * Parse a string literal that contains interpolations. Return the string | 7046 * Parse a string literal that contains interpolations. Return the string |
| 7016 * literal that was parsed. | 7047 * literal that was parsed. |
| 7017 * | 7048 * |
| 7018 * This method assumes that the current token matches either | 7049 * This method assumes that the current token matches either |
| 7019 * [TokenType.STRING_INTERPOLATION_EXPRESSION] or | 7050 * [TokenType.STRING_INTERPOLATION_EXPRESSION] or |
| 7020 * [TokenType.STRING_INTERPOLATION_IDENTIFIER]. | 7051 * [TokenType.STRING_INTERPOLATION_IDENTIFIER]. |
| 7021 */ | 7052 */ |
| 7022 StringInterpolation _parseStringInterpolation(Token string) { | 7053 StringInterpolation _parseStringInterpolation(Token string) { |
| 7023 List<InterpolationElement> elements = <InterpolationElement>[ | 7054 List<InterpolationElement> elements = <InterpolationElement>[ |
| 7024 new InterpolationString( | 7055 astFactory.interpolationString( |
| 7025 string, computeStringValue(string.lexeme, true, false)) | 7056 string, computeStringValue(string.lexeme, true, false)) |
| 7026 ]; | 7057 ]; |
| 7027 bool hasMore = true; | 7058 bool hasMore = true; |
| 7028 bool isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION); | 7059 bool isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION); |
| 7029 while (hasMore) { | 7060 while (hasMore) { |
| 7030 if (isExpression) { | 7061 if (isExpression) { |
| 7031 Token openToken = getAndAdvance(); | 7062 Token openToken = getAndAdvance(); |
| 7032 bool wasInInitializer = _inInitializer; | 7063 bool wasInInitializer = _inInitializer; |
| 7033 _inInitializer = false; | 7064 _inInitializer = false; |
| 7034 try { | 7065 try { |
| 7035 Expression expression = parseExpression2(); | 7066 Expression expression = parseExpression2(); |
| 7036 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); | 7067 Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET); |
| 7037 elements.add( | 7068 elements.add(astFactory.interpolationExpression( |
| 7038 new InterpolationExpression(openToken, expression, rightBracket)); | 7069 openToken, expression, rightBracket)); |
| 7039 } finally { | 7070 } finally { |
| 7040 _inInitializer = wasInInitializer; | 7071 _inInitializer = wasInInitializer; |
| 7041 } | 7072 } |
| 7042 } else { | 7073 } else { |
| 7043 Token openToken = getAndAdvance(); | 7074 Token openToken = getAndAdvance(); |
| 7044 Expression expression = null; | 7075 Expression expression = null; |
| 7045 if (_matchesKeyword(Keyword.THIS)) { | 7076 if (_matchesKeyword(Keyword.THIS)) { |
| 7046 expression = new ThisExpression(getAndAdvance()); | 7077 expression = astFactory.thisExpression(getAndAdvance()); |
| 7047 } else { | 7078 } else { |
| 7048 expression = parseSimpleIdentifier(); | 7079 expression = parseSimpleIdentifier(); |
| 7049 } | 7080 } |
| 7050 elements.add(new InterpolationExpression(openToken, expression, null)); | 7081 elements.add( |
| 7082 astFactory.interpolationExpression(openToken, expression, null)); | |
| 7051 } | 7083 } |
| 7052 if (_matches(TokenType.STRING)) { | 7084 if (_matches(TokenType.STRING)) { |
| 7053 string = getAndAdvance(); | 7085 string = getAndAdvance(); |
| 7054 isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION); | 7086 isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION); |
| 7055 hasMore = | 7087 hasMore = |
| 7056 isExpression || _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER); | 7088 isExpression || _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER); |
| 7057 elements.add(new InterpolationString( | 7089 elements.add(astFactory.interpolationString( |
| 7058 string, computeStringValue(string.lexeme, false, !hasMore))); | 7090 string, computeStringValue(string.lexeme, false, !hasMore))); |
| 7059 } else { | 7091 } else { |
| 7060 hasMore = false; | 7092 hasMore = false; |
| 7061 } | 7093 } |
| 7062 } | 7094 } |
| 7063 return new StringInterpolation(elements); | 7095 return astFactory.stringInterpolation(elements); |
| 7064 } | 7096 } |
| 7065 | 7097 |
| 7066 /** | 7098 /** |
| 7067 * Parse a string literal. Return the string literal that was parsed. | 7099 * Parse a string literal. Return the string literal that was parsed. |
| 7068 * | 7100 * |
| 7069 * This method assumes that the current token matches `TokenType.STRING`. | 7101 * This method assumes that the current token matches `TokenType.STRING`. |
| 7070 * | 7102 * |
| 7071 * stringLiteral ::= | 7103 * stringLiteral ::= |
| 7072 * MULTI_LINE_STRING+ | 7104 * MULTI_LINE_STRING+ |
| 7073 * | SINGLE_LINE_STRING+ | 7105 * | SINGLE_LINE_STRING+ |
| 7074 */ | 7106 */ |
| 7075 StringLiteral _parseStringLiteralUnchecked() { | 7107 StringLiteral _parseStringLiteralUnchecked() { |
| 7076 List<StringLiteral> strings = <StringLiteral>[]; | 7108 List<StringLiteral> strings = <StringLiteral>[]; |
| 7077 do { | 7109 do { |
| 7078 Token string = getAndAdvance(); | 7110 Token string = getAndAdvance(); |
| 7079 if (_matches(TokenType.STRING_INTERPOLATION_EXPRESSION) || | 7111 if (_matches(TokenType.STRING_INTERPOLATION_EXPRESSION) || |
| 7080 _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER)) { | 7112 _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER)) { |
| 7081 strings.add(_parseStringInterpolation(string)); | 7113 strings.add(_parseStringInterpolation(string)); |
| 7082 } else { | 7114 } else { |
| 7083 strings.add(new SimpleStringLiteral( | 7115 strings.add(astFactory.simpleStringLiteral( |
| 7084 string, computeStringValue(string.lexeme, true, true))); | 7116 string, computeStringValue(string.lexeme, true, true))); |
| 7085 } | 7117 } |
| 7086 } while (_matches(TokenType.STRING)); | 7118 } while (_matches(TokenType.STRING)); |
| 7087 return strings.length == 1 ? strings[0] : new AdjacentStrings(strings); | 7119 return strings.length == 1 |
| 7120 ? strings[0] | |
| 7121 : astFactory.adjacentStrings(strings); | |
| 7088 } | 7122 } |
| 7089 | 7123 |
| 7090 TypeName _parseTypeName(bool inExpression) { | 7124 TypeName _parseTypeName(bool inExpression) { |
| 7091 Identifier typeName; | 7125 Identifier typeName; |
| 7092 if (_matchesIdentifier()) { | 7126 if (_matchesIdentifier()) { |
| 7093 typeName = _parsePrefixedIdentifierUnchecked(); | 7127 typeName = _parsePrefixedIdentifierUnchecked(); |
| 7094 } else if (_matchesKeyword(Keyword.VAR)) { | 7128 } else if (_matchesKeyword(Keyword.VAR)) { |
| 7095 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); | 7129 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); |
| 7096 typeName = new SimpleIdentifier(getAndAdvance()); | 7130 typeName = astFactory.simpleIdentifier(getAndAdvance()); |
| 7097 } else { | 7131 } else { |
| 7098 typeName = createSyntheticIdentifier(); | 7132 typeName = createSyntheticIdentifier(); |
| 7099 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); | 7133 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); |
| 7100 } | 7134 } |
| 7101 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7135 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 7102 Token question = null; | 7136 Token question = null; |
| 7103 if (enableNnbd && _matches(TokenType.QUESTION)) { | 7137 if (enableNnbd && _matches(TokenType.QUESTION)) { |
| 7104 if (!inExpression || !_isConditionalOperator()) { | 7138 if (!inExpression || !_isConditionalOperator()) { |
| 7105 question = getAndAdvance(); | 7139 question = getAndAdvance(); |
| 7106 } | 7140 } |
| 7107 } | 7141 } |
| 7108 return new TypeName(typeName, typeArguments, question: question); | 7142 return astFactory.typeName(typeName, typeArguments, question: question); |
| 7109 } | 7143 } |
| 7110 | 7144 |
| 7111 /** | 7145 /** |
| 7112 * Parse a type name. Return the type name that was parsed. | 7146 * Parse a type name. Return the type name that was parsed. |
| 7113 * | 7147 * |
| 7114 * This method assumes that the current token is an identifier. | 7148 * This method assumes that the current token is an identifier. |
| 7115 * | 7149 * |
| 7116 * type ::= | 7150 * type ::= |
| 7117 * qualified typeArguments? | 7151 * qualified typeArguments? |
| 7118 */ | 7152 */ |
| 7119 TypeName _parseTypeNameAfterIdentifier() { | 7153 TypeName _parseTypeNameAfterIdentifier() { |
| 7120 Identifier typeName = _parsePrefixedIdentifierUnchecked(); | 7154 Identifier typeName = _parsePrefixedIdentifierUnchecked(); |
| 7121 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7155 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 7122 // If this is followed by a generic method type comment, allow the comment | 7156 // If this is followed by a generic method type comment, allow the comment |
| 7123 // type to replace the real type name. | 7157 // type to replace the real type name. |
| 7124 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to | 7158 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to |
| 7125 // only work inside generic methods? | 7159 // only work inside generic methods? |
| 7126 TypeName typeFromComment = _parseOptionalTypeNameComment(); | 7160 TypeName typeFromComment = _parseOptionalTypeNameComment(); |
| 7127 return typeFromComment ?? new TypeName(typeName, typeArguments); | 7161 return typeFromComment ?? astFactory.typeName(typeName, typeArguments); |
| 7128 } | 7162 } |
| 7129 | 7163 |
| 7130 /** | 7164 /** |
| 7131 * Parse a string literal representing a URI. Return the string literal that | 7165 * Parse a string literal representing a URI. Return the string literal that |
| 7132 * was parsed. | 7166 * was parsed. |
| 7133 */ | 7167 */ |
| 7134 StringLiteral _parseUri() { | 7168 StringLiteral _parseUri() { |
| 7135 // TODO(brianwilkerson) Should this function also return true for valid | 7169 // TODO(brianwilkerson) Should this function also return true for valid |
| 7136 // top-level keywords? | 7170 // top-level keywords? |
| 7137 bool isKeywordAfterUri(Token token) => | 7171 bool isKeywordAfterUri(Token token) => |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7174 } | 7208 } |
| 7175 buffer.write(token.lexeme); | 7209 buffer.write(token.lexeme); |
| 7176 endOffset = token.end; | 7210 endOffset = token.end; |
| 7177 } | 7211 } |
| 7178 String value = buffer.toString(); | 7212 String value = buffer.toString(); |
| 7179 Token newToken = | 7213 Token newToken = |
| 7180 new StringToken(TokenType.STRING, "'$value'", _currentToken.offset); | 7214 new StringToken(TokenType.STRING, "'$value'", _currentToken.offset); |
| 7181 _reportErrorForToken( | 7215 _reportErrorForToken( |
| 7182 ParserErrorCode.NON_STRING_LITERAL_AS_URI, newToken); | 7216 ParserErrorCode.NON_STRING_LITERAL_AS_URI, newToken); |
| 7183 _currentToken = endToken.next; | 7217 _currentToken = endToken.next; |
| 7184 return new SimpleStringLiteral(newToken, value); | 7218 return astFactory.simpleStringLiteral(newToken, value); |
| 7185 } | 7219 } |
| 7186 } | 7220 } |
| 7187 return parseStringLiteral(); | 7221 return parseStringLiteral(); |
| 7188 } | 7222 } |
| 7189 | 7223 |
| 7190 /** | 7224 /** |
| 7191 * Parse a variable declaration statement. The [commentAndMetadata] is the | 7225 * Parse a variable declaration statement. The [commentAndMetadata] is the |
| 7192 * metadata to be associated with the variable declaration statement, or | 7226 * metadata to be associated with the variable declaration statement, or |
| 7193 * `null` if there is no attempt at parsing the comment and metadata. The | 7227 * `null` if there is no attempt at parsing the comment and metadata. The |
| 7194 * [keyword] is the token representing the 'final', 'const' or 'var' keyword, | 7228 * [keyword] is the token representing the 'final', 'const' or 'var' keyword, |
| 7195 * or `null` if there is no keyword. The [type] is the type of the variables | 7229 * or `null` if there is no keyword. The [type] is the type of the variables |
| 7196 * in the list. Return the variable declaration statement that was parsed. | 7230 * in the list. Return the variable declaration statement that was parsed. |
| 7197 * | 7231 * |
| 7198 * variableDeclarationStatement ::= | 7232 * variableDeclarationStatement ::= |
| 7199 * variableDeclarationList ';' | 7233 * variableDeclarationList ';' |
| 7200 */ | 7234 */ |
| 7201 VariableDeclarationStatement _parseVariableDeclarationStatementAfterType( | 7235 VariableDeclarationStatement _parseVariableDeclarationStatementAfterType( |
| 7202 CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) { | 7236 CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) { |
| 7203 VariableDeclarationList variableList = | 7237 VariableDeclarationList variableList = |
| 7204 parseVariableDeclarationListAfterType( | 7238 parseVariableDeclarationListAfterType( |
| 7205 commentAndMetadata, keyword, type); | 7239 commentAndMetadata, keyword, type); |
| 7206 Token semicolon = _expect(TokenType.SEMICOLON); | 7240 Token semicolon = _expect(TokenType.SEMICOLON); |
| 7207 return new VariableDeclarationStatement(variableList, semicolon); | 7241 return astFactory.variableDeclarationStatement(variableList, semicolon); |
| 7208 } | 7242 } |
| 7209 | 7243 |
| 7210 /** | 7244 /** |
| 7211 * Return the token that is immediately after the current token. This is | 7245 * Return the token that is immediately after the current token. This is |
| 7212 * equivalent to [_peekAt](1). | 7246 * equivalent to [_peekAt](1). |
| 7213 */ | 7247 */ |
| 7214 Token _peek() => _currentToken.next; | 7248 Token _peek() => _currentToken.next; |
| 7215 | 7249 |
| 7216 /** | 7250 /** |
| 7217 * Return the token that is the given [distance] after the current token, | 7251 * Return the token that is the given [distance] after the current token, |
| (...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8147 */ | 8181 */ |
| 8148 Parser_SyntheticKeywordToken(Keyword keyword, int offset) | 8182 Parser_SyntheticKeywordToken(Keyword keyword, int offset) |
| 8149 : super(keyword, offset); | 8183 : super(keyword, offset); |
| 8150 | 8184 |
| 8151 @override | 8185 @override |
| 8152 int get length => 0; | 8186 int get length => 0; |
| 8153 | 8187 |
| 8154 @override | 8188 @override |
| 8155 Token copy() => new Parser_SyntheticKeywordToken(keyword, offset); | 8189 Token copy() => new Parser_SyntheticKeywordToken(keyword, offset); |
| 8156 } | 8190 } |
| OLD | NEW |