Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: pkg/analyzer/lib/src/generated/parser.dart

Issue 2342383002: Initial support for the NNBD proposal (Closed)
Patch Set: Addressed comments and added tests Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/ast/utilities.dart ('k') | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698