| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library fasta.parser.parser; | 5 library fasta.parser.parser; |
| 6 | 6 |
| 7 import '../scanner.dart' show ErrorToken; | 7 import '../scanner.dart' show ErrorToken; |
| 8 | 8 |
| 9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; | 9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; |
| 10 | 10 |
| (...skipping 2580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2591 token = parsePrecedenceExpression(token.next, level, allowCascades); | 2591 token = parsePrecedenceExpression(token.next, level, allowCascades); |
| 2592 listener.handleAssignmentExpression(operator); | 2592 listener.handleAssignmentExpression(operator); |
| 2593 } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) { | 2593 } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) { |
| 2594 if (identical(info, PERIOD_INFO) || | 2594 if (identical(info, PERIOD_INFO) || |
| 2595 identical(info, QUESTION_PERIOD_INFO)) { | 2595 identical(info, QUESTION_PERIOD_INFO)) { |
| 2596 // Left associative, so we recurse at the next higher precedence | 2596 // Left associative, so we recurse at the next higher precedence |
| 2597 // level. However, POSTFIX_PRECEDENCE is the highest level, so we | 2597 // level. However, POSTFIX_PRECEDENCE is the highest level, so we |
| 2598 // should just call [parseUnaryExpression] directly. However, a | 2598 // should just call [parseUnaryExpression] directly. However, a |
| 2599 // unary expression isn't legal after a period, so we call | 2599 // unary expression isn't legal after a period, so we call |
| 2600 // [parsePrimary] instead. | 2600 // [parsePrimary] instead. |
| 2601 token = parsePrimary(token.next); | 2601 token = parsePrimary( |
| 2602 token.next, IdentifierContext.expressionContinuation); |
| 2602 listener.handleBinaryExpression(operator); | 2603 listener.handleBinaryExpression(operator); |
| 2603 } else if ((identical(info, OPEN_PAREN_INFO)) || | 2604 } else if ((identical(info, OPEN_PAREN_INFO)) || |
| 2604 (identical(info, OPEN_SQUARE_BRACKET_INFO))) { | 2605 (identical(info, OPEN_SQUARE_BRACKET_INFO))) { |
| 2605 token = parseArgumentOrIndexStar(token); | 2606 token = parseArgumentOrIndexStar(token); |
| 2606 } else if ((identical(info, PLUS_PLUS_INFO)) || | 2607 } else if ((identical(info, PLUS_PLUS_INFO)) || |
| 2607 (identical(info, MINUS_MINUS_INFO))) { | 2608 (identical(info, MINUS_MINUS_INFO))) { |
| 2608 listener.handleUnaryPostfixAssignmentExpression(token); | 2609 listener.handleUnaryPostfixAssignmentExpression(token); |
| 2609 token = token.next; | 2610 token = token.next; |
| 2610 } else { | 2611 } else { |
| 2611 token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken) | 2612 token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2669 } | 2670 } |
| 2670 listener.endCascade(); | 2671 listener.endCascade(); |
| 2671 return token; | 2672 return token; |
| 2672 } | 2673 } |
| 2673 | 2674 |
| 2674 Token parseUnaryExpression(Token token, bool allowCascades) { | 2675 Token parseUnaryExpression(Token token, bool allowCascades) { |
| 2675 String value = token.stringValue; | 2676 String value = token.stringValue; |
| 2676 // Prefix: | 2677 // Prefix: |
| 2677 if (optional('await', token)) { | 2678 if (optional('await', token)) { |
| 2678 if (inPlainSync) { | 2679 if (inPlainSync) { |
| 2679 return parsePrimary(token); | 2680 return parsePrimary(token, IdentifierContext.expression); |
| 2680 } else { | 2681 } else { |
| 2681 return parseAwaitExpression(token, allowCascades); | 2682 return parseAwaitExpression(token, allowCascades); |
| 2682 } | 2683 } |
| 2683 } else if (identical(value, '+')) { | 2684 } else if (identical(value, '+')) { |
| 2684 // Dart no longer allows prefix-plus. | 2685 // Dart no longer allows prefix-plus. |
| 2685 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); | 2686 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); |
| 2686 return parseUnaryExpression(token.next, allowCascades); | 2687 return parseUnaryExpression(token.next, allowCascades); |
| 2687 } else if ((identical(value, '!')) || | 2688 } else if ((identical(value, '!')) || |
| 2688 (identical(value, '-')) || | 2689 (identical(value, '-')) || |
| 2689 (identical(value, '~'))) { | 2690 (identical(value, '~'))) { |
| 2690 Token operator = token; | 2691 Token operator = token; |
| 2691 // Right associative, so we recurse at the same precedence | 2692 // Right associative, so we recurse at the same precedence |
| 2692 // level. | 2693 // level. |
| 2693 token = parsePrecedenceExpression( | 2694 token = parsePrecedenceExpression( |
| 2694 token.next, POSTFIX_PRECEDENCE, allowCascades); | 2695 token.next, POSTFIX_PRECEDENCE, allowCascades); |
| 2695 listener.handleUnaryPrefixExpression(operator); | 2696 listener.handleUnaryPrefixExpression(operator); |
| 2696 return token; | 2697 return token; |
| 2697 } else if ((identical(value, '++')) || identical(value, '--')) { | 2698 } else if ((identical(value, '++')) || identical(value, '--')) { |
| 2698 // TODO(ahe): Validate this is used correctly. | 2699 // TODO(ahe): Validate this is used correctly. |
| 2699 Token operator = token; | 2700 Token operator = token; |
| 2700 // Right associative, so we recurse at the same precedence | 2701 // Right associative, so we recurse at the same precedence |
| 2701 // level. | 2702 // level. |
| 2702 token = parsePrecedenceExpression( | 2703 token = parsePrecedenceExpression( |
| 2703 token.next, POSTFIX_PRECEDENCE, allowCascades); | 2704 token.next, POSTFIX_PRECEDENCE, allowCascades); |
| 2704 listener.handleUnaryPrefixAssignmentExpression(operator); | 2705 listener.handleUnaryPrefixAssignmentExpression(operator); |
| 2705 return token; | 2706 return token; |
| 2706 } else { | 2707 } else { |
| 2707 return parsePrimary(token); | 2708 return parsePrimary(token, IdentifierContext.expression); |
| 2708 } | 2709 } |
| 2709 } | 2710 } |
| 2710 | 2711 |
| 2711 Token parseArgumentOrIndexStar(Token token) { | 2712 Token parseArgumentOrIndexStar(Token token) { |
| 2712 Token beginToken = token; | 2713 Token beginToken = token; |
| 2713 while (true) { | 2714 while (true) { |
| 2714 if (optional('[', token)) { | 2715 if (optional('[', token)) { |
| 2715 Token openSquareBracket = token; | 2716 Token openSquareBracket = token; |
| 2716 bool old = mayParseFunctionExpressions; | 2717 bool old = mayParseFunctionExpressions; |
| 2717 mayParseFunctionExpressions = true; | 2718 mayParseFunctionExpressions = true; |
| 2718 token = parseExpression(token.next); | 2719 token = parseExpression(token.next); |
| 2719 mayParseFunctionExpressions = old; | 2720 mayParseFunctionExpressions = old; |
| 2720 listener.handleIndexedExpression(openSquareBracket, token); | 2721 listener.handleIndexedExpression(openSquareBracket, token); |
| 2721 token = expect(']', token); | 2722 token = expect(']', token); |
| 2722 } else if (optional('(', token)) { | 2723 } else if (optional('(', token)) { |
| 2723 listener.handleNoTypeArguments(token); | 2724 listener.handleNoTypeArguments(token); |
| 2724 token = parseArguments(token); | 2725 token = parseArguments(token); |
| 2725 listener.endSend(beginToken, token); | 2726 listener.endSend(beginToken, token); |
| 2726 } else { | 2727 } else { |
| 2727 break; | 2728 break; |
| 2728 } | 2729 } |
| 2729 } | 2730 } |
| 2730 return token; | 2731 return token; |
| 2731 } | 2732 } |
| 2732 | 2733 |
| 2733 Token parsePrimary(Token token) { | 2734 Token parsePrimary(Token token, IdentifierContext context) { |
| 2734 final kind = token.kind; | 2735 final kind = token.kind; |
| 2735 if (kind == IDENTIFIER_TOKEN) { | 2736 if (kind == IDENTIFIER_TOKEN) { |
| 2736 return parseSendOrFunctionLiteral(token); | 2737 return parseSendOrFunctionLiteral(token, context); |
| 2737 } else if (kind == INT_TOKEN || kind == HEXADECIMAL_TOKEN) { | 2738 } else if (kind == INT_TOKEN || kind == HEXADECIMAL_TOKEN) { |
| 2738 return parseLiteralInt(token); | 2739 return parseLiteralInt(token); |
| 2739 } else if (kind == DOUBLE_TOKEN) { | 2740 } else if (kind == DOUBLE_TOKEN) { |
| 2740 return parseLiteralDouble(token); | 2741 return parseLiteralDouble(token); |
| 2741 } else if (kind == STRING_TOKEN) { | 2742 } else if (kind == STRING_TOKEN) { |
| 2742 return parseLiteralString(token); | 2743 return parseLiteralString(token); |
| 2743 } else if (kind == HASH_TOKEN) { | 2744 } else if (kind == HASH_TOKEN) { |
| 2744 return parseLiteralSymbol(token); | 2745 return parseLiteralSymbol(token); |
| 2745 } else if (kind == KEYWORD_TOKEN) { | 2746 } else if (kind == KEYWORD_TOKEN) { |
| 2746 final String value = token.stringValue; | 2747 final String value = token.stringValue; |
| 2747 if (identical(value, "true") || identical(value, "false")) { | 2748 if (identical(value, "true") || identical(value, "false")) { |
| 2748 return parseLiteralBool(token); | 2749 return parseLiteralBool(token); |
| 2749 } else if (identical(value, "null")) { | 2750 } else if (identical(value, "null")) { |
| 2750 return parseLiteralNull(token); | 2751 return parseLiteralNull(token); |
| 2751 } else if (identical(value, "this")) { | 2752 } else if (identical(value, "this")) { |
| 2752 return parseThisExpression(token); | 2753 return parseThisExpression(token, context); |
| 2753 } else if (identical(value, "super")) { | 2754 } else if (identical(value, "super")) { |
| 2754 return parseSuperExpression(token); | 2755 return parseSuperExpression(token, context); |
| 2755 } else if (identical(value, "new")) { | 2756 } else if (identical(value, "new")) { |
| 2756 return parseNewExpression(token); | 2757 return parseNewExpression(token); |
| 2757 } else if (identical(value, "const")) { | 2758 } else if (identical(value, "const")) { |
| 2758 return parseConstExpression(token); | 2759 return parseConstExpression(token); |
| 2759 } else if (identical(value, "void")) { | 2760 } else if (identical(value, "void")) { |
| 2760 return parseFunctionExpression(token); | 2761 return parseFunctionExpression(token); |
| 2761 } else if (!inPlainSync && | 2762 } else if (!inPlainSync && |
| 2762 (identical(value, "yield") || identical(value, "async"))) { | 2763 (identical(value, "yield") || identical(value, "async"))) { |
| 2763 return expressionExpected(token); | 2764 return expressionExpected(token); |
| 2764 } else if (token.isIdentifier()) { | 2765 } else if (token.isIdentifier()) { |
| 2765 return parseSendOrFunctionLiteral(token); | 2766 return parseSendOrFunctionLiteral(token, context); |
| 2766 } else { | 2767 } else { |
| 2767 return expressionExpected(token); | 2768 return expressionExpected(token); |
| 2768 } | 2769 } |
| 2769 } else if (kind == OPEN_PAREN_TOKEN) { | 2770 } else if (kind == OPEN_PAREN_TOKEN) { |
| 2770 return parseParenthesizedExpressionOrFunctionLiteral(token); | 2771 return parseParenthesizedExpressionOrFunctionLiteral(token); |
| 2771 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { | 2772 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { |
| 2772 listener.handleNoTypeArguments(token); | 2773 listener.handleNoTypeArguments(token); |
| 2773 return parseLiteralListSuffix(token, null); | 2774 return parseLiteralListSuffix(token, null); |
| 2774 } else if (kind == OPEN_CURLY_BRACKET_TOKEN) { | 2775 } else if (kind == OPEN_CURLY_BRACKET_TOKEN) { |
| 2775 listener.handleNoTypeArguments(token); | 2776 listener.handleNoTypeArguments(token); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2817 // [begin] is now known to have type [BeginGroupToken]. | 2818 // [begin] is now known to have type [BeginGroupToken]. |
| 2818 token = parseExpression(token); | 2819 token = parseExpression(token); |
| 2819 if (!identical(begin.endGroup, token)) { | 2820 if (!identical(begin.endGroup, token)) { |
| 2820 reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next; | 2821 reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next; |
| 2821 token = begin.endGroup; | 2822 token = begin.endGroup; |
| 2822 } | 2823 } |
| 2823 listener.handleParenthesizedExpression(begin); | 2824 listener.handleParenthesizedExpression(begin); |
| 2824 return expect(')', token); | 2825 return expect(')', token); |
| 2825 } | 2826 } |
| 2826 | 2827 |
| 2827 Token parseThisExpression(Token token) { | 2828 Token parseThisExpression(Token token, IdentifierContext context) { |
| 2828 Token beginToken = token; | 2829 Token beginToken = token; |
| 2829 listener.handleThisExpression(token); | 2830 listener.handleThisExpression(token, context); |
| 2830 token = token.next; | 2831 token = token.next; |
| 2831 if (optional('(', token)) { | 2832 if (optional('(', token)) { |
| 2832 // Constructor forwarding. | 2833 // Constructor forwarding. |
| 2833 listener.handleNoTypeArguments(token); | 2834 listener.handleNoTypeArguments(token); |
| 2834 token = parseArguments(token); | 2835 token = parseArguments(token); |
| 2835 listener.endSend(beginToken, token); | 2836 listener.endSend(beginToken, token); |
| 2836 } | 2837 } |
| 2837 return token; | 2838 return token; |
| 2838 } | 2839 } |
| 2839 | 2840 |
| 2840 Token parseSuperExpression(Token token) { | 2841 Token parseSuperExpression(Token token, IdentifierContext context) { |
| 2841 Token beginToken = token; | 2842 Token beginToken = token; |
| 2842 listener.handleSuperExpression(token); | 2843 listener.handleSuperExpression(token, context); |
| 2843 token = token.next; | 2844 token = token.next; |
| 2844 if (optional('(', token)) { | 2845 if (optional('(', token)) { |
| 2845 // Super constructor. | 2846 // Super constructor. |
| 2846 listener.handleNoTypeArguments(token); | 2847 listener.handleNoTypeArguments(token); |
| 2847 token = parseArguments(token); | 2848 token = parseArguments(token); |
| 2848 listener.endSend(beginToken, token); | 2849 listener.endSend(beginToken, token); |
| 2849 } | 2850 } |
| 2850 return token; | 2851 return token; |
| 2851 } | 2852 } |
| 2852 | 2853 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2958 listener.beginLiteralMapEntry(token); | 2959 listener.beginLiteralMapEntry(token); |
| 2959 // Assume the listener rejects non-string keys. | 2960 // Assume the listener rejects non-string keys. |
| 2960 token = parseExpression(token); | 2961 token = parseExpression(token); |
| 2961 Token colon = token; | 2962 Token colon = token; |
| 2962 token = expect(':', token); | 2963 token = expect(':', token); |
| 2963 token = parseExpression(token); | 2964 token = parseExpression(token); |
| 2964 listener.endLiteralMapEntry(colon, token); | 2965 listener.endLiteralMapEntry(colon, token); |
| 2965 return token; | 2966 return token; |
| 2966 } | 2967 } |
| 2967 | 2968 |
| 2968 Token parseSendOrFunctionLiteral(Token token) { | 2969 Token parseSendOrFunctionLiteral(Token token, IdentifierContext context) { |
| 2969 if (!mayParseFunctionExpressions) { | 2970 if (!mayParseFunctionExpressions) { |
| 2970 return parseSend(token, IdentifierContext.expression); | 2971 return parseSend(token, context); |
| 2971 } | 2972 } |
| 2972 Token peek = peekAfterIfType(token); | 2973 Token peek = peekAfterIfType(token); |
| 2973 if (peek != null && | 2974 if (peek != null && |
| 2974 identical(peek.kind, IDENTIFIER_TOKEN) && | 2975 identical(peek.kind, IDENTIFIER_TOKEN) && |
| 2975 isFunctionDeclaration(peek.next)) { | 2976 isFunctionDeclaration(peek.next)) { |
| 2976 return parseFunctionExpression(token); | 2977 return parseFunctionExpression(token); |
| 2977 } else if (isFunctionDeclaration(token.next)) { | 2978 } else if (isFunctionDeclaration(token.next)) { |
| 2978 return parseFunctionExpression(token); | 2979 return parseFunctionExpression(token); |
| 2979 } else { | 2980 } else { |
| 2980 return parseSend(token, IdentifierContext.expression); | 2981 return parseSend(token, context); |
| 2981 } | 2982 } |
| 2982 } | 2983 } |
| 2983 | 2984 |
| 2984 bool isFunctionDeclaration(Token token) { | 2985 bool isFunctionDeclaration(Token token) { |
| 2985 if (optional('<', token)) { | 2986 if (optional('<', token)) { |
| 2986 BeginGroupToken begin = token; | 2987 BeginGroupToken begin = token; |
| 2987 if (begin.endGroup == null) return false; | 2988 if (begin.endGroup == null) return false; |
| 2988 token = begin.endGroup.next; | 2989 token = begin.endGroup.next; |
| 2989 } | 2990 } |
| 2990 if (optional('(', token)) { | 2991 if (optional('(', token)) { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3696 break; | 3697 break; |
| 3697 } | 3698 } |
| 3698 if (isRecoverable) { | 3699 if (isRecoverable) { |
| 3699 listener.handleRecoverableError(token, kind, arguments); | 3700 listener.handleRecoverableError(token, kind, arguments); |
| 3700 return null; | 3701 return null; |
| 3701 } else { | 3702 } else { |
| 3702 return listener.handleUnrecoverableError(token, kind, arguments); | 3703 return listener.handleUnrecoverableError(token, kind, arguments); |
| 3703 } | 3704 } |
| 3704 } | 3705 } |
| 3705 } | 3706 } |
| OLD | NEW |