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'; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 new MethodTrampoline(0, (Parser target) => target.parseReturnType()), | 83 new MethodTrampoline(0, (Parser target) => target.parseReturnType()), |
84 'parseSimpleIdentifier_0': new MethodTrampoline( | 84 'parseSimpleIdentifier_0': new MethodTrampoline( |
85 0, (Parser target) => target.parseSimpleIdentifier()), | 85 0, (Parser target) => target.parseSimpleIdentifier()), |
86 'parseStatement_0': | 86 'parseStatement_0': |
87 new MethodTrampoline(0, (Parser target) => target.parseStatement2()), | 87 new MethodTrampoline(0, (Parser target) => target.parseStatement2()), |
88 'parseStringLiteral_0': | 88 'parseStringLiteral_0': |
89 new MethodTrampoline(0, (Parser target) => target.parseStringLiteral()), | 89 new MethodTrampoline(0, (Parser target) => target.parseStringLiteral()), |
90 'parseTypeArgumentList_0': new MethodTrampoline( | 90 'parseTypeArgumentList_0': new MethodTrampoline( |
91 0, (Parser target) => target.parseTypeArgumentList()), | 91 0, (Parser target) => target.parseTypeArgumentList()), |
92 'parseTypeName_0': | 92 'parseTypeName_0': |
93 new MethodTrampoline(0, (Parser target) => target.parseTypeName()), | 93 new MethodTrampoline(0, (Parser target) => target.parseTypeName(false)), |
94 'parseTypeParameter_0': | 94 'parseTypeParameter_0': |
95 new MethodTrampoline(0, (Parser target) => target.parseTypeParameter()), | 95 new MethodTrampoline(0, (Parser target) => target.parseTypeParameter()), |
96 'parseTypeParameterList_0': new MethodTrampoline( | 96 'parseTypeParameterList_0': new MethodTrampoline( |
97 0, (Parser target) => target.parseTypeParameterList()), | 97 0, (Parser target) => target.parseTypeParameterList()), |
98 'parseWithClause_0': | 98 'parseWithClause_0': |
99 new MethodTrampoline(0, (Parser target) => target.parseWithClause()), | 99 new MethodTrampoline(0, (Parser target) => target.parseWithClause()), |
100 'advance_0': new MethodTrampoline(0, (Parser target) => target._advance()), | 100 'advance_0': new MethodTrampoline(0, (Parser target) => target._advance()), |
101 'appendScalarValue_5': new MethodTrampoline( | 101 'appendScalarValue_5': new MethodTrampoline( |
102 5, | 102 5, |
103 (Parser target, arg0, arg1, arg2, arg3, arg4) => | 103 (Parser target, arg0, arg1, arg2, arg3, arg4) => |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
676 */ | 676 */ |
677 int _errorListenerLock = 0; | 677 int _errorListenerLock = 0; |
678 | 678 |
679 /** | 679 /** |
680 * A flag indicating whether the parser is to parse asserts in the initializer | 680 * A flag indicating whether the parser is to parse asserts in the initializer |
681 * list of a constructor. | 681 * list of a constructor. |
682 */ | 682 */ |
683 bool _enableAssertInitializer = false; | 683 bool _enableAssertInitializer = false; |
684 | 684 |
685 /** | 685 /** |
686 * A flag indicating whether the parser is to parse the non-nullable modifier | |
687 * in type names. | |
688 */ | |
689 bool _enableNnbd = false; | |
690 | |
691 /** | |
686 * A flag indicating whether the parser is to parse the async support. | 692 * A flag indicating whether the parser is to parse the async support. |
687 */ | 693 */ |
688 bool _parseAsync = true; | 694 bool _parseAsync = true; |
689 | 695 |
690 /** | 696 /** |
691 * A flag indicating whether parser is to parse function bodies. | 697 * A flag indicating whether parser is to parse function bodies. |
692 */ | 698 */ |
693 bool _parseFunctionBodies = true; | 699 bool _parseFunctionBodies = true; |
694 | 700 |
695 /** | 701 /** |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
757 | 763 |
758 /** | 764 /** |
759 * Set whether the parser is to parse asserts in the initializer list of a | 765 * Set whether the parser is to parse asserts in the initializer list of a |
760 * constructor to match the given [enable] flag. | 766 * constructor to match the given [enable] flag. |
761 */ | 767 */ |
762 void set enableAssertInitializer(bool enable) { | 768 void set enableAssertInitializer(bool enable) { |
763 _enableAssertInitializer = enable; | 769 _enableAssertInitializer = enable; |
764 } | 770 } |
765 | 771 |
766 /** | 772 /** |
773 * Return `true` if the parser is to parse the non-nullable modifier in type | |
774 * names. | |
775 */ | |
776 bool get enableNnbd => _enableNnbd; | |
777 | |
778 /** | |
779 * Set whether the parser is to parse the non-nullable modifier in type names | |
780 * to match the given [enable] flag. | |
781 */ | |
782 void set enableNnbd(bool enable) { | |
783 _enableNnbd = enable; | |
784 } | |
785 | |
786 /** | |
767 * Return `true` if the current token is the first token of a return type that | 787 * Return `true` if the current token is the first token of a return type that |
768 * is followed by an identifier, possibly followed by a list of type | 788 * is followed by an identifier, possibly followed by a list of type |
769 * parameters, followed by a left-parenthesis. This is used by | 789 * parameters, followed by a left-parenthesis. This is used by |
770 * [_parseTypeAlias] to determine whether or not to parse a return type. | 790 * [_parseTypeAlias] to determine whether or not to parse a return type. |
771 */ | 791 */ |
772 @deprecated | 792 @deprecated |
773 bool get hasReturnTypeInTypeAlias { | 793 bool get hasReturnTypeInTypeAlias { |
774 Token next = _skipReturnType(_currentToken); | 794 Token next = _skipReturnType(_currentToken); |
775 if (next == null) { | 795 if (next == null) { |
776 return false; | 796 return false; |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1514 } | 1534 } |
1515 | 1535 |
1516 /** | 1536 /** |
1517 * Parse the name of a constructor. Return the constructor name that was | 1537 * Parse the name of a constructor. Return the constructor name that was |
1518 * parsed. | 1538 * parsed. |
1519 * | 1539 * |
1520 * constructorName: | 1540 * constructorName: |
1521 * type ('.' identifier)? | 1541 * type ('.' identifier)? |
1522 */ | 1542 */ |
1523 ConstructorName parseConstructorName() { | 1543 ConstructorName parseConstructorName() { |
1524 TypeName type = parseTypeName(); | 1544 TypeName type = parseTypeName(false); |
1525 Token period = null; | 1545 Token period = null; |
1526 SimpleIdentifier name = null; | 1546 SimpleIdentifier name = null; |
1527 if (_matches(TokenType.PERIOD)) { | 1547 if (_matches(TokenType.PERIOD)) { |
1528 period = getAndAdvance(); | 1548 period = getAndAdvance(); |
1529 name = parseSimpleIdentifier(); | 1549 name = parseSimpleIdentifier(); |
1530 } | 1550 } |
1531 return new ConstructorName(type, period, name); | 1551 return new ConstructorName(type, period, name); |
1532 } | 1552 } |
1533 | 1553 |
1534 /** | 1554 /** |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1630 * Parse a class extends clause. Return the class extends clause that was | 1650 * Parse a class extends clause. Return the class extends clause that was |
1631 * parsed. | 1651 * parsed. |
1632 * | 1652 * |
1633 * This method assumes that the current token matches `Keyword.EXTENDS`. | 1653 * This method assumes that the current token matches `Keyword.EXTENDS`. |
1634 * | 1654 * |
1635 * classExtendsClause ::= | 1655 * classExtendsClause ::= |
1636 * 'extends' type | 1656 * 'extends' type |
1637 */ | 1657 */ |
1638 ExtendsClause parseExtendsClause() { | 1658 ExtendsClause parseExtendsClause() { |
1639 Token keyword = getAndAdvance(); | 1659 Token keyword = getAndAdvance(); |
1640 TypeName superclass = parseTypeName(); | 1660 TypeName superclass = parseTypeName(false); |
1641 return new ExtendsClause(keyword, superclass); | 1661 return new ExtendsClause(keyword, superclass); |
1642 } | 1662 } |
1643 | 1663 |
1644 /** | 1664 /** |
1645 * Parse a list of formal parameters. Return the formal parameters that were | 1665 * Parse a list of formal parameters. Return the formal parameters that were |
1646 * parsed. | 1666 * parsed. |
1647 * | 1667 * |
1648 * formalParameterList ::= | 1668 * formalParameterList ::= |
1649 * '(' ')' | 1669 * '(' ')' |
1650 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')' | 1670 * | '(' normalFormalParameters (',' optionalFormalParameters)? ')' |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1711 * Parse an implements clause. Return the implements clause that was parsed. | 1731 * Parse an implements clause. Return the implements clause that was parsed. |
1712 * | 1732 * |
1713 * This method assumes that the current token matches `Keyword.IMPLEMENTS`. | 1733 * This method assumes that the current token matches `Keyword.IMPLEMENTS`. |
1714 * | 1734 * |
1715 * implementsClause ::= | 1735 * implementsClause ::= |
1716 * 'implements' type (',' type)* | 1736 * 'implements' type (',' type)* |
1717 */ | 1737 */ |
1718 ImplementsClause parseImplementsClause() { | 1738 ImplementsClause parseImplementsClause() { |
1719 Token keyword = getAndAdvance(); | 1739 Token keyword = getAndAdvance(); |
1720 List<TypeName> interfaces = <TypeName>[]; | 1740 List<TypeName> interfaces = <TypeName>[]; |
1721 interfaces.add(parseTypeName()); | 1741 interfaces.add(parseTypeName(false)); |
1722 while (_optional(TokenType.COMMA)) { | 1742 while (_optional(TokenType.COMMA)) { |
1723 interfaces.add(parseTypeName()); | 1743 interfaces.add(parseTypeName(false)); |
1724 } | 1744 } |
1725 return new ImplementsClause(keyword, interfaces); | 1745 return new ImplementsClause(keyword, interfaces); |
1726 } | 1746 } |
1727 | 1747 |
1728 /** | 1748 /** |
1729 * Parse a label. Return the label that was parsed. | 1749 * Parse a label. Return the label that was parsed. |
1730 * | 1750 * |
1731 * This method assumes that the current token matches an identifier and that | 1751 * This method assumes that the current token matches an identifier and that |
1732 * the following token matches `TokenType.COLON`. | 1752 * the following token matches `TokenType.COLON`. |
1733 * | 1753 * |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1815 } | 1835 } |
1816 SimpleIdentifier identifier = parseSimpleIdentifier(); | 1836 SimpleIdentifier identifier = parseSimpleIdentifier(); |
1817 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); | 1837 TypeParameterList typeParameters = _parseGenericMethodTypeParameters(); |
1818 if (_matches(TokenType.OPEN_PAREN)) { | 1838 if (_matches(TokenType.OPEN_PAREN)) { |
1819 FormalParameterList parameters = _parseFormalParameterListUnchecked(); | 1839 FormalParameterList parameters = _parseFormalParameterListUnchecked(); |
1820 if (thisKeyword == null) { | 1840 if (thisKeyword == null) { |
1821 if (holder.keyword != null) { | 1841 if (holder.keyword != null) { |
1822 _reportErrorForToken( | 1842 _reportErrorForToken( |
1823 ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword); | 1843 ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword); |
1824 } | 1844 } |
1845 Token question = null; | |
1846 if (enableNnbd && _matches(TokenType.QUESTION)) { | |
1847 question = getAndAdvance(); | |
1848 } | |
1825 return new FunctionTypedFormalParameter( | 1849 return new FunctionTypedFormalParameter( |
1826 commentAndMetadata.comment, | 1850 commentAndMetadata.comment, |
1827 commentAndMetadata.metadata, | 1851 commentAndMetadata.metadata, |
1828 holder.type, | 1852 holder.type, |
1829 new SimpleIdentifier(identifier.token, isDeclaration: true), | 1853 new SimpleIdentifier(identifier.token, isDeclaration: true), |
1830 typeParameters, | 1854 typeParameters, |
1831 parameters); | 1855 parameters, |
1856 question: question); | |
1832 } else { | 1857 } else { |
1833 return new FieldFormalParameter( | 1858 return new FieldFormalParameter( |
1834 commentAndMetadata.comment, | 1859 commentAndMetadata.comment, |
1835 commentAndMetadata.metadata, | 1860 commentAndMetadata.metadata, |
1836 holder.keyword, | 1861 holder.keyword, |
1837 holder.type, | 1862 holder.type, |
1838 thisKeyword, | 1863 thisKeyword, |
1839 period, | 1864 period, |
1840 identifier, | 1865 identifier, |
1841 typeParameters, | 1866 typeParameters, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1894 * Parse a return type. Return the return type that was parsed. | 1919 * Parse a return type. Return the return type that was parsed. |
1895 * | 1920 * |
1896 * returnType ::= | 1921 * returnType ::= |
1897 * 'void' | 1922 * 'void' |
1898 * | type | 1923 * | type |
1899 */ | 1924 */ |
1900 TypeName parseReturnType() { | 1925 TypeName parseReturnType() { |
1901 if (_currentToken.keyword == Keyword.VOID) { | 1926 if (_currentToken.keyword == Keyword.VOID) { |
1902 return new TypeName(new SimpleIdentifier(getAndAdvance()), null); | 1927 return new TypeName(new SimpleIdentifier(getAndAdvance()), null); |
1903 } else { | 1928 } else { |
1904 return parseTypeName(); | 1929 return parseTypeName(false); |
1905 } | 1930 } |
1906 } | 1931 } |
1907 | 1932 |
1908 /** | 1933 /** |
1909 * Parse a simple identifier. Return the simple identifier that was parsed. | 1934 * Parse a simple identifier. Return the simple identifier that was parsed. |
1910 * | 1935 * |
1911 * identifier ::= | 1936 * identifier ::= |
1912 * IDENTIFIER | 1937 * IDENTIFIER |
1913 */ | 1938 */ |
1914 SimpleIdentifier parseSimpleIdentifier({bool isDeclaration: false}) { | 1939 SimpleIdentifier parseSimpleIdentifier({bool isDeclaration: false}) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1984 * This method assumes that the current token matches `TokenType.LT`. | 2009 * This method assumes that the current token matches `TokenType.LT`. |
1985 * | 2010 * |
1986 * typeArguments ::= | 2011 * typeArguments ::= |
1987 * '<' typeList '>' | 2012 * '<' typeList '>' |
1988 * | 2013 * |
1989 * typeList ::= | 2014 * typeList ::= |
1990 * type (',' type)* | 2015 * type (',' type)* |
1991 */ | 2016 */ |
1992 TypeArgumentList parseTypeArgumentList() { | 2017 TypeArgumentList parseTypeArgumentList() { |
1993 Token leftBracket = getAndAdvance(); | 2018 Token leftBracket = getAndAdvance(); |
1994 List<TypeName> arguments = <TypeName>[parseTypeName()]; | 2019 List<TypeName> arguments = <TypeName>[parseTypeName(false)]; |
1995 while (_optional(TokenType.COMMA)) { | 2020 while (_optional(TokenType.COMMA)) { |
1996 arguments.add(parseTypeName()); | 2021 arguments.add(parseTypeName(false)); |
1997 } | 2022 } |
1998 Token rightBracket = _expectGt(); | 2023 Token rightBracket = _expectGt(); |
1999 return new TypeArgumentList(leftBracket, arguments, rightBracket); | 2024 return new TypeArgumentList(leftBracket, arguments, rightBracket); |
2000 } | 2025 } |
2001 | 2026 |
2002 /** | 2027 /** |
2003 * Parse a type name. Return the type name that was parsed. | 2028 * Parse a type name. Return the type name that was parsed. |
2004 * | 2029 * |
2005 * type ::= | 2030 * type ::= |
2006 * qualified typeArguments? | 2031 * qualified typeArguments? |
2007 */ | 2032 */ |
2008 TypeName parseTypeName() { | 2033 TypeName parseTypeName(bool inExpression) { |
2009 TypeName realType = _parseTypeName(); | 2034 TypeName realType = _parseTypeName(inExpression); |
2010 // If this is followed by a generic method type comment, allow the comment | 2035 // If this is followed by a generic method type comment, allow the comment |
2011 // type to replace the real type name. | 2036 // type to replace the real type name. |
2012 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to | 2037 // TODO(jmesserly): this feels like a big hammer. Can we restrict it to |
2013 // only work inside generic methods? | 2038 // only work inside generic methods? |
2014 TypeName typeFromComment = _parseOptionalTypeNameComment(); | 2039 TypeName typeFromComment = _parseOptionalTypeNameComment(); |
2015 return typeFromComment ?? realType; | 2040 return typeFromComment ?? realType; |
2016 } | 2041 } |
2017 | 2042 |
2018 /** | 2043 /** |
2019 * Parse a type parameter. Return the type parameter that was parsed. | 2044 * Parse a type parameter. Return the type parameter that was parsed. |
2020 * | 2045 * |
2021 * typeParameter ::= | 2046 * typeParameter ::= |
2022 * metadata name ('extends' bound)? | 2047 * metadata name ('extends' bound)? |
2023 */ | 2048 */ |
2024 TypeParameter parseTypeParameter() { | 2049 TypeParameter parseTypeParameter() { |
2025 CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata(); | 2050 CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata(); |
2026 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); | 2051 SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true); |
2027 if (_matchesKeyword(Keyword.EXTENDS)) { | 2052 if (_matchesKeyword(Keyword.EXTENDS)) { |
2028 Token keyword = getAndAdvance(); | 2053 Token keyword = getAndAdvance(); |
2029 TypeName bound = parseTypeName(); | 2054 TypeName bound = parseTypeName(false); |
2030 return new TypeParameter(commentAndMetadata.comment, | 2055 return new TypeParameter(commentAndMetadata.comment, |
2031 commentAndMetadata.metadata, name, keyword, bound); | 2056 commentAndMetadata.metadata, name, keyword, bound); |
2032 } | 2057 } |
2033 return new TypeParameter(commentAndMetadata.comment, | 2058 return new TypeParameter(commentAndMetadata.comment, |
2034 commentAndMetadata.metadata, name, null, null); | 2059 commentAndMetadata.metadata, name, null, null); |
2035 } | 2060 } |
2036 | 2061 |
2037 /** | 2062 /** |
2038 * Parse a list of type parameters. Return the list of type parameters that | 2063 * Parse a list of type parameters. Return the list of type parameters that |
2039 * were parsed. | 2064 * were parsed. |
(...skipping 16 matching lines...) Expand all Loading... | |
2056 /** | 2081 /** |
2057 * Parse a with clause. Return the with clause that was parsed. | 2082 * Parse a with clause. Return the with clause that was parsed. |
2058 * | 2083 * |
2059 * This method assumes that the current token matches `Keyword.WITH`. | 2084 * This method assumes that the current token matches `Keyword.WITH`. |
2060 * | 2085 * |
2061 * withClause ::= | 2086 * withClause ::= |
2062 * 'with' typeName (',' typeName)* | 2087 * 'with' typeName (',' typeName)* |
2063 */ | 2088 */ |
2064 WithClause parseWithClause() { | 2089 WithClause parseWithClause() { |
2065 Token withKeyword = getAndAdvance(); | 2090 Token withKeyword = getAndAdvance(); |
2066 List<TypeName> types = <TypeName>[parseTypeName()]; | 2091 List<TypeName> types = <TypeName>[parseTypeName(false)]; |
2067 while (_optional(TokenType.COMMA)) { | 2092 while (_optional(TokenType.COMMA)) { |
2068 types.add(parseTypeName()); | 2093 types.add(parseTypeName(false)); |
2069 } | 2094 } |
2070 return new WithClause(withKeyword, types); | 2095 return new WithClause(withKeyword, types); |
2071 } | 2096 } |
2072 | 2097 |
2073 /** | 2098 /** |
2099 * Return `true` if the current token could be the question mark in a | |
2100 * condition expression. The current token is assumed to be a question mark. | |
2101 */ | |
2102 bool _isConditionalOperator() { | |
2103 void parseFunction(Parser parser) { | |
scheglov
2016/09/16 15:29:38
The name looks like this function will parse a fun
Brian Wilkerson
2016/09/16 15:47:35
Yes it does. :-) I've renamed it to 'parseOperatio
| |
2104 parser.parseExpressionWithoutCascade(); | |
2105 } | |
2106 | |
2107 Token token = _skip(_currentToken.next, parseFunction); | |
2108 if (token == null || !_tokenMatches(token, TokenType.COLON)) { | |
2109 return false; | |
2110 } | |
2111 token = _skip(token.next, parseFunction); | |
scheglov
2016/09/16 15:29:38
Out of curiosity - what is an example when just se
Brian Wilkerson
2016/09/16 15:47:35
I'm concerned about cases like
if (foo is Bar?
| |
2112 return token != null; | |
2113 } | |
2114 | |
2115 /** | |
2074 * Advance to the next token in the token stream. | 2116 * Advance to the next token in the token stream. |
2075 */ | 2117 */ |
2076 void _advance() { | 2118 void _advance() { |
2077 _currentToken = _currentToken.next; | 2119 _currentToken = _currentToken.next; |
2078 } | 2120 } |
2079 | 2121 |
2080 /** | 2122 /** |
2081 * Append the character equivalent of the given [scalarValue] to the given | 2123 * Append the character equivalent of the given [scalarValue] to the given |
2082 * [builder]. Use the [startIndex] and [endIndex] to report an error, and | 2124 * [builder]. Use the [startIndex] and [endIndex] to report an error, and |
2083 * don't append anything to the builder, if the scalar value is invalid. The | 2125 * don't append anything to the builder, if the scalar value is invalid. The |
(...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3500 * mixinApplication ::= | 3542 * mixinApplication ::= |
3501 * type withClause implementsClause? ';' | 3543 * type withClause implementsClause? ';' |
3502 */ | 3544 */ |
3503 ClassTypeAlias _parseClassTypeAliasAfterName( | 3545 ClassTypeAlias _parseClassTypeAliasAfterName( |
3504 CommentAndMetadata commentAndMetadata, | 3546 CommentAndMetadata commentAndMetadata, |
3505 Token abstractKeyword, | 3547 Token abstractKeyword, |
3506 Token classKeyword, | 3548 Token classKeyword, |
3507 SimpleIdentifier className, | 3549 SimpleIdentifier className, |
3508 TypeParameterList typeParameters) { | 3550 TypeParameterList typeParameters) { |
3509 Token equals = _expect(TokenType.EQ); | 3551 Token equals = _expect(TokenType.EQ); |
3510 TypeName superclass = parseTypeName(); | 3552 TypeName superclass = parseTypeName(false); |
3511 WithClause withClause = null; | 3553 WithClause withClause = null; |
3512 if (_matchesKeyword(Keyword.WITH)) { | 3554 if (_matchesKeyword(Keyword.WITH)) { |
3513 withClause = parseWithClause(); | 3555 withClause = parseWithClause(); |
3514 } else { | 3556 } else { |
3515 _reportErrorForCurrentToken( | 3557 _reportErrorForCurrentToken( |
3516 ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.syntax]); | 3558 ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.syntax]); |
3517 } | 3559 } |
3518 ImplementsClause implementsClause = null; | 3560 ImplementsClause implementsClause = null; |
3519 if (_matchesKeyword(Keyword.IMPLEMENTS)) { | 3561 if (_matchesKeyword(Keyword.IMPLEMENTS)) { |
3520 implementsClause = parseImplementsClause(); | 3562 implementsClause = parseImplementsClause(); |
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4573 * | 'var' | 4615 * | 'var' |
4574 * | type | 4616 * | type |
4575 */ | 4617 */ |
4576 FinalConstVarOrType _parseFinalConstVarOrType(bool optional) { | 4618 FinalConstVarOrType _parseFinalConstVarOrType(bool optional) { |
4577 Token keywordToken = null; | 4619 Token keywordToken = null; |
4578 TypeName type = null; | 4620 TypeName type = null; |
4579 Keyword keyword = _currentToken.keyword; | 4621 Keyword keyword = _currentToken.keyword; |
4580 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { | 4622 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { |
4581 keywordToken = getAndAdvance(); | 4623 keywordToken = getAndAdvance(); |
4582 if (_isTypedIdentifier(_currentToken)) { | 4624 if (_isTypedIdentifier(_currentToken)) { |
4583 type = parseTypeName(); | 4625 type = parseTypeName(false); |
4584 } else { | 4626 } else { |
4585 // Support `final/*=T*/ x;` | 4627 // Support `final/*=T*/ x;` |
4586 type = _parseOptionalTypeNameComment(); | 4628 type = _parseOptionalTypeNameComment(); |
4587 } | 4629 } |
4588 } else if (keyword == Keyword.VAR) { | 4630 } else if (keyword == Keyword.VAR) { |
4589 keywordToken = getAndAdvance(); | 4631 keywordToken = getAndAdvance(); |
4590 // Support `var/*=T*/ x;` | 4632 // Support `var/*=T*/ x;` |
4591 type = _parseOptionalTypeNameComment(); | 4633 type = _parseOptionalTypeNameComment(); |
4592 if (type != null) { | 4634 if (type != null) { |
4593 // Clear the keyword to prevent an error. | 4635 // Clear the keyword to prevent an error. |
(...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6210 */ | 6252 */ |
6211 TypeArgumentList _parseOptionalTypeArguments() { | 6253 TypeArgumentList _parseOptionalTypeArguments() { |
6212 if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) { | 6254 if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) { |
6213 return parseTypeArgumentList(); | 6255 return parseTypeArgumentList(); |
6214 } | 6256 } |
6215 return null; | 6257 return null; |
6216 } | 6258 } |
6217 | 6259 |
6218 TypeName _parseOptionalTypeNameComment() { | 6260 TypeName _parseOptionalTypeNameComment() { |
6219 if (_injectGenericCommentTypeAssign()) { | 6261 if (_injectGenericCommentTypeAssign()) { |
6220 return _parseTypeName(); | 6262 return _parseTypeName(false); |
6221 } | 6263 } |
6222 return null; | 6264 return null; |
6223 } | 6265 } |
6224 | 6266 |
6225 /** | 6267 /** |
6226 * Parse a part directive. The [commentAndMetadata] is the metadata to be | 6268 * Parse a part directive. The [commentAndMetadata] is the metadata to be |
6227 * associated with the directive. Return the part or part-of directive that | 6269 * associated with the directive. Return the part or part-of directive that |
6228 * was parsed. | 6270 * was parsed. |
6229 * | 6271 * |
6230 * This method assumes that the current token matches `Keyword.PART`. | 6272 * This method assumes that the current token matches `Keyword.PART`. |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6548 _currentToken.next.type.isRelationalOperator) { | 6590 _currentToken.next.type.isRelationalOperator) { |
6549 Expression expression = new SuperExpression(getAndAdvance()); | 6591 Expression expression = new SuperExpression(getAndAdvance()); |
6550 Token operator = getAndAdvance(); | 6592 Token operator = getAndAdvance(); |
6551 return new BinaryExpression( | 6593 return new BinaryExpression( |
6552 expression, operator, parseBitwiseOrExpression()); | 6594 expression, operator, parseBitwiseOrExpression()); |
6553 } | 6595 } |
6554 Expression expression = parseBitwiseOrExpression(); | 6596 Expression expression = parseBitwiseOrExpression(); |
6555 Keyword keyword = _currentToken.keyword; | 6597 Keyword keyword = _currentToken.keyword; |
6556 if (keyword == Keyword.AS) { | 6598 if (keyword == Keyword.AS) { |
6557 Token asOperator = getAndAdvance(); | 6599 Token asOperator = getAndAdvance(); |
6558 return new AsExpression(expression, asOperator, parseTypeName()); | 6600 return new AsExpression(expression, asOperator, parseTypeName(true)); |
6559 } else if (keyword == Keyword.IS) { | 6601 } else if (keyword == Keyword.IS) { |
6560 Token isOperator = getAndAdvance(); | 6602 Token isOperator = getAndAdvance(); |
6561 Token notOperator = null; | 6603 Token notOperator = null; |
6562 if (_matches(TokenType.BANG)) { | 6604 if (_matches(TokenType.BANG)) { |
6563 notOperator = getAndAdvance(); | 6605 notOperator = getAndAdvance(); |
6564 } | 6606 } |
6565 return new IsExpression( | 6607 return new IsExpression( |
6566 expression, isOperator, notOperator, parseTypeName()); | 6608 expression, isOperator, notOperator, parseTypeName(true)); |
6567 } else if (_currentToken.type.isRelationalOperator) { | 6609 } else if (_currentToken.type.isRelationalOperator) { |
6568 Token operator = getAndAdvance(); | 6610 Token operator = getAndAdvance(); |
6569 return new BinaryExpression( | 6611 return new BinaryExpression( |
6570 expression, operator, parseBitwiseOrExpression()); | 6612 expression, operator, parseBitwiseOrExpression()); |
6571 } | 6613 } |
6572 return expression; | 6614 return expression; |
6573 } | 6615 } |
6574 | 6616 |
6575 /** | 6617 /** |
6576 * Parse a rethrow expression. Return the rethrow expression that was parsed. | 6618 * Parse a rethrow expression. Return the rethrow expression that was parsed. |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6995 Statement _parseTryStatement() { | 7037 Statement _parseTryStatement() { |
6996 Token tryKeyword = getAndAdvance(); | 7038 Token tryKeyword = getAndAdvance(); |
6997 Block body = _parseBlockChecked(); | 7039 Block body = _parseBlockChecked(); |
6998 List<CatchClause> catchClauses = <CatchClause>[]; | 7040 List<CatchClause> catchClauses = <CatchClause>[]; |
6999 Block finallyClause = null; | 7041 Block finallyClause = null; |
7000 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { | 7042 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { |
7001 Token onKeyword = null; | 7043 Token onKeyword = null; |
7002 TypeName exceptionType = null; | 7044 TypeName exceptionType = null; |
7003 if (_matchesString(_ON)) { | 7045 if (_matchesString(_ON)) { |
7004 onKeyword = getAndAdvance(); | 7046 onKeyword = getAndAdvance(); |
7005 exceptionType = parseTypeName(); | 7047 exceptionType = parseTypeName(false); |
7006 } | 7048 } |
7007 Token catchKeyword = null; | 7049 Token catchKeyword = null; |
7008 Token leftParenthesis = null; | 7050 Token leftParenthesis = null; |
7009 SimpleIdentifier exceptionParameter = null; | 7051 SimpleIdentifier exceptionParameter = null; |
7010 Token comma = null; | 7052 Token comma = null; |
7011 SimpleIdentifier stackTraceParameter = null; | 7053 SimpleIdentifier stackTraceParameter = null; |
7012 Token rightParenthesis = null; | 7054 Token rightParenthesis = null; |
7013 if (_matchesKeyword(Keyword.CATCH)) { | 7055 if (_matchesKeyword(Keyword.CATCH)) { |
7014 catchKeyword = getAndAdvance(); | 7056 catchKeyword = getAndAdvance(); |
7015 leftParenthesis = _expect(TokenType.OPEN_PAREN); | 7057 leftParenthesis = _expect(TokenType.OPEN_PAREN); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7085 TypeAlias typeAlias = | 7127 TypeAlias typeAlias = |
7086 _parseClassTypeAlias(commentAndMetadata, null, keyword); | 7128 _parseClassTypeAlias(commentAndMetadata, null, keyword); |
7087 _reportErrorForToken( | 7129 _reportErrorForToken( |
7088 ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword); | 7130 ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword); |
7089 return typeAlias; | 7131 return typeAlias; |
7090 } | 7132 } |
7091 } | 7133 } |
7092 return _parseFunctionTypeAlias(commentAndMetadata, keyword); | 7134 return _parseFunctionTypeAlias(commentAndMetadata, keyword); |
7093 } | 7135 } |
7094 | 7136 |
7095 TypeName _parseTypeName() { | 7137 TypeName _parseTypeName(bool inExpression) { |
7096 Identifier typeName; | 7138 Identifier typeName; |
7097 if (_matchesIdentifier()) { | 7139 if (_matchesIdentifier()) { |
7098 typeName = _parsePrefixedIdentifierUnchecked(); | 7140 typeName = _parsePrefixedIdentifierUnchecked(); |
7099 } else if (_matchesKeyword(Keyword.VAR)) { | 7141 } else if (_matchesKeyword(Keyword.VAR)) { |
7100 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); | 7142 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); |
7101 typeName = new SimpleIdentifier(getAndAdvance()); | 7143 typeName = new SimpleIdentifier(getAndAdvance()); |
7102 } else { | 7144 } else { |
7103 typeName = _createSyntheticIdentifier(); | 7145 typeName = _createSyntheticIdentifier(); |
7104 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); | 7146 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); |
7105 } | 7147 } |
7106 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7148 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
7107 return new TypeName(typeName, typeArguments); | 7149 Token question = null; |
7150 if (enableNnbd && _matches(TokenType.QUESTION)) { | |
7151 if (!inExpression || !_isConditionalOperator()) { | |
7152 question = getAndAdvance(); | |
7153 } | |
7154 } | |
7155 return new TypeName(typeName, typeArguments, question: question); | |
7108 } | 7156 } |
7109 | 7157 |
7110 /** | 7158 /** |
7159 * Execute the given [parseFunction] in a temporary parser whose current token | |
7160 * has been set to the given [startToken]. If the parse does not generate any | |
7161 * errors or exceptions, then return the token following the matching portion | |
7162 * of the token stream. Otherwise, return `null`. | |
7163 * | |
7164 * Note: This is an extremely inefficient way of testing whether the tokens in | |
7165 * the token stream match a given production. It should not be used for | |
7166 * production code. | |
7167 */ | |
7168 Token _skip(Token startToken, parseFunction(Parser parser)) { | |
7169 // TODO(brianwilkerson) We need to create a copy of the token stream from | |
7170 // the current token onward so that token re-writes don't change the | |
7171 // behavior of the current parser. | |
7172 BooleanErrorListener listener = new BooleanErrorListener(); | |
7173 Parser parser = new Parser(_source, listener); | |
7174 parser._currentToken = startToken; | |
7175 parser._enableAssertInitializer = _enableAssertInitializer; | |
7176 parser._enableNnbd = _enableNnbd; | |
7177 parser._inAsync = _inAsync; | |
7178 parser._inGenerator = _inGenerator; | |
7179 parser._inInitializer = _inInitializer; | |
7180 parser._inLoop = _inLoop; | |
7181 parser._inSwitch = _inSwitch; | |
7182 parser._parseAsync = _parseAsync; | |
7183 parser._parseFunctionBodies = _parseFunctionBodies; | |
7184 try { | |
7185 parseFunction(parser); | |
7186 } catch (exception) { | |
7187 return null; | |
7188 } | |
7189 if (listener.errorReported) { | |
7190 return null; | |
7191 } | |
7192 return parser._currentToken; | |
7193 } | |
7194 | |
7195 /** | |
7111 * Parse a type name. Return the type name that was parsed. | 7196 * Parse a type name. Return the type name that was parsed. |
7112 * | 7197 * |
7113 * This method assumes that the current token is an identifier. | 7198 * This method assumes that the current token is an identifier. |
7114 * | 7199 * |
7115 * type ::= | 7200 * type ::= |
7116 * qualified typeArguments? | 7201 * qualified typeArguments? |
7117 */ | 7202 */ |
7118 TypeName _parseTypeNameAfterIdentifier() { | 7203 TypeName _parseTypeNameAfterIdentifier() { |
7119 Identifier typeName = _parsePrefixedIdentifierUnchecked(); | 7204 Identifier typeName = _parsePrefixedIdentifierUnchecked(); |
7120 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7205 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
(...skipping 1963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9084 */ | 9169 */ |
9085 const ParserErrorCode(String name, String message, [String correction]) | 9170 const ParserErrorCode(String name, String message, [String correction]) |
9086 : super(name, message, correction); | 9171 : super(name, message, correction); |
9087 | 9172 |
9088 @override | 9173 @override |
9089 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; | 9174 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; |
9090 | 9175 |
9091 @override | 9176 @override |
9092 ErrorType get type => ErrorType.SYNTACTIC_ERROR; | 9177 ErrorType get type => ErrorType.SYNTACTIC_ERROR; |
9093 } | 9178 } |
OLD | NEW |