Chromium Code Reviews| 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 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 token = parseReturnTypeOpt(token); | 456 token = parseReturnTypeOpt(token); |
| 457 Token thisKeyword = null; | 457 Token thisKeyword = null; |
| 458 if (optional('this', token)) { | 458 if (optional('this', token)) { |
| 459 thisKeyword = token; | 459 thisKeyword = token; |
| 460 // TODO(ahe): Validate field initializers are only used in | 460 // TODO(ahe): Validate field initializers are only used in |
| 461 // constructors, and not for function-typed arguments. | 461 // constructors, and not for function-typed arguments. |
| 462 token = expect('.', token.next); | 462 token = expect('.', token.next); |
| 463 } | 463 } |
| 464 token = parseIdentifier(token); | 464 token = parseIdentifier(token); |
| 465 if (optional('(', token)) { | 465 if (optional('(', token)) { |
| 466 listener.handleNoTypeVariables(token); | |
| 467 token = parseFormalParameters(token); | |
| 468 listener.handleFunctionTypedFormalParameter(token); | |
| 469 } else if (enableGenericMethodSyntax && optional('<', token)) { | |
| 470 token = parseTypeVariablesOpt(token); | |
| 466 token = parseFormalParameters(token); | 471 token = parseFormalParameters(token); |
| 467 listener.handleFunctionTypedFormalParameter(token); | 472 listener.handleFunctionTypedFormalParameter(token); |
| 468 } | 473 } |
| 469 String value = token.stringValue; | 474 String value = token.stringValue; |
| 470 if ((identical('=', value)) || (identical(':', value))) { | 475 if ((identical('=', value)) || (identical(':', value))) { |
| 471 // TODO(ahe): Validate that these are only used for optional parameters. | 476 // TODO(ahe): Validate that these are only used for optional parameters. |
| 472 Token equal = token; | 477 Token equal = token; |
| 473 token = parseExpression(token.next); | 478 token = parseExpression(token.next); |
| 474 listener.handleValuedFormalParameter(equal, token); | 479 listener.handleValuedFormalParameter(equal, token); |
| 475 if (type.isRequired) { | 480 if (type.isRequired) { |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 Token expect(String string, Token token) { | 765 Token expect(String string, Token token) { |
| 761 if (!identical(string, token.stringValue)) { | 766 if (!identical(string, token.stringValue)) { |
| 762 return listener.expected(string, token); | 767 return listener.expected(string, token); |
| 763 } | 768 } |
| 764 return token.next; | 769 return token.next; |
| 765 } | 770 } |
| 766 | 771 |
| 767 Token parseTypeVariable(Token token) { | 772 Token parseTypeVariable(Token token) { |
| 768 listener.beginTypeVariable(token); | 773 listener.beginTypeVariable(token); |
| 769 token = parseIdentifier(token); | 774 token = parseIdentifier(token); |
| 770 if (optional('extends', token)) { | 775 Token extendsOrSuper = null; |
| 776 if (optional('extends', token) || | |
| 777 (enableGenericMethodSyntax && optional('super', token))) { | |
| 778 extendsOrSuper = token; | |
| 771 token = parseType(token.next); | 779 token = parseType(token.next); |
| 772 } else { | 780 } else { |
| 773 listener.handleNoType(token); | 781 listener.handleNoType(token); |
| 774 } | 782 } |
| 775 listener.endTypeVariable(token); | 783 listener.endTypeVariable(token, extendsOrSuper); |
| 776 return token; | 784 return token; |
| 777 } | 785 } |
| 778 | 786 |
| 779 /** | 787 /** |
| 780 * Returns true if the stringValue of the [token] is [value]. | 788 * Returns true if the stringValue of the [token] is [value]. |
| 781 */ | 789 */ |
| 782 bool optional(String value, Token token) { | 790 bool optional(String value, Token token) { |
| 783 return identical(value, token.stringValue); | 791 return identical(value, token.stringValue); |
| 784 } | 792 } |
| 785 | 793 |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1838 int afterIdKind = afterId.kind; | 1846 int afterIdKind = afterId.kind; |
| 1839 if (identical(afterIdKind, EQ_TOKEN) || | 1847 if (identical(afterIdKind, EQ_TOKEN) || |
| 1840 identical(afterIdKind, SEMICOLON_TOKEN) || | 1848 identical(afterIdKind, SEMICOLON_TOKEN) || |
| 1841 identical(afterIdKind, COMMA_TOKEN)) { | 1849 identical(afterIdKind, COMMA_TOKEN)) { |
| 1842 // We are looking at "type identifier" followed by '=', ';', ','. | 1850 // We are looking at "type identifier" followed by '=', ';', ','. |
| 1843 return parseVariablesDeclaration(token); | 1851 return parseVariablesDeclaration(token); |
| 1844 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { | 1852 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { |
| 1845 // We are looking at "type identifier '('". | 1853 // We are looking at "type identifier '('". |
| 1846 BeginGroupToken beginParen = afterId; | 1854 BeginGroupToken beginParen = afterId; |
| 1847 Token endParen = beginParen.endGroup; | 1855 Token endParen = beginParen.endGroup; |
| 1856 // TODO(eernst): Check for NPE as described in issue 26252. | |
| 1848 Token afterParens = endParen.next; | 1857 Token afterParens = endParen.next; |
| 1849 if (optional('{', afterParens) || | 1858 if (optional('{', afterParens) || |
| 1850 optional('=>', afterParens) || | 1859 optional('=>', afterParens) || |
| 1851 optional('async', afterParens) || | 1860 optional('async', afterParens) || |
| 1852 optional('sync', afterParens)) { | 1861 optional('sync', afterParens)) { |
| 1853 // We are looking at "type identifier '(' ... ')'" followed | 1862 // We are looking at "type identifier '(' ... ')'" followed |
| 1854 // by '=>' or '{'. | 1863 // by '{', '=>', 'async', or 'sync'. |
| 1855 return parseFunctionDeclaration(token); | 1864 return parseFunctionDeclaration(token); |
| 1856 } | 1865 } |
| 1866 } else if (enableGenericMethodSyntax && | |
| 1867 identical(afterIdKind, LT_TOKEN)) { | |
| 1868 // We are looking at "type identifier '<'". | |
| 1869 BeginGroupToken beginAngle = afterId; | |
| 1870 Token endAngle = beginAngle.endGroup; | |
| 1871 if (endAngle != null && | |
| 1872 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { | |
| 1873 BeginGroupToken beginParen = endAngle.next; | |
| 1874 Token endParen = beginParen.endGroup; | |
| 1875 if (endParen != null) { | |
| 1876 Token afterParens = endParen.next; | |
| 1877 if (optional('{', afterParens) || | |
| 1878 optional('=>', afterParens) || | |
| 1879 optional('async', afterParens) || | |
| 1880 optional('sync', afterParens)) { | |
| 1881 // We are looking at "type identifier '<' ... '>' '(' ... ')'" | |
| 1882 // followed by '{', '=>', 'async', or 'sync'. | |
| 1883 return parseFunctionDeclaration(token); | |
| 1884 } | |
| 1885 } | |
| 1886 } | |
| 1857 } | 1887 } |
| 1858 // Fall-through to expression statement. | 1888 // Fall-through to expression statement. |
| 1859 } else { | 1889 } else { |
| 1860 if (optional(':', token.next)) { | 1890 if (optional(':', token.next)) { |
| 1861 return parseLabeledStatement(token); | 1891 return parseLabeledStatement(token); |
| 1862 } else if (optional('(', token.next)) { | 1892 } else if (optional('(', token.next)) { |
| 1863 BeginGroupToken begin = token.next; | 1893 BeginGroupToken begin = token.next; |
| 1894 // TODO(eernst): Check for NPE as described in issue 26252. | |
| 1864 String afterParens = begin.endGroup.next.stringValue; | 1895 String afterParens = begin.endGroup.next.stringValue; |
| 1865 if (identical(afterParens, '{') || | 1896 if (identical(afterParens, '{') || |
| 1866 identical(afterParens, '=>') || | 1897 identical(afterParens, '=>') || |
| 1867 identical(afterParens, 'async') || | 1898 identical(afterParens, 'async') || |
| 1868 identical(afterParens, 'sync')) { | 1899 identical(afterParens, 'sync')) { |
| 1869 return parseFunctionDeclaration(token); | 1900 return parseFunctionDeclaration(token); |
| 1870 } | 1901 } |
| 1902 } else if (enableGenericMethodSyntax && optional('<', token.next)) { | |
| 1903 BeginGroupToken beginAngle = token.next; | |
| 1904 Token endAngle = beginAngle.endGroup; | |
| 1905 if (endAngle != null && | |
| 1906 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { | |
| 1907 BeginGroupToken beginParen = endAngle.next; | |
| 1908 Token endParen = beginParen.endGroup; | |
| 1909 if (endParen != null) { | |
| 1910 String afterParens = endParen.next.stringValue; | |
| 1911 if (identical(afterParens, '{') || | |
| 1912 identical(afterParens, '=>') || | |
| 1913 identical(afterParens, 'async') || | |
| 1914 identical(afterParens, 'sync')) { | |
| 1915 return parseFunctionDeclaration(token); | |
| 1916 } | |
| 1917 } | |
| 1918 } | |
| 1919 // Fall through to expression statement. | |
| 1871 } | 1920 } |
| 1872 } | 1921 } |
| 1873 return parseExpressionStatement(token); | 1922 return parseExpressionStatement(token); |
| 1874 } | 1923 } |
| 1875 | 1924 |
| 1876 Token parseExpressionStatementOrConstDeclaration(Token token) { | 1925 Token parseExpressionStatementOrConstDeclaration(Token token) { |
| 1877 assert(identical(token.stringValue, 'const')); | 1926 assert(identical(token.stringValue, 'const')); |
| 1878 if (isModifier(token.next)) { | 1927 if (isModifier(token.next)) { |
| 1879 return parseVariablesDeclaration(token); | 1928 return parseVariablesDeclaration(token); |
| 1880 } | 1929 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2128 } else if (asyncAwaitKeywordsEnabled && | 2177 } else if (asyncAwaitKeywordsEnabled && |
| 2129 (value == 'yield' || value == 'async')) { | 2178 (value == 'yield' || value == 'async')) { |
| 2130 return listener.expectedExpression(token); | 2179 return listener.expectedExpression(token); |
| 2131 } else if (token.isIdentifier()) { | 2180 } else if (token.isIdentifier()) { |
| 2132 return parseSendOrFunctionLiteral(token); | 2181 return parseSendOrFunctionLiteral(token); |
| 2133 } else { | 2182 } else { |
| 2134 return listener.expectedExpression(token); | 2183 return listener.expectedExpression(token); |
| 2135 } | 2184 } |
| 2136 } else if (kind == OPEN_PAREN_TOKEN) { | 2185 } else if (kind == OPEN_PAREN_TOKEN) { |
| 2137 return parseParenthesizedExpressionOrFunctionLiteral(token); | 2186 return parseParenthesizedExpressionOrFunctionLiteral(token); |
| 2138 } else if ((kind == LT_TOKEN) || | 2187 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || token.stringValue == '[]') { |
| 2139 (kind == OPEN_SQUARE_BRACKET_TOKEN) || | 2188 listener.handleNoTypeArguments(token); |
| 2140 (kind == OPEN_CURLY_BRACKET_TOKEN) || | 2189 return parseLiteralListSuffix(token, null); |
| 2141 token.stringValue == '[]') { | 2190 } else if (kind == OPEN_CURLY_BRACKET_TOKEN) { |
| 2142 return parseLiteralListOrMap(token); | 2191 listener.handleNoTypeArguments(token); |
| 2192 return parseLiteralMapSuffix(token, null); | |
| 2193 } else if (kind == LT_TOKEN) { | |
| 2194 return parseLiteralListOrMapOrFunction(token, null); | |
| 2143 } else { | 2195 } else { |
| 2144 return listener.expectedExpression(token); | 2196 return listener.expectedExpression(token); |
| 2145 } | 2197 } |
| 2146 } | 2198 } |
| 2147 | 2199 |
| 2148 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { | 2200 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { |
| 2149 BeginGroupToken beginGroup = token; | 2201 BeginGroupToken beginGroup = token; |
| 2202 // TODO(eernst): Check for NPE as described in issue 26252. | |
| 2150 Token nextToken = beginGroup.endGroup.next; | 2203 Token nextToken = beginGroup.endGroup.next; |
| 2151 int kind = nextToken.kind; | 2204 int kind = nextToken.kind; |
| 2152 if (mayParseFunctionExpressions && | 2205 if (mayParseFunctionExpressions && |
| 2153 (identical(kind, FUNCTION_TOKEN) || | 2206 (identical(kind, FUNCTION_TOKEN) || |
| 2154 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || | 2207 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || |
| 2155 (identical(kind, KEYWORD_TOKEN) && | 2208 (identical(kind, KEYWORD_TOKEN) && |
| 2156 (nextToken.value == 'async' || nextToken.value == 'sync')))) { | 2209 (nextToken.value == 'async' || nextToken.value == 'sync')))) { |
| 2210 listener.handleNoTypeVariables(token); | |
| 2157 return parseUnnamedFunction(token); | 2211 return parseUnnamedFunction(token); |
| 2158 } else { | 2212 } else { |
| 2159 bool old = mayParseFunctionExpressions; | 2213 bool old = mayParseFunctionExpressions; |
| 2160 mayParseFunctionExpressions = true; | 2214 mayParseFunctionExpressions = true; |
| 2161 token = parseParenthesizedExpression(token); | 2215 token = parseParenthesizedExpression(token); |
| 2162 mayParseFunctionExpressions = old; | 2216 mayParseFunctionExpressions = old; |
| 2163 return token; | 2217 return token; |
| 2164 } | 2218 } |
| 2165 } | 2219 } |
| 2166 | 2220 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2196 token = token.next; | 2250 token = token.next; |
| 2197 if (optional('(', token)) { | 2251 if (optional('(', token)) { |
| 2198 // Super constructor. | 2252 // Super constructor. |
| 2199 listener.handleNoTypeArguments(token); | 2253 listener.handleNoTypeArguments(token); |
| 2200 token = parseArguments(token); | 2254 token = parseArguments(token); |
| 2201 listener.endSend(token); | 2255 listener.endSend(token); |
| 2202 } | 2256 } |
| 2203 return token; | 2257 return token; |
| 2204 } | 2258 } |
| 2205 | 2259 |
| 2206 Token parseLiteralListOrMap(Token token) { | 2260 // '[' (expression (',' expression))? ']'. |
| 2207 Token constKeyword = null; | 2261 // Provide [constKeyword] if preceded by 'const', null if not. |
| 2208 if (optional('const', token)) { | 2262 // This is a suffix parser because it is assumed that type arguments have |
| 2209 constKeyword = token; | 2263 // been parsed, or `listener.handleNoTypeArguments(..)` has been executed. |
| 2210 token = token.next; | 2264 Token parseLiteralListSuffix(Token token, Token constKeyword) { |
| 2265 Token beginToken = token; | |
|
Johnni Winther
2016/04/14 08:23:50
You can assert that token is '[' or '[]' here.
eernst
2016/04/14 09:47:27
Done.
| |
| 2266 int count = 0; | |
| 2267 if (optional('[', token)) { | |
| 2268 bool old = mayParseFunctionExpressions; | |
| 2269 mayParseFunctionExpressions = true; | |
| 2270 do { | |
| 2271 if (optional(']', token.next)) { | |
| 2272 token = token.next; | |
| 2273 break; | |
| 2274 } | |
| 2275 token = parseExpression(token.next); | |
| 2276 ++count; | |
| 2277 } while (optional(',', token)); | |
| 2278 mayParseFunctionExpressions = old; | |
| 2279 listener.handleLiteralList(count, beginToken, constKeyword, token); | |
| 2280 return expect(']', token); | |
| 2281 } else if (optional('[]', token)) { | |
| 2282 listener.handleLiteralList(0, token, constKeyword, token); | |
| 2283 return token.next; | |
| 2211 } | 2284 } |
| 2212 token = parseTypeArgumentsOpt(token); | 2285 listener.unexpected(token); |
| 2286 return null; | |
| 2287 } | |
| 2288 | |
| 2289 // '{' expression (',' expression) '}'. | |
| 2290 // Provide token for [constKeyword] if preceded by 'const', null if not. | |
| 2291 // This is a suffix parser because it is assumed that type arguments have | |
| 2292 // been parsed, or `listener.handleNoTypeArguments(..)` has been executed. | |
| 2293 Token parseLiteralMapSuffix(Token token, Token constKeyword) { | |
| 2213 Token beginToken = token; | 2294 Token beginToken = token; |
|
Johnni Winther
2016/04/14 08:23:50
You can assert that token is '{' here.
eernst
2016/04/14 09:47:27
Done.
| |
| 2214 int count = 0; | 2295 int count = 0; |
| 2215 if (optional('{', token)) { | 2296 if (optional('{', token)) { |
| 2216 bool old = mayParseFunctionExpressions; | 2297 bool old = mayParseFunctionExpressions; |
| 2217 mayParseFunctionExpressions = true; | 2298 mayParseFunctionExpressions = true; |
| 2218 do { | 2299 do { |
| 2219 if (optional('}', token.next)) { | 2300 if (optional('}', token.next)) { |
| 2220 token = token.next; | 2301 token = token.next; |
| 2221 break; | 2302 break; |
| 2222 } | 2303 } |
| 2223 token = parseMapLiteralEntry(token.next); | 2304 token = parseMapLiteralEntry(token.next); |
| 2224 ++count; | 2305 ++count; |
| 2225 } while (optional(',', token)); | 2306 } while (optional(',', token)); |
| 2226 mayParseFunctionExpressions = old; | 2307 mayParseFunctionExpressions = old; |
| 2227 listener.handleLiteralMap(count, beginToken, constKeyword, token); | 2308 listener.handleLiteralMap(count, beginToken, constKeyword, token); |
| 2228 return expect('}', token); | 2309 return expect('}', token); |
| 2229 } else if (optional('[', token)) { | 2310 } |
| 2230 bool old = mayParseFunctionExpressions; | 2311 listener.unexpected(token); |
| 2231 mayParseFunctionExpressions = true; | 2312 return null; |
| 2232 do { | 2313 } |
| 2233 if (optional(']', token.next)) { | 2314 |
| 2234 token = token.next; | 2315 // '(' (argument (',' argument)*)? ')' body. |
| 2235 break; | 2316 // This is a suffix parser because it is assumed that type arguments have |
| 2317 // been parsed, or `listener.handleNoTypeArguments(..)` has been executed. | |
| 2318 Token parseLiteralFunctionSuffix(Token token) { | |
| 2319 if (optional('(',token)) { | |
|
Johnni Winther
2016/04/14 08:23:50
You can assert that token is '(' here.
eernst
2016/04/14 09:47:27
Done.
| |
| 2320 BeginGroupToken beginGroup = token; | |
| 2321 if (beginGroup.endGroup != null) { | |
| 2322 Token nextToken = beginGroup.endGroup.next; | |
| 2323 int kind = nextToken.kind; | |
| 2324 if (identical(kind, FUNCTION_TOKEN) || | |
| 2325 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || | |
| 2326 (identical(kind, KEYWORD_TOKEN) && | |
| 2327 (nextToken.value == 'async' || nextToken.value == 'sync'))) { | |
| 2328 return parseUnnamedFunction(token); | |
| 2236 } | 2329 } |
| 2237 token = parseExpression(token.next); | 2330 // Fall through. |
| 2238 ++count; | 2331 } |
| 2239 } while (optional(',', token)); | 2332 // Fall through. |
| 2240 mayParseFunctionExpressions = old; | 2333 } |
| 2241 listener.handleLiteralList(count, beginToken, constKeyword, token); | 2334 listener.unexpected(token); |
| 2242 return expect(']', token); | 2335 return null; |
| 2243 } else if (optional('[]', token)) { | 2336 } |
| 2244 listener.handleLiteralList(0, token, constKeyword, token); | 2337 |
| 2245 return token.next; | 2338 // typeArguments (literalList | literalMap | unnamedFunction). |
| 2339 // Provide token for [constKeyword] if preceded by 'const', null if not. | |
| 2340 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) { | |
| 2341 assert(optional('<', token)); | |
| 2342 BeginGroupToken begin = token; | |
| 2343 if (enableGenericMethodSyntax && | |
| 2344 constKeyword == null && | |
| 2345 begin.endGroup != null && | |
| 2346 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) { | |
| 2347 token = parseTypeVariablesOpt(token); | |
| 2348 return parseLiteralFunctionSuffix(token); | |
| 2246 } else { | 2349 } else { |
| 2350 token = parseTypeArgumentsOpt(token); | |
| 2351 if (optional('{', token)) { | |
| 2352 return parseLiteralMapSuffix(token, constKeyword); | |
| 2353 } else if ((optional('[', token)) || (optional('[]', token))) { | |
| 2354 return parseLiteralListSuffix(token, constKeyword); | |
| 2355 } | |
| 2247 listener.unexpected(token); | 2356 listener.unexpected(token); |
| 2248 return null; | 2357 return null; |
| 2249 } | 2358 } |
| 2250 } | 2359 } |
| 2251 | 2360 |
| 2252 Token parseMapLiteralEntry(Token token) { | 2361 Token parseMapLiteralEntry(Token token) { |
| 2253 listener.beginLiteralMapEntry(token); | 2362 listener.beginLiteralMapEntry(token); |
| 2254 // Assume the listener rejects non-string keys. | 2363 // Assume the listener rejects non-string keys. |
| 2255 token = parseExpression(token); | 2364 token = parseExpression(token); |
| 2256 Token colon = token; | 2365 Token colon = token; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2268 isFunctionDeclaration(peek.next)) { | 2377 isFunctionDeclaration(peek.next)) { |
| 2269 return parseFunctionExpression(token); | 2378 return parseFunctionExpression(token); |
| 2270 } else if (isFunctionDeclaration(token.next)) { | 2379 } else if (isFunctionDeclaration(token.next)) { |
| 2271 return parseFunctionExpression(token); | 2380 return parseFunctionExpression(token); |
| 2272 } else { | 2381 } else { |
| 2273 return parseSend(token); | 2382 return parseSend(token); |
| 2274 } | 2383 } |
| 2275 } | 2384 } |
| 2276 | 2385 |
| 2277 bool isFunctionDeclaration(Token token) { | 2386 bool isFunctionDeclaration(Token token) { |
| 2387 if (enableGenericMethodSyntax && optional('<', token)) { | |
| 2388 BeginGroupToken begin = token; | |
| 2389 if (begin.endGroup == null) return false; | |
| 2390 token = begin.endGroup.next; | |
| 2391 } | |
| 2278 if (optional('(', token)) { | 2392 if (optional('(', token)) { |
| 2279 BeginGroupToken begin = token; | 2393 BeginGroupToken begin = token; |
| 2394 // TODO(eernst): Check for NPE as described in issue 26252. | |
| 2280 String afterParens = begin.endGroup.next.stringValue; | 2395 String afterParens = begin.endGroup.next.stringValue; |
| 2281 if (identical(afterParens, '{') || | 2396 if (identical(afterParens, '{') || |
| 2282 identical(afterParens, '=>') || | 2397 identical(afterParens, '=>') || |
| 2283 identical(afterParens, 'async') || | 2398 identical(afterParens, 'async') || |
| 2284 identical(afterParens, 'sync')) { | 2399 identical(afterParens, 'sync')) { |
| 2285 return true; | 2400 return true; |
| 2286 } | 2401 } |
| 2287 } | 2402 } |
| 2288 return false; | 2403 return false; |
| 2289 } | 2404 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2304 token = parseConstructorReference(token); | 2419 token = parseConstructorReference(token); |
| 2305 token = parseRequiredArguments(token); | 2420 token = parseRequiredArguments(token); |
| 2306 listener.handleNewExpression(newKeyword); | 2421 listener.handleNewExpression(newKeyword); |
| 2307 return token; | 2422 return token; |
| 2308 } | 2423 } |
| 2309 | 2424 |
| 2310 Token parseConstExpression(Token token) { | 2425 Token parseConstExpression(Token token) { |
| 2311 Token constKeyword = token; | 2426 Token constKeyword = token; |
| 2312 token = expect('const', token); | 2427 token = expect('const', token); |
| 2313 final String value = token.stringValue; | 2428 final String value = token.stringValue; |
| 2314 if ((identical(value, '<')) || | 2429 if ((identical(value, '[')) || (identical(value, '[]'))) { |
| 2315 (identical(value, '[')) || | 2430 listener.handleNoTypeArguments(token); |
| 2316 (identical(value, '[]')) || | 2431 return parseLiteralListSuffix(token, constKeyword); |
| 2317 (identical(value, '{'))) { | 2432 } |
| 2318 return parseLiteralListOrMap(constKeyword); | 2433 if (identical(value, '{')) { |
| 2434 listener.handleNoTypeArguments(token); | |
| 2435 return parseLiteralMapSuffix(token, constKeyword); | |
| 2436 } | |
| 2437 if (identical(value, '<')) { | |
| 2438 return parseLiteralListOrMapOrFunction(token, constKeyword); | |
| 2319 } | 2439 } |
| 2320 token = parseConstructorReference(token); | 2440 token = parseConstructorReference(token); |
| 2321 token = parseRequiredArguments(token); | 2441 token = parseRequiredArguments(token); |
| 2322 listener.handleConstExpression(constKeyword); | 2442 listener.handleConstExpression(constKeyword); |
| 2323 return token; | 2443 return token; |
| 2324 } | 2444 } |
| 2325 | 2445 |
| 2326 Token parseLiteralInt(Token token) { | 2446 Token parseLiteralInt(Token token) { |
| 2327 listener.handleLiteralInt(token); | 2447 listener.handleLiteralInt(token); |
| 2328 return token.next; | 2448 return token.next; |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2861 } | 2981 } |
| 2862 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2982 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 2863 return expectSemicolon(token); | 2983 return expectSemicolon(token); |
| 2864 } | 2984 } |
| 2865 | 2985 |
| 2866 Token parseEmptyStatement(Token token) { | 2986 Token parseEmptyStatement(Token token) { |
| 2867 listener.handleEmptyStatement(token); | 2987 listener.handleEmptyStatement(token); |
| 2868 return expectSemicolon(token); | 2988 return expectSemicolon(token); |
| 2869 } | 2989 } |
| 2870 } | 2990 } |
| OLD | NEW |