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 fasta.parser.parser; | 5 library fasta.parser.parser; |
6 | 6 |
7 import '../fasta_codes.dart' show FastaCode, FastaMessage; | 7 import '../fasta_codes.dart' show FastaCode, FastaMessage; |
8 | 8 |
9 import '../fasta_codes.dart' as fasta; | 9 import '../fasta_codes.dart' as fasta; |
10 | 10 |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 } | 1382 } |
1383 // Fall-through to expression statement. | 1383 // Fall-through to expression statement. |
1384 } | 1384 } |
1385 | 1385 |
1386 return parseExpressionStatement(begin); | 1386 return parseExpressionStatement(begin); |
1387 | 1387 |
1388 case TypeContinuation.SendOrFunctionLiteral: | 1388 case TypeContinuation.SendOrFunctionLiteral: |
1389 if (looksLikeType && | 1389 if (looksLikeType && |
1390 token.isIdentifier && | 1390 token.isIdentifier && |
1391 isFunctionDeclaration(token.next)) { | 1391 isFunctionDeclaration(token.next)) { |
1392 return parseFunctionExpression(begin); | 1392 return parseNamedFunctionExpression(begin); |
1393 } else if (isFunctionDeclaration(begin.next)) { | 1393 } else if (isFunctionDeclaration(begin.next)) { |
1394 return parseFunctionExpression(begin); | 1394 return parseNamedFunctionExpression(begin); |
1395 } | 1395 } |
1396 return parseSend(begin, continuationContext); | 1396 return parseSend(begin, continuationContext); |
1397 | 1397 |
1398 case TypeContinuation.VariablesDeclarationOrExpression: | 1398 case TypeContinuation.VariablesDeclarationOrExpression: |
1399 if (looksLikeType && | 1399 if (looksLikeType && |
1400 token.isIdentifier && | 1400 token.isIdentifier && |
1401 isOneOf4(token.next, '=', ';', ',', 'in')) { | 1401 isOneOf4(token.next, '=', ';', ',', 'in')) { |
1402 // TODO(ahe): Generate type events and call | 1402 // TODO(ahe): Generate type events and call |
1403 // parseVariablesDeclarationNoSemicolonRest instead. | 1403 // parseVariablesDeclarationNoSemicolonRest instead. |
1404 return parseVariablesDeclarationNoSemicolon(begin); | 1404 return parseVariablesDeclarationNoSemicolon(begin); |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 if (isUserDefinableOperator(token.next.stringValue)) { | 2439 if (isUserDefinableOperator(token.next.stringValue)) { |
2440 Token operator = token; | 2440 Token operator = token; |
2441 token = token.next; | 2441 token = token.next; |
2442 listener.handleOperatorName(operator, token); | 2442 listener.handleOperatorName(operator, token); |
2443 return token.next; | 2443 return token.next; |
2444 } else { | 2444 } else { |
2445 return parseIdentifier(token, IdentifierContext.operatorName); | 2445 return parseIdentifier(token, IdentifierContext.operatorName); |
2446 } | 2446 } |
2447 } | 2447 } |
2448 | 2448 |
2449 Token parseFunction(Token token) { | 2449 Token parseFunctionExpression(Token token) { |
2450 Token beginToken = token; | 2450 Token beginToken = token; |
2451 listener.beginFunction(token); | 2451 listener.beginFunctionExpression(token); |
| 2452 token = parseFormalParameters(token, MemberKind.Local); |
| 2453 AsyncModifier savedAsyncModifier = asyncState; |
| 2454 token = parseAsyncModifier(token); |
| 2455 bool isBlock = optional('{', token); |
| 2456 token = parseFunctionBody(token, true, false); |
| 2457 asyncState = savedAsyncModifier; |
| 2458 listener.endFunctionExpression(beginToken, token); |
| 2459 return isBlock ? token.next : token; |
| 2460 } |
| 2461 |
| 2462 Token parseFunctionDeclaration(Token token) { |
| 2463 listener.beginFunctionDeclaration(token); |
| 2464 Token beginToken = token; |
2452 token = parseModifiers(token, MemberKind.Local); | 2465 token = parseModifiers(token, MemberKind.Local); |
2453 listener.beginFunctionName(token); | 2466 listener.beginFunctionName(token); |
2454 token = parseIdentifier(token, IdentifierContext.localFunctionDeclaration); | 2467 token = parseIdentifier(token, IdentifierContext.localFunctionDeclaration); |
2455 token = parseQualifiedRestOpt( | 2468 token = parseQualifiedRestOpt( |
2456 token, IdentifierContext.localFunctionDeclarationContinuation); | 2469 token, IdentifierContext.localFunctionDeclarationContinuation); |
2457 listener.endFunctionName(beginToken, token); | 2470 listener.endFunctionName(beginToken, token); |
2458 token = parseTypeVariablesOpt(token); | 2471 token = parseTypeVariablesOpt(token); |
2459 token = parseFormalParametersOpt(token, MemberKind.Local); | 2472 token = parseFormalParametersOpt(token, MemberKind.Local); |
2460 token = parseInitializersOpt(token); | 2473 token = parseInitializersOpt(token); |
2461 AsyncModifier savedAsyncModifier = asyncState; | 2474 AsyncModifier savedAsyncModifier = asyncState; |
2462 token = parseAsyncModifier(token); | 2475 token = parseAsyncModifier(token); |
2463 token = parseFunctionBody(token, false, true); | 2476 token = parseFunctionBody(token, false, true); |
2464 asyncState = savedAsyncModifier; | 2477 asyncState = savedAsyncModifier; |
2465 listener.endFunction(null, token); | 2478 token = token.next; |
2466 return token.next; | |
2467 } | |
2468 | |
2469 Token parseUnnamedFunction(Token token) { | |
2470 Token beginToken = token; | |
2471 listener.beginUnnamedFunction(token); | |
2472 token = parseFormalParameters(token, MemberKind.Local); | |
2473 AsyncModifier savedAsyncModifier = asyncState; | |
2474 token = parseAsyncModifier(token); | |
2475 bool isBlock = optional('{', token); | |
2476 token = parseFunctionBody(token, true, false); | |
2477 asyncState = savedAsyncModifier; | |
2478 listener.endUnnamedFunction(beginToken, token); | |
2479 return isBlock ? token.next : token; | |
2480 } | |
2481 | |
2482 Token parseFunctionDeclaration(Token token) { | |
2483 listener.beginFunctionDeclaration(token); | |
2484 token = parseFunction(token); | |
2485 listener.endFunctionDeclaration(token); | 2479 listener.endFunctionDeclaration(token); |
2486 return token; | 2480 return token; |
2487 } | 2481 } |
2488 | 2482 |
2489 Token parseFunctionExpression(Token token) { | 2483 /// Parses a named function expression which isn't legal syntax in Dart. |
| 2484 /// Useful for recovering from Javascript code being pasted into a Dart |
| 2485 /// proram, as it will interpret `function foo() {}` as a named function |
| 2486 /// expression with return type `function` and name `foo`. |
| 2487 Token parseNamedFunctionExpression(Token token) { |
2490 Token beginToken = token; | 2488 Token beginToken = token; |
2491 listener.beginFunction(token); | 2489 listener.beginNamedFunctionExpression(token); |
2492 listener.handleModifiers(0); | 2490 listener.handleModifiers(0); |
2493 token = parseType(token, TypeContinuation.Optional); | 2491 token = parseType(token, TypeContinuation.Optional); |
| 2492 if (token != beginToken) { |
| 2493 reportRecoverableErrorCode(token, fasta.codeReturnTypeFunctionExpression); |
| 2494 } |
2494 listener.beginFunctionName(token); | 2495 listener.beginFunctionName(token); |
| 2496 Token nameToken = token; |
2495 token = parseIdentifier(token, IdentifierContext.functionExpressionName); | 2497 token = parseIdentifier(token, IdentifierContext.functionExpressionName); |
| 2498 reportRecoverableErrorCode(nameToken, fasta.codeNamedFunctionExpression); |
2496 listener.endFunctionName(beginToken, token); | 2499 listener.endFunctionName(beginToken, token); |
2497 token = parseTypeVariablesOpt(token); | 2500 token = parseTypeVariablesOpt(token); |
2498 token = parseFormalParameters(token, MemberKind.Local); | 2501 token = parseFormalParameters(token, MemberKind.Local); |
2499 listener.handleNoInitializers(); | 2502 listener.handleNoInitializers(); |
2500 AsyncModifier savedAsyncModifier = asyncState; | 2503 AsyncModifier savedAsyncModifier = asyncState; |
2501 token = parseAsyncModifier(token); | 2504 token = parseAsyncModifier(token); |
2502 bool isBlock = optional('{', token); | 2505 bool isBlock = optional('{', token); |
2503 token = parseFunctionBody(token, true, false); | 2506 token = parseFunctionBody(token, true, false); |
2504 asyncState = savedAsyncModifier; | 2507 asyncState = savedAsyncModifier; |
2505 listener.endFunction(null, token); | 2508 listener.endNamedFunctionExpression(token); |
2506 return isBlock ? token.next : token; | 2509 return isBlock ? token.next : token; |
2507 } | 2510 } |
2508 | 2511 |
2509 Token parseConstructorReference(Token token) { | 2512 Token parseConstructorReference(Token token) { |
2510 Token start = token; | 2513 Token start = token; |
2511 listener.beginConstructorReference(start); | 2514 listener.beginConstructorReference(start); |
2512 token = parseIdentifier(token, IdentifierContext.constructorReference); | 2515 token = parseIdentifier(token, IdentifierContext.constructorReference); |
2513 token = parseQualifiedRestOpt( | 2516 token = parseQualifiedRestOpt( |
2514 token, IdentifierContext.constructorReferenceContinuation); | 2517 token, IdentifierContext.constructorReferenceContinuation); |
2515 token = parseTypeArgumentsOpt(token); | 2518 token = parseTypeArgumentsOpt(token); |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3106 return parseLiteralNull(token); | 3109 return parseLiteralNull(token); |
3107 } else if (identical(value, "this")) { | 3110 } else if (identical(value, "this")) { |
3108 return parseThisExpression(token, context); | 3111 return parseThisExpression(token, context); |
3109 } else if (identical(value, "super")) { | 3112 } else if (identical(value, "super")) { |
3110 return parseSuperExpression(token, context); | 3113 return parseSuperExpression(token, context); |
3111 } else if (identical(value, "new")) { | 3114 } else if (identical(value, "new")) { |
3112 return parseNewExpression(token); | 3115 return parseNewExpression(token); |
3113 } else if (identical(value, "const")) { | 3116 } else if (identical(value, "const")) { |
3114 return parseConstExpression(token); | 3117 return parseConstExpression(token); |
3115 } else if (identical(value, "void")) { | 3118 } else if (identical(value, "void")) { |
3116 return parseFunctionExpression(token); | 3119 return parseNamedFunctionExpression(token); |
3117 } else if (!inPlainSync && | 3120 } else if (!inPlainSync && |
3118 (identical(value, "yield") || identical(value, "async"))) { | 3121 (identical(value, "yield") || identical(value, "async"))) { |
3119 return expressionExpected(token); | 3122 return expressionExpected(token); |
3120 } else if (identical(value, "assert")) { | 3123 } else if (identical(value, "assert")) { |
3121 return parseAssert(token, Assert.Expression); | 3124 return parseAssert(token, Assert.Expression); |
3122 } else if (token.isIdentifier) { | 3125 } else if (token.isIdentifier) { |
3123 return parseSendOrFunctionLiteral(token, context); | 3126 return parseSendOrFunctionLiteral(token, context); |
3124 } else { | 3127 } else { |
3125 return expressionExpected(token); | 3128 return expressionExpected(token); |
3126 } | 3129 } |
(...skipping 24 matching lines...) Expand all Loading... |
3151 BeginToken beginGroup = token; | 3154 BeginToken beginGroup = token; |
3152 Token nextToken = beginGroup.endGroup.next; | 3155 Token nextToken = beginGroup.endGroup.next; |
3153 int kind = nextToken.kind; | 3156 int kind = nextToken.kind; |
3154 if (mayParseFunctionExpressions && | 3157 if (mayParseFunctionExpressions && |
3155 (identical(kind, FUNCTION_TOKEN) || | 3158 (identical(kind, FUNCTION_TOKEN) || |
3156 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || | 3159 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || |
3157 (identical(kind, KEYWORD_TOKEN) && | 3160 (identical(kind, KEYWORD_TOKEN) && |
3158 (optional('async', nextToken) || | 3161 (optional('async', nextToken) || |
3159 optional('sync', nextToken))))) { | 3162 optional('sync', nextToken))))) { |
3160 listener.handleNoTypeVariables(token); | 3163 listener.handleNoTypeVariables(token); |
3161 return parseUnnamedFunction(token); | 3164 return parseFunctionExpression(token); |
3162 } else { | 3165 } else { |
3163 bool old = mayParseFunctionExpressions; | 3166 bool old = mayParseFunctionExpressions; |
3164 mayParseFunctionExpressions = true; | 3167 mayParseFunctionExpressions = true; |
3165 token = parseParenthesizedExpression(token); | 3168 token = parseParenthesizedExpression(token); |
3166 mayParseFunctionExpressions = old; | 3169 mayParseFunctionExpressions = old; |
3167 return token; | 3170 return token; |
3168 } | 3171 } |
3169 } | 3172 } |
3170 | 3173 |
3171 Token parseParenthesizedExpression(Token token) { | 3174 Token parseParenthesizedExpression(Token token) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3271 Token parseLiteralFunctionSuffix(Token token) { | 3274 Token parseLiteralFunctionSuffix(Token token) { |
3272 assert(optional('(', token)); | 3275 assert(optional('(', token)); |
3273 BeginToken beginGroup = token; | 3276 BeginToken beginGroup = token; |
3274 if (beginGroup.endGroup != null) { | 3277 if (beginGroup.endGroup != null) { |
3275 Token nextToken = beginGroup.endGroup.next; | 3278 Token nextToken = beginGroup.endGroup.next; |
3276 int kind = nextToken.kind; | 3279 int kind = nextToken.kind; |
3277 if (identical(kind, FUNCTION_TOKEN) || | 3280 if (identical(kind, FUNCTION_TOKEN) || |
3278 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || | 3281 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || |
3279 (identical(kind, KEYWORD_TOKEN) && | 3282 (identical(kind, KEYWORD_TOKEN) && |
3280 (optional('async', nextToken) || optional('sync', nextToken)))) { | 3283 (optional('async', nextToken) || optional('sync', nextToken)))) { |
3281 return parseUnnamedFunction(token); | 3284 return parseFunctionExpression(token); |
3282 } | 3285 } |
3283 // Fall through. | 3286 // Fall through. |
3284 } | 3287 } |
3285 return reportUnexpectedToken(token).next; | 3288 return reportUnexpectedToken(token).next; |
3286 } | 3289 } |
3287 | 3290 |
3288 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral. | 3291 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral. |
3289 /// | 3292 /// |
3290 /// Where | 3293 /// Where |
3291 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']' | 3294 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']' |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4149 return reportUnrecoverableError( | 4152 return reportUnrecoverableError( |
4150 token, () => code.format(uri, token.charOffset, string)); | 4153 token, () => code.format(uri, token.charOffset, string)); |
4151 } | 4154 } |
4152 } | 4155 } |
4153 | 4156 |
4154 typedef FastaMessage NoArgument(Uri uri, int charOffset); | 4157 typedef FastaMessage NoArgument(Uri uri, int charOffset); |
4155 | 4158 |
4156 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); | 4159 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); |
4157 | 4160 |
4158 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); | 4161 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); |
OLD | NEW |