| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.parser; | 5 library dart2js.parser; |
| 6 | 6 |
| 7 import '../options.dart' show ParserOptions; | 7 import '../options.dart' show ParserOptions; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../tokens/keyword.dart' show Keyword; | 9 import '../tokens/keyword.dart' show Keyword; |
| 10 import '../tokens/precedence.dart' show PrecedenceInfo; | 10 import '../tokens/precedence.dart' show PrecedenceInfo; |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 ++interfacesCount; | 732 ++interfacesCount; |
| 733 } while (optional(',', token)); | 733 } while (optional(',', token)); |
| 734 } | 734 } |
| 735 token = parseClassBody(token); | 735 token = parseClassBody(token); |
| 736 listener.endClassDeclaration( | 736 listener.endClassDeclaration( |
| 737 interfacesCount, begin, extendsKeyword, implementsKeyword, token); | 737 interfacesCount, begin, extendsKeyword, implementsKeyword, token); |
| 738 return token.next; | 738 return token.next; |
| 739 } | 739 } |
| 740 | 740 |
| 741 Token parseStringPart(Token token) { | 741 Token parseStringPart(Token token) { |
| 742 if (identical(token.kind, STRING_TOKEN)) { | 742 if (token.kind != STRING_TOKEN) { |
| 743 listener.handleStringPart(token); | 743 token = listener.expectedString(token); |
| 744 return token.next; | |
| 745 } else { | |
| 746 return listener.expected('string', token); | |
| 747 } | 744 } |
| 745 listener.handleStringPart(token); |
| 746 return token.next; |
| 748 } | 747 } |
| 749 | 748 |
| 750 Token parseIdentifier(Token token) { | 749 Token parseIdentifier(Token token) { |
| 751 if (!token.isIdentifier()) { | 750 if (!token.isIdentifier()) { |
| 752 token = listener.expectedIdentifier(token); | 751 token = listener.expectedIdentifier(token); |
| 753 } | 752 } |
| 754 listener.handleIdentifier(token); | 753 listener.handleIdentifier(token); |
| 755 return token.next; | 754 return token.next; |
| 756 } | 755 } |
| 757 | 756 |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 /// get foo async* { return null } | 1116 /// get foo async* { return null } |
| 1118 /// results in | 1117 /// results in |
| 1119 /// ['{', 'foo', 'get'] | 1118 /// ['{', 'foo', 'get'] |
| 1120 /// | 1119 /// |
| 1121 /// | 1120 /// |
| 1122 /// operator *(arg) => null; | 1121 /// operator *(arg) => null; |
| 1123 /// results in | 1122 /// results in |
| 1124 /// ['(', '*', 'operator'] | 1123 /// ['(', '*', 'operator'] |
| 1125 /// | 1124 /// |
| 1126 Link<Token> findMemberName(Token token) { | 1125 Link<Token> findMemberName(Token token) { |
| 1126 Link<Token> discardNative(Link<Token> tokens) { |
| 1127 if (!tokens.isEmpty && !tokens.tail.isEmpty && |
| 1128 tokens.tail.head.kind == STRING_TOKEN && |
| 1129 !tokens.tail.tail.isEmpty && |
| 1130 optional('native', tokens.tail.tail.head)) { |
| 1131 return tokens.tail.tail.tail.prepend(tokens.head); |
| 1132 } else { |
| 1133 return tokens; |
| 1134 } |
| 1135 } |
| 1136 |
| 1127 Link<Token> identifiers = const Link<Token>(); | 1137 Link<Token> identifiers = const Link<Token>(); |
| 1128 | 1138 |
| 1129 // `true` if 'get' has been seen. | 1139 // `true` if 'get' has been seen. |
| 1130 bool isGetter = false; | 1140 bool isGetter = false; |
| 1131 // `true` if an identifier has been seen after 'get'. | 1141 // `true` if an identifier has been seen after 'get'. |
| 1132 bool hasName = false; | 1142 bool hasName = false; |
| 1133 | 1143 |
| 1134 while (token.kind != EOF_TOKEN) { | 1144 while (token.kind != EOF_TOKEN) { |
| 1135 String value = token.stringValue; | 1145 String value = token.stringValue; |
| 1136 if (value == 'get') { | 1146 if (value == 'get') { |
| 1137 isGetter = true; | 1147 isGetter = true; |
| 1138 } else if (hasName && (value == 'sync' || value == 'async')) { | 1148 } else if (hasName && (value == 'sync' || value == 'async')) { |
| 1139 // Skip. | 1149 // Skip. |
| 1140 token = token.next; | 1150 token = token.next; |
| 1141 value = token.stringValue; | 1151 value = token.stringValue; |
| 1142 if (value == '*') { | 1152 if (value == '*') { |
| 1143 // Skip. | 1153 // Skip. |
| 1144 token = token.next; | 1154 token = token.next; |
| 1145 } | 1155 } |
| 1146 continue; | 1156 continue; |
| 1147 } else if (value == '(' || value == '{' || value == '=>') { | 1157 } else if (value == '(' || value == '{' || value == '=>') { |
| 1148 // A method. | 1158 // A method. |
| 1149 identifiers = identifiers.prepend(token); | 1159 identifiers = identifiers.prepend(token); |
| 1150 return identifiers; | 1160 return discardNative(identifiers); |
| 1151 } else if (value == '=' || value == ';' || value == ',') { | 1161 } else if (value == '=' || value == ';' || value == ',') { |
| 1152 // A field or abstract getter. | 1162 // A field or abstract getter. |
| 1153 identifiers = identifiers.prepend(token); | 1163 identifiers = identifiers.prepend(token); |
| 1154 return identifiers; | 1164 return discardNative(identifiers); |
| 1155 } else if (isGetter) { | 1165 } else if (isGetter) { |
| 1156 hasName = true; | 1166 hasName = true; |
| 1157 } | 1167 } |
| 1158 identifiers = identifiers.prepend(token); | 1168 identifiers = identifiers.prepend(token); |
| 1159 if (isValidTypeReference(token)) { | 1169 if (isValidTypeReference(token)) { |
| 1160 // type ... | 1170 // type ... |
| 1161 if (optional('.', token.next)) { | 1171 if (optional('.', token.next)) { |
| 1162 // type '.' ... | 1172 // type '.' ... |
| 1163 if (token.next.next.isIdentifier()) { | 1173 if (token.next.next.isIdentifier()) { |
| 1164 // type '.' identifier | 1174 // type '.' identifier |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 star = token; | 1724 star = token; |
| 1715 token = token.next; | 1725 token = token.next; |
| 1716 } else { | 1726 } else { |
| 1717 listener.reportError(async, MessageKind.INVALID_SYNC_MODIFIER); | 1727 listener.reportError(async, MessageKind.INVALID_SYNC_MODIFIER); |
| 1718 } | 1728 } |
| 1719 } | 1729 } |
| 1720 listener.handleAsyncModifier(async, star); | 1730 listener.handleAsyncModifier(async, star); |
| 1721 return token; | 1731 return token; |
| 1722 } | 1732 } |
| 1723 | 1733 |
| 1734 int statementDepth = 0; |
| 1724 Token parseStatement(Token token) { | 1735 Token parseStatement(Token token) { |
| 1736 if (statementDepth++ > 500) { |
| 1737 listener.reportError( |
| 1738 token, MessageKind.GENERIC, {'text': 'Stack overflow'}); |
| 1739 return listener.skipToEof(token); |
| 1740 } |
| 1741 Token result = parseStatementX(token); |
| 1742 statementDepth--; |
| 1743 return result; |
| 1744 } |
| 1745 |
| 1746 Token parseStatementX(Token token) { |
| 1725 final value = token.stringValue; | 1747 final value = token.stringValue; |
| 1726 if (identical(token.kind, IDENTIFIER_TOKEN)) { | 1748 if (identical(token.kind, IDENTIFIER_TOKEN)) { |
| 1727 return parseExpressionStatementOrDeclaration(token); | 1749 return parseExpressionStatementOrDeclaration(token); |
| 1728 } else if (identical(value, '{')) { | 1750 } else if (identical(value, '{')) { |
| 1729 return parseBlock(token); | 1751 return parseBlock(token); |
| 1730 } else if (identical(value, 'return')) { | 1752 } else if (identical(value, 'return')) { |
| 1731 return parseReturnStatement(token); | 1753 return parseReturnStatement(token); |
| 1732 } else if (identical(value, 'var') || identical(value, 'final')) { | 1754 } else if (identical(value, 'var') || identical(value, 'final')) { |
| 1733 return parseVariablesDeclaration(token); | 1755 return parseVariablesDeclaration(token); |
| 1734 } else if (identical(value, 'if')) { | 1756 } else if (identical(value, 'if')) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 return token; | 1936 return token; |
| 1915 } | 1937 } |
| 1916 | 1938 |
| 1917 Token parseExpressionStatement(Token token) { | 1939 Token parseExpressionStatement(Token token) { |
| 1918 listener.beginExpressionStatement(token); | 1940 listener.beginExpressionStatement(token); |
| 1919 token = parseExpression(token); | 1941 token = parseExpression(token); |
| 1920 listener.endExpressionStatement(token); | 1942 listener.endExpressionStatement(token); |
| 1921 return expectSemicolon(token); | 1943 return expectSemicolon(token); |
| 1922 } | 1944 } |
| 1923 | 1945 |
| 1946 int expressionDepth = 0; |
| 1924 Token parseExpression(Token token) { | 1947 Token parseExpression(Token token) { |
| 1925 return optional('throw', token) | 1948 if (expressionDepth++ > 500) { |
| 1949 listener.reportError( |
| 1950 token, MessageKind.GENERIC, {'text': 'Stack overflow'}); |
| 1951 return token.next; |
| 1952 } |
| 1953 Token result = optional('throw', token) |
| 1926 ? parseThrowExpression(token, true) | 1954 ? parseThrowExpression(token, true) |
| 1927 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true); | 1955 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true); |
| 1956 expressionDepth--; |
| 1957 return result; |
| 1928 } | 1958 } |
| 1929 | 1959 |
| 1930 Token parseExpressionWithoutCascade(Token token) { | 1960 Token parseExpressionWithoutCascade(Token token) { |
| 1931 return optional('throw', token) | 1961 return optional('throw', token) |
| 1932 ? parseThrowExpression(token, false) | 1962 ? parseThrowExpression(token, false) |
| 1933 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, false); | 1963 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, false); |
| 1934 } | 1964 } |
| 1935 | 1965 |
| 1936 Token parseConditionalExpressionRest(Token token) { | 1966 Token parseConditionalExpressionRest(Token token) { |
| 1937 assert(optional('?', token)); | 1967 assert(optional('?', token)); |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2859 } | 2889 } |
| 2860 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2890 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 2861 return expectSemicolon(token); | 2891 return expectSemicolon(token); |
| 2862 } | 2892 } |
| 2863 | 2893 |
| 2864 Token parseEmptyStatement(Token token) { | 2894 Token parseEmptyStatement(Token token) { |
| 2865 listener.handleEmptyStatement(token); | 2895 listener.handleEmptyStatement(token); |
| 2866 return expectSemicolon(token); | 2896 return expectSemicolon(token); |
| 2867 } | 2897 } |
| 2868 } | 2898 } |
| OLD | NEW |