| 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 /** |
| 2074 * Advance to the next token in the token stream. | 2099 * Advance to the next token in the token stream. |
| 2075 */ | 2100 */ |
| 2076 void _advance() { | 2101 void _advance() { |
| 2077 _currentToken = _currentToken.next; | 2102 _currentToken = _currentToken.next; |
| 2078 } | 2103 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2094 return; | 2119 return; |
| 2095 } | 2120 } |
| 2096 if (scalarValue < Character.MAX_VALUE) { | 2121 if (scalarValue < Character.MAX_VALUE) { |
| 2097 buffer.writeCharCode(scalarValue); | 2122 buffer.writeCharCode(scalarValue); |
| 2098 } else { | 2123 } else { |
| 2099 buffer.write(Character.toChars(scalarValue)); | 2124 buffer.write(Character.toChars(scalarValue)); |
| 2100 } | 2125 } |
| 2101 } | 2126 } |
| 2102 | 2127 |
| 2103 /** | 2128 /** |
| 2129 * Clone all token starting from the given [token] up to the end of the token |
| 2130 * stream, and return the first token in the new token stream. |
| 2131 */ |
| 2132 Token _cloneTokens(Token token) { |
| 2133 if (token == null) { |
| 2134 return null; |
| 2135 } |
| 2136 token = token is CommentToken ? token.parent : token; |
| 2137 Token head = new Token(TokenType.EOF, -1); |
| 2138 head.setNext(head); |
| 2139 Token current = head; |
| 2140 while (token.type != TokenType.EOF) { |
| 2141 Token clone = token.copy(); |
| 2142 current.setNext(clone); |
| 2143 current = clone; |
| 2144 token = token.next; |
| 2145 } |
| 2146 Token tail = new Token(TokenType.EOF, 0); |
| 2147 tail.setNext(tail); |
| 2148 current.setNext(tail); |
| 2149 return head.next; |
| 2150 } |
| 2151 |
| 2152 /** |
| 2104 * Return the content of a string with the given literal representation. The | 2153 * Return the content of a string with the given literal representation. The |
| 2105 * [lexeme] is the literal representation of the string. The flag [isFirst] is | 2154 * [lexeme] is the literal representation of the string. The flag [isFirst] is |
| 2106 * `true` if this is the first token in a string literal. The flag [isLast] is | 2155 * `true` if this is the first token in a string literal. The flag [isLast] is |
| 2107 * `true` if this is the last token in a string literal. | 2156 * `true` if this is the last token in a string literal. |
| 2108 */ | 2157 */ |
| 2109 String _computeStringValue(String lexeme, bool isFirst, bool isLast) { | 2158 String _computeStringValue(String lexeme, bool isFirst, bool isLast) { |
| 2110 StringLexemeHelper helper = new StringLexemeHelper(lexeme, isFirst, isLast); | 2159 StringLexemeHelper helper = new StringLexemeHelper(lexeme, isFirst, isLast); |
| 2111 int start = helper.start; | 2160 int start = helper.start; |
| 2112 int end = helper.end; | 2161 int end = helper.end; |
| 2113 bool stringEndsAfterStart = end >= start; | 2162 bool stringEndsAfterStart = end >= start; |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 lastToken = lastToken.next; | 2539 lastToken = lastToken.next; |
| 2491 } | 2540 } |
| 2492 // Inject these new tokens into the stream. | 2541 // Inject these new tokens into the stream. |
| 2493 Token previous = _currentToken.previous; | 2542 Token previous = _currentToken.previous; |
| 2494 lastToken.setNext(_currentToken); | 2543 lastToken.setNext(_currentToken); |
| 2495 previous.setNext(firstToken); | 2544 previous.setNext(firstToken); |
| 2496 _currentToken = firstToken; | 2545 _currentToken = firstToken; |
| 2497 } | 2546 } |
| 2498 | 2547 |
| 2499 /** | 2548 /** |
| 2549 * Return `true` if the current token could be the question mark in a |
| 2550 * condition expression. The current token is assumed to be a question mark. |
| 2551 */ |
| 2552 bool _isConditionalOperator() { |
| 2553 void parseOperation(Parser parser) { |
| 2554 parser.parseExpressionWithoutCascade(); |
| 2555 } |
| 2556 |
| 2557 Token token = _skip(_currentToken.next, parseOperation); |
| 2558 if (token == null || !_tokenMatches(token, TokenType.COLON)) { |
| 2559 return false; |
| 2560 } |
| 2561 token = _skip(token.next, parseOperation); |
| 2562 return token != null; |
| 2563 } |
| 2564 |
| 2565 /** |
| 2500 * Return `true` if the current token appears to be the beginning of a | 2566 * Return `true` if the current token appears to be the beginning of a |
| 2501 * function declaration. | 2567 * function declaration. |
| 2502 */ | 2568 */ |
| 2503 bool _isFunctionDeclaration() { | 2569 bool _isFunctionDeclaration() { |
| 2504 Keyword keyword = _currentToken.keyword; | 2570 Keyword keyword = _currentToken.keyword; |
| 2505 if (keyword == Keyword.VOID) { | 2571 if (keyword == Keyword.VOID) { |
| 2506 return true; | 2572 return true; |
| 2507 } | 2573 } |
| 2508 Token afterReturnType = _skipTypeName(_currentToken); | 2574 Token afterReturnType = _skipTypeName(_currentToken); |
| 2509 if (afterReturnType == null) { | 2575 if (afterReturnType == null) { |
| (...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3500 * mixinApplication ::= | 3566 * mixinApplication ::= |
| 3501 * type withClause implementsClause? ';' | 3567 * type withClause implementsClause? ';' |
| 3502 */ | 3568 */ |
| 3503 ClassTypeAlias _parseClassTypeAliasAfterName( | 3569 ClassTypeAlias _parseClassTypeAliasAfterName( |
| 3504 CommentAndMetadata commentAndMetadata, | 3570 CommentAndMetadata commentAndMetadata, |
| 3505 Token abstractKeyword, | 3571 Token abstractKeyword, |
| 3506 Token classKeyword, | 3572 Token classKeyword, |
| 3507 SimpleIdentifier className, | 3573 SimpleIdentifier className, |
| 3508 TypeParameterList typeParameters) { | 3574 TypeParameterList typeParameters) { |
| 3509 Token equals = _expect(TokenType.EQ); | 3575 Token equals = _expect(TokenType.EQ); |
| 3510 TypeName superclass = parseTypeName(); | 3576 TypeName superclass = parseTypeName(false); |
| 3511 WithClause withClause = null; | 3577 WithClause withClause = null; |
| 3512 if (_matchesKeyword(Keyword.WITH)) { | 3578 if (_matchesKeyword(Keyword.WITH)) { |
| 3513 withClause = parseWithClause(); | 3579 withClause = parseWithClause(); |
| 3514 } else { | 3580 } else { |
| 3515 _reportErrorForCurrentToken( | 3581 _reportErrorForCurrentToken( |
| 3516 ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.syntax]); | 3582 ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.syntax]); |
| 3517 } | 3583 } |
| 3518 ImplementsClause implementsClause = null; | 3584 ImplementsClause implementsClause = null; |
| 3519 if (_matchesKeyword(Keyword.IMPLEMENTS)) { | 3585 if (_matchesKeyword(Keyword.IMPLEMENTS)) { |
| 3520 implementsClause = parseImplementsClause(); | 3586 implementsClause = parseImplementsClause(); |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4573 * | 'var' | 4639 * | 'var' |
| 4574 * | type | 4640 * | type |
| 4575 */ | 4641 */ |
| 4576 FinalConstVarOrType _parseFinalConstVarOrType(bool optional) { | 4642 FinalConstVarOrType _parseFinalConstVarOrType(bool optional) { |
| 4577 Token keywordToken = null; | 4643 Token keywordToken = null; |
| 4578 TypeName type = null; | 4644 TypeName type = null; |
| 4579 Keyword keyword = _currentToken.keyword; | 4645 Keyword keyword = _currentToken.keyword; |
| 4580 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { | 4646 if (keyword == Keyword.FINAL || keyword == Keyword.CONST) { |
| 4581 keywordToken = getAndAdvance(); | 4647 keywordToken = getAndAdvance(); |
| 4582 if (_isTypedIdentifier(_currentToken)) { | 4648 if (_isTypedIdentifier(_currentToken)) { |
| 4583 type = parseTypeName(); | 4649 type = parseTypeName(false); |
| 4584 } else { | 4650 } else { |
| 4585 // Support `final/*=T*/ x;` | 4651 // Support `final/*=T*/ x;` |
| 4586 type = _parseOptionalTypeNameComment(); | 4652 type = _parseOptionalTypeNameComment(); |
| 4587 } | 4653 } |
| 4588 } else if (keyword == Keyword.VAR) { | 4654 } else if (keyword == Keyword.VAR) { |
| 4589 keywordToken = getAndAdvance(); | 4655 keywordToken = getAndAdvance(); |
| 4590 // Support `var/*=T*/ x;` | 4656 // Support `var/*=T*/ x;` |
| 4591 type = _parseOptionalTypeNameComment(); | 4657 type = _parseOptionalTypeNameComment(); |
| 4592 if (type != null) { | 4658 if (type != null) { |
| 4593 // Clear the keyword to prevent an error. | 4659 // Clear the keyword to prevent an error. |
| (...skipping 1616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6210 */ | 6276 */ |
| 6211 TypeArgumentList _parseOptionalTypeArguments() { | 6277 TypeArgumentList _parseOptionalTypeArguments() { |
| 6212 if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) { | 6278 if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) { |
| 6213 return parseTypeArgumentList(); | 6279 return parseTypeArgumentList(); |
| 6214 } | 6280 } |
| 6215 return null; | 6281 return null; |
| 6216 } | 6282 } |
| 6217 | 6283 |
| 6218 TypeName _parseOptionalTypeNameComment() { | 6284 TypeName _parseOptionalTypeNameComment() { |
| 6219 if (_injectGenericCommentTypeAssign()) { | 6285 if (_injectGenericCommentTypeAssign()) { |
| 6220 return _parseTypeName(); | 6286 return _parseTypeName(false); |
| 6221 } | 6287 } |
| 6222 return null; | 6288 return null; |
| 6223 } | 6289 } |
| 6224 | 6290 |
| 6225 /** | 6291 /** |
| 6226 * Parse a part directive. The [commentAndMetadata] is the metadata to be | 6292 * Parse a part directive. The [commentAndMetadata] is the metadata to be |
| 6227 * associated with the directive. Return the part or part-of directive that | 6293 * associated with the directive. Return the part or part-of directive that |
| 6228 * was parsed. | 6294 * was parsed. |
| 6229 * | 6295 * |
| 6230 * This method assumes that the current token matches `Keyword.PART`. | 6296 * 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) { | 6614 _currentToken.next.type.isRelationalOperator) { |
| 6549 Expression expression = new SuperExpression(getAndAdvance()); | 6615 Expression expression = new SuperExpression(getAndAdvance()); |
| 6550 Token operator = getAndAdvance(); | 6616 Token operator = getAndAdvance(); |
| 6551 return new BinaryExpression( | 6617 return new BinaryExpression( |
| 6552 expression, operator, parseBitwiseOrExpression()); | 6618 expression, operator, parseBitwiseOrExpression()); |
| 6553 } | 6619 } |
| 6554 Expression expression = parseBitwiseOrExpression(); | 6620 Expression expression = parseBitwiseOrExpression(); |
| 6555 Keyword keyword = _currentToken.keyword; | 6621 Keyword keyword = _currentToken.keyword; |
| 6556 if (keyword == Keyword.AS) { | 6622 if (keyword == Keyword.AS) { |
| 6557 Token asOperator = getAndAdvance(); | 6623 Token asOperator = getAndAdvance(); |
| 6558 return new AsExpression(expression, asOperator, parseTypeName()); | 6624 return new AsExpression(expression, asOperator, parseTypeName(true)); |
| 6559 } else if (keyword == Keyword.IS) { | 6625 } else if (keyword == Keyword.IS) { |
| 6560 Token isOperator = getAndAdvance(); | 6626 Token isOperator = getAndAdvance(); |
| 6561 Token notOperator = null; | 6627 Token notOperator = null; |
| 6562 if (_matches(TokenType.BANG)) { | 6628 if (_matches(TokenType.BANG)) { |
| 6563 notOperator = getAndAdvance(); | 6629 notOperator = getAndAdvance(); |
| 6564 } | 6630 } |
| 6565 return new IsExpression( | 6631 return new IsExpression( |
| 6566 expression, isOperator, notOperator, parseTypeName()); | 6632 expression, isOperator, notOperator, parseTypeName(true)); |
| 6567 } else if (_currentToken.type.isRelationalOperator) { | 6633 } else if (_currentToken.type.isRelationalOperator) { |
| 6568 Token operator = getAndAdvance(); | 6634 Token operator = getAndAdvance(); |
| 6569 return new BinaryExpression( | 6635 return new BinaryExpression( |
| 6570 expression, operator, parseBitwiseOrExpression()); | 6636 expression, operator, parseBitwiseOrExpression()); |
| 6571 } | 6637 } |
| 6572 return expression; | 6638 return expression; |
| 6573 } | 6639 } |
| 6574 | 6640 |
| 6575 /** | 6641 /** |
| 6576 * Parse a rethrow expression. Return the rethrow expression that was parsed. | 6642 * 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() { | 7061 Statement _parseTryStatement() { |
| 6996 Token tryKeyword = getAndAdvance(); | 7062 Token tryKeyword = getAndAdvance(); |
| 6997 Block body = _parseBlockChecked(); | 7063 Block body = _parseBlockChecked(); |
| 6998 List<CatchClause> catchClauses = <CatchClause>[]; | 7064 List<CatchClause> catchClauses = <CatchClause>[]; |
| 6999 Block finallyClause = null; | 7065 Block finallyClause = null; |
| 7000 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { | 7066 while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) { |
| 7001 Token onKeyword = null; | 7067 Token onKeyword = null; |
| 7002 TypeName exceptionType = null; | 7068 TypeName exceptionType = null; |
| 7003 if (_matchesString(_ON)) { | 7069 if (_matchesString(_ON)) { |
| 7004 onKeyword = getAndAdvance(); | 7070 onKeyword = getAndAdvance(); |
| 7005 exceptionType = parseTypeName(); | 7071 exceptionType = parseTypeName(false); |
| 7006 } | 7072 } |
| 7007 Token catchKeyword = null; | 7073 Token catchKeyword = null; |
| 7008 Token leftParenthesis = null; | 7074 Token leftParenthesis = null; |
| 7009 SimpleIdentifier exceptionParameter = null; | 7075 SimpleIdentifier exceptionParameter = null; |
| 7010 Token comma = null; | 7076 Token comma = null; |
| 7011 SimpleIdentifier stackTraceParameter = null; | 7077 SimpleIdentifier stackTraceParameter = null; |
| 7012 Token rightParenthesis = null; | 7078 Token rightParenthesis = null; |
| 7013 if (_matchesKeyword(Keyword.CATCH)) { | 7079 if (_matchesKeyword(Keyword.CATCH)) { |
| 7014 catchKeyword = getAndAdvance(); | 7080 catchKeyword = getAndAdvance(); |
| 7015 leftParenthesis = _expect(TokenType.OPEN_PAREN); | 7081 leftParenthesis = _expect(TokenType.OPEN_PAREN); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7085 TypeAlias typeAlias = | 7151 TypeAlias typeAlias = |
| 7086 _parseClassTypeAlias(commentAndMetadata, null, keyword); | 7152 _parseClassTypeAlias(commentAndMetadata, null, keyword); |
| 7087 _reportErrorForToken( | 7153 _reportErrorForToken( |
| 7088 ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword); | 7154 ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword); |
| 7089 return typeAlias; | 7155 return typeAlias; |
| 7090 } | 7156 } |
| 7091 } | 7157 } |
| 7092 return _parseFunctionTypeAlias(commentAndMetadata, keyword); | 7158 return _parseFunctionTypeAlias(commentAndMetadata, keyword); |
| 7093 } | 7159 } |
| 7094 | 7160 |
| 7095 TypeName _parseTypeName() { | 7161 TypeName _parseTypeName(bool inExpression) { |
| 7096 Identifier typeName; | 7162 Identifier typeName; |
| 7097 if (_matchesIdentifier()) { | 7163 if (_matchesIdentifier()) { |
| 7098 typeName = _parsePrefixedIdentifierUnchecked(); | 7164 typeName = _parsePrefixedIdentifierUnchecked(); |
| 7099 } else if (_matchesKeyword(Keyword.VAR)) { | 7165 } else if (_matchesKeyword(Keyword.VAR)) { |
| 7100 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); | 7166 _reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME); |
| 7101 typeName = new SimpleIdentifier(getAndAdvance()); | 7167 typeName = new SimpleIdentifier(getAndAdvance()); |
| 7102 } else { | 7168 } else { |
| 7103 typeName = _createSyntheticIdentifier(); | 7169 typeName = _createSyntheticIdentifier(); |
| 7104 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); | 7170 _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME); |
| 7105 } | 7171 } |
| 7106 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); | 7172 TypeArgumentList typeArguments = _parseOptionalTypeArguments(); |
| 7107 return new TypeName(typeName, typeArguments); | 7173 Token question = null; |
| 7174 if (enableNnbd && _matches(TokenType.QUESTION)) { |
| 7175 if (!inExpression || !_isConditionalOperator()) { |
| 7176 question = getAndAdvance(); |
| 7177 } |
| 7178 } |
| 7179 return new TypeName(typeName, typeArguments, question: question); |
| 7108 } | 7180 } |
| 7109 | 7181 |
| 7110 /** | 7182 /** |
| 7111 * Parse a type name. Return the type name that was parsed. | 7183 * Parse a type name. Return the type name that was parsed. |
| 7112 * | 7184 * |
| 7113 * This method assumes that the current token is an identifier. | 7185 * This method assumes that the current token is an identifier. |
| 7114 * | 7186 * |
| 7115 * type ::= | 7187 * type ::= |
| 7116 * qualified typeArguments? | 7188 * qualified typeArguments? |
| 7117 */ | 7189 */ |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7509 new Scanner(null, new SubSequenceReader(code, offset), listener); | 7581 new Scanner(null, new SubSequenceReader(code, offset), listener); |
| 7510 scanner.setSourceStart(1, 1); | 7582 scanner.setSourceStart(1, 1); |
| 7511 Token firstToken = scanner.tokenize(); | 7583 Token firstToken = scanner.tokenize(); |
| 7512 if (listener.errorReported) { | 7584 if (listener.errorReported) { |
| 7513 return null; | 7585 return null; |
| 7514 } | 7586 } |
| 7515 return firstToken; | 7587 return firstToken; |
| 7516 } | 7588 } |
| 7517 | 7589 |
| 7518 /** | 7590 /** |
| 7591 * Execute the given [parseOperation] in a temporary parser whose current |
| 7592 * token has been set to the given [startToken]. If the parse does not |
| 7593 * generate any errors or exceptions, then return the token following the |
| 7594 * matching portion of the token stream. Otherwise, return `null`. |
| 7595 * |
| 7596 * Note: This is an extremely inefficient way of testing whether the tokens in |
| 7597 * the token stream match a given production. It should not be used for |
| 7598 * production code. |
| 7599 */ |
| 7600 Token _skip(Token startToken, parseOperation(Parser parser)) { |
| 7601 BooleanErrorListener listener = new BooleanErrorListener(); |
| 7602 Parser parser = new Parser(_source, listener); |
| 7603 parser._currentToken = _cloneTokens(startToken); |
| 7604 parser._enableAssertInitializer = _enableAssertInitializer; |
| 7605 parser._enableNnbd = _enableNnbd; |
| 7606 parser._inAsync = _inAsync; |
| 7607 parser._inGenerator = _inGenerator; |
| 7608 parser._inInitializer = _inInitializer; |
| 7609 parser._inLoop = _inLoop; |
| 7610 parser._inSwitch = _inSwitch; |
| 7611 parser._parseAsync = _parseAsync; |
| 7612 parser._parseFunctionBodies = _parseFunctionBodies; |
| 7613 try { |
| 7614 parseOperation(parser); |
| 7615 } catch (exception) { |
| 7616 return null; |
| 7617 } |
| 7618 if (listener.errorReported) { |
| 7619 return null; |
| 7620 } |
| 7621 return parser._currentToken; |
| 7622 } |
| 7623 |
| 7624 /** |
| 7519 * Skips a block with all containing blocks. | 7625 * Skips a block with all containing blocks. |
| 7520 */ | 7626 */ |
| 7521 void _skipBlock() { | 7627 void _skipBlock() { |
| 7522 Token endToken = (_currentToken as BeginToken).endToken; | 7628 Token endToken = (_currentToken as BeginToken).endToken; |
| 7523 if (endToken == null) { | 7629 if (endToken == null) { |
| 7524 endToken = _currentToken.next; | 7630 endToken = _currentToken.next; |
| 7525 while (!identical(endToken, _currentToken)) { | 7631 while (!identical(endToken, _currentToken)) { |
| 7526 _currentToken = endToken; | 7632 _currentToken = endToken; |
| 7527 endToken = _currentToken.next; | 7633 endToken = _currentToken.next; |
| 7528 } | 7634 } |
| (...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9084 */ | 9190 */ |
| 9085 const ParserErrorCode(String name, String message, [String correction]) | 9191 const ParserErrorCode(String name, String message, [String correction]) |
| 9086 : super(name, message, correction); | 9192 : super(name, message, correction); |
| 9087 | 9193 |
| 9088 @override | 9194 @override |
| 9089 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; | 9195 ErrorSeverity get errorSeverity => ErrorSeverity.ERROR; |
| 9090 | 9196 |
| 9091 @override | 9197 @override |
| 9092 ErrorType get type => ErrorType.SYNTACTIC_ERROR; | 9198 ErrorType get type => ErrorType.SYNTACTIC_ERROR; |
| 9093 } | 9199 } |
| OLD | NEW |