OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/bailout-reason.h" | 8 #include "src/bailout-reason.h" |
9 #include "src/expression-classifier.h" | 9 #include "src/expression-classifier.h" |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 2229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 // Number | 2240 // Number |
2241 // String | 2241 // String |
2242 // ArrayLiteral | 2242 // ArrayLiteral |
2243 // ObjectLiteral | 2243 // ObjectLiteral |
2244 // RegExpLiteral | 2244 // RegExpLiteral |
2245 // ClassLiteral | 2245 // ClassLiteral |
2246 // '(' Expression ')' | 2246 // '(' Expression ')' |
2247 // TemplateLiteral | 2247 // TemplateLiteral |
2248 // do Block | 2248 // do Block |
2249 | 2249 |
2250 int beg_pos = scanner()->peek_location().beg_pos; | 2250 int beg_pos = peek_position(); |
2251 int end_pos = scanner()->peek_location().end_pos; | 2251 switch (peek()) { |
2252 ExpressionT result = this->EmptyExpression(); | |
2253 Token::Value token = peek(); | |
2254 switch (token) { | |
2255 case Token::THIS: { | 2252 case Token::THIS: { |
2256 BindingPatternUnexpectedToken(classifier); | 2253 BindingPatternUnexpectedToken(classifier); |
2257 Consume(Token::THIS); | 2254 Consume(Token::THIS); |
2258 if (FLAG_strong_this && is_strong(language_mode())) { | 2255 if (FLAG_strong_this && is_strong(language_mode())) { |
2259 // Constructors' usages of 'this' in strong mode are parsed separately. | 2256 // Constructors' usages of 'this' in strong mode are parsed separately. |
2260 // TODO(rossberg): this does not work with arrow functions yet. | 2257 // TODO(rossberg): this does not work with arrow functions yet. |
2261 if (IsClassConstructor(function_state_->kind())) { | 2258 if (IsClassConstructor(function_state_->kind())) { |
2262 ReportMessage(MessageTemplate::kStrongConstructorThis); | 2259 ReportMessage(MessageTemplate::kStrongConstructorThis); |
2263 *ok = false; | 2260 *ok = false; |
2264 break; | 2261 return this->EmptyExpression(); |
2265 } | 2262 } |
2266 } | 2263 } |
2267 result = this->ThisExpression(scope_, factory(), beg_pos); | 2264 return this->ThisExpression(scope_, factory(), beg_pos); |
2268 break; | |
2269 } | 2265 } |
2270 | 2266 |
2271 case Token::NULL_LITERAL: | 2267 case Token::NULL_LITERAL: |
2272 case Token::TRUE_LITERAL: | 2268 case Token::TRUE_LITERAL: |
2273 case Token::FALSE_LITERAL: | 2269 case Token::FALSE_LITERAL: |
2274 BindingPatternUnexpectedToken(classifier); | 2270 BindingPatternUnexpectedToken(classifier); |
2275 Next(); | 2271 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
2276 result = | |
2277 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | |
2278 break; | |
2279 case Token::SMI: | 2272 case Token::SMI: |
2280 case Token::NUMBER: | 2273 case Token::NUMBER: |
2281 classifier->RecordBindingPatternError( | 2274 classifier->RecordBindingPatternError( |
2282 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); | 2275 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); |
2283 Next(); | 2276 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
2284 result = | |
2285 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | |
2286 break; | |
2287 | 2277 |
2288 case Token::IDENTIFIER: | 2278 case Token::IDENTIFIER: |
2289 case Token::LET: | 2279 case Token::LET: |
2290 case Token::STATIC: | 2280 case Token::STATIC: |
2291 case Token::YIELD: | 2281 case Token::YIELD: |
2292 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2282 case Token::FUTURE_STRICT_RESERVED_WORD: { |
2293 // Using eval or arguments in this context is OK even in strict mode. | 2283 // Using eval or arguments in this context is OK even in strict mode. |
2294 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2284 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
2295 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2285 return this->ExpressionFromIdentifier( |
2296 factory()); | 2286 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
2297 break; | |
2298 } | 2287 } |
2299 | 2288 |
2300 case Token::STRING: { | 2289 case Token::STRING: { |
2301 classifier->RecordBindingPatternError( | 2290 classifier->RecordBindingPatternError( |
2302 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString); | 2291 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString); |
2303 Consume(Token::STRING); | 2292 Consume(Token::STRING); |
2304 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2293 return this->ExpressionFromString(beg_pos, scanner(), factory()); |
2305 break; | |
2306 } | 2294 } |
2307 | 2295 |
2308 case Token::ASSIGN_DIV: | 2296 case Token::ASSIGN_DIV: |
2309 classifier->RecordBindingPatternError( | 2297 classifier->RecordBindingPatternError( |
2310 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); | 2298 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); |
2311 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); | 2299 return this->ParseRegExpLiteral(true, classifier, ok); |
2312 break; | |
2313 | 2300 |
2314 case Token::DIV: | 2301 case Token::DIV: |
2315 classifier->RecordBindingPatternError( | 2302 classifier->RecordBindingPatternError( |
2316 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); | 2303 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); |
2317 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); | 2304 return this->ParseRegExpLiteral(false, classifier, ok); |
2318 break; | |
2319 | 2305 |
2320 case Token::LBRACK: | 2306 case Token::LBRACK: |
2321 if (!allow_harmony_destructuring()) { | 2307 if (!allow_harmony_destructuring()) { |
2322 BindingPatternUnexpectedToken(classifier); | 2308 BindingPatternUnexpectedToken(classifier); |
2323 } | 2309 } |
2324 result = this->ParseArrayLiteral(classifier, CHECK_OK); | 2310 return this->ParseArrayLiteral(classifier, ok); |
2325 break; | |
2326 | 2311 |
2327 case Token::LBRACE: | 2312 case Token::LBRACE: |
2328 if (!allow_harmony_destructuring()) { | 2313 if (!allow_harmony_destructuring()) { |
2329 BindingPatternUnexpectedToken(classifier); | 2314 BindingPatternUnexpectedToken(classifier); |
2330 } | 2315 } |
2331 result = this->ParseObjectLiteral(classifier, CHECK_OK); | 2316 return this->ParseObjectLiteral(classifier, ok); |
2332 break; | |
2333 | 2317 |
2334 case Token::LPAREN: | 2318 case Token::LPAREN: { |
2335 // Arrow function formal parameters are either a single identifier or a | 2319 // Arrow function formal parameters are either a single identifier or a |
2336 // list of BindingPattern productions enclosed in parentheses. | 2320 // list of BindingPattern productions enclosed in parentheses. |
2337 // Parentheses are not valid on the LHS of a BindingPattern, so we use the | 2321 // Parentheses are not valid on the LHS of a BindingPattern, so we use the |
2338 // is_valid_binding_pattern() check to detect multiple levels of | 2322 // is_valid_binding_pattern() check to detect multiple levels of |
2339 // parenthesization. | 2323 // parenthesization. |
2340 if (!classifier->is_valid_binding_pattern()) { | 2324 if (!classifier->is_valid_binding_pattern()) { |
2341 ArrowFormalParametersUnexpectedToken(classifier); | 2325 ArrowFormalParametersUnexpectedToken(classifier); |
2342 } | 2326 } |
2343 BindingPatternUnexpectedToken(classifier); | 2327 BindingPatternUnexpectedToken(classifier); |
2344 Consume(Token::LPAREN); | 2328 Consume(Token::LPAREN); |
2345 if (Check(Token::RPAREN)) { | 2329 if (Check(Token::RPAREN)) { |
2346 // ()=>x. The continuation that looks for the => is in | 2330 // ()=>x. The continuation that looks for the => is in |
2347 // ParseAssignmentExpression. | 2331 // ParseAssignmentExpression. |
2348 classifier->RecordExpressionError(scanner()->location(), | 2332 classifier->RecordExpressionError(scanner()->location(), |
2349 MessageTemplate::kUnexpectedToken, | 2333 MessageTemplate::kUnexpectedToken, |
2350 Token::String(Token::RPAREN)); | 2334 Token::String(Token::RPAREN)); |
2351 classifier->RecordBindingPatternError(scanner()->location(), | 2335 classifier->RecordBindingPatternError(scanner()->location(), |
2352 MessageTemplate::kUnexpectedToken, | 2336 MessageTemplate::kUnexpectedToken, |
2353 Token::String(Token::RPAREN)); | 2337 Token::String(Token::RPAREN)); |
2354 result = factory()->NewEmptyParentheses(beg_pos); | 2338 return factory()->NewEmptyParentheses(beg_pos); |
2355 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { | 2339 } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { |
2356 // (...x)=>x. The continuation that looks for the => is in | 2340 // (...x)=>x. The continuation that looks for the => is in |
2357 // ParseAssignmentExpression. | 2341 // ParseAssignmentExpression. |
2358 int ellipsis_pos = scanner()->location().beg_pos; | 2342 int ellipsis_pos = position(); |
2359 classifier->RecordExpressionError(scanner()->location(), | 2343 classifier->RecordExpressionError(scanner()->location(), |
2360 MessageTemplate::kUnexpectedToken, | 2344 MessageTemplate::kUnexpectedToken, |
2361 Token::String(Token::ELLIPSIS)); | 2345 Token::String(Token::ELLIPSIS)); |
2362 classifier->RecordNonSimpleParameter(); | 2346 classifier->RecordNonSimpleParameter(); |
2363 Scanner::Location expr_loc = scanner()->peek_location(); | 2347 Scanner::Location expr_loc = scanner()->peek_location(); |
2364 Token::Value tok = peek(); | 2348 Token::Value tok = peek(); |
2365 result = this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 2349 ExpressionT expr = |
| 2350 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2366 // Patterns are not allowed as rest parameters. There is no way we can | 2351 // Patterns are not allowed as rest parameters. There is no way we can |
2367 // succeed so go ahead and use the convenient ReportUnexpectedToken | 2352 // succeed so go ahead and use the convenient ReportUnexpectedToken |
2368 // interface. | 2353 // interface. |
2369 if (!Traits::IsIdentifier(result)) { | 2354 if (!Traits::IsIdentifier(expr)) { |
2370 ReportUnexpectedTokenAt(expr_loc, tok); | 2355 ReportUnexpectedTokenAt(expr_loc, tok); |
2371 *ok = false; | 2356 *ok = false; |
2372 return this->EmptyExpression(); | 2357 return this->EmptyExpression(); |
2373 } | 2358 } |
2374 result = factory()->NewSpread(result, ellipsis_pos); | |
2375 | |
2376 if (peek() == Token::COMMA) { | 2359 if (peek() == Token::COMMA) { |
2377 ReportMessageAt(scanner()->peek_location(), | 2360 ReportMessageAt(scanner()->peek_location(), |
2378 MessageTemplate::kParamAfterRest); | 2361 MessageTemplate::kParamAfterRest); |
2379 *ok = false; | 2362 *ok = false; |
2380 return this->EmptyExpression(); | 2363 return this->EmptyExpression(); |
2381 } | 2364 } |
2382 Expect(Token::RPAREN, CHECK_OK); | 2365 Expect(Token::RPAREN, CHECK_OK); |
2383 } else { | 2366 return factory()->NewSpread(expr, ellipsis_pos); |
2384 // Heuristically try to detect immediately called functions before | |
2385 // seeing the call parentheses. | |
2386 parenthesized_function_ = (peek() == Token::FUNCTION); | |
2387 result = this->ParseExpression(true, classifier, CHECK_OK); | |
2388 Expect(Token::RPAREN, CHECK_OK); | |
2389 } | 2367 } |
2390 break; | 2368 // Heuristically try to detect immediately called functions before |
| 2369 // seeing the call parentheses. |
| 2370 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2371 ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK); |
| 2372 Expect(Token::RPAREN, CHECK_OK); |
| 2373 return expr; |
| 2374 } |
2391 | 2375 |
2392 case Token::CLASS: { | 2376 case Token::CLASS: { |
2393 BindingPatternUnexpectedToken(classifier); | 2377 BindingPatternUnexpectedToken(classifier); |
2394 Consume(Token::CLASS); | 2378 Consume(Token::CLASS); |
2395 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2379 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2396 ReportMessage(MessageTemplate::kSloppyLexical); | 2380 ReportMessage(MessageTemplate::kSloppyLexical); |
2397 *ok = false; | 2381 *ok = false; |
2398 break; | 2382 return this->EmptyExpression(); |
2399 } | 2383 } |
2400 int class_token_position = position(); | 2384 int class_token_position = position(); |
2401 IdentifierT name = this->EmptyIdentifier(); | 2385 IdentifierT name = this->EmptyIdentifier(); |
2402 bool is_strict_reserved_name = false; | 2386 bool is_strict_reserved_name = false; |
2403 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2387 Scanner::Location class_name_location = Scanner::Location::invalid(); |
2404 if (peek_any_identifier()) { | 2388 if (peek_any_identifier()) { |
2405 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2389 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
2406 CHECK_OK); | 2390 CHECK_OK); |
2407 class_name_location = scanner()->location(); | 2391 class_name_location = scanner()->location(); |
2408 } | 2392 } |
2409 result = this->ParseClassLiteral(name, class_name_location, | 2393 return this->ParseClassLiteral(name, class_name_location, |
2410 is_strict_reserved_name, | 2394 is_strict_reserved_name, |
2411 class_token_position, CHECK_OK); | 2395 class_token_position, ok); |
2412 break; | |
2413 } | 2396 } |
2414 | 2397 |
2415 case Token::TEMPLATE_SPAN: | 2398 case Token::TEMPLATE_SPAN: |
2416 case Token::TEMPLATE_TAIL: | 2399 case Token::TEMPLATE_TAIL: |
2417 classifier->RecordBindingPatternError( | 2400 classifier->RecordBindingPatternError( |
2418 scanner()->peek_location(), | 2401 scanner()->peek_location(), |
2419 MessageTemplate::kUnexpectedTemplateString); | 2402 MessageTemplate::kUnexpectedTemplateString); |
2420 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2403 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
2421 classifier, CHECK_OK); | 2404 classifier, ok); |
2422 break; | |
2423 | 2405 |
2424 case Token::MOD: | 2406 case Token::MOD: |
2425 if (allow_natives() || extension_ != NULL) { | 2407 if (allow_natives() || extension_ != NULL) { |
2426 result = this->ParseV8Intrinsic(CHECK_OK); | 2408 return this->ParseV8Intrinsic(ok); |
2427 break; | |
2428 } | 2409 } |
| 2410 break; |
2429 | 2411 |
2430 case Token::DO: | 2412 case Token::DO: |
2431 // TODO(caitp): reorganize ParsePrimaryExpression() to not require this | 2413 if (allow_harmony_do_expressions()) { |
2432 // extra `token == Token::DO` test due to potential fall-through | |
2433 if (token == Token::DO && allow_harmony_do_expressions()) { | |
2434 BindingPatternUnexpectedToken(classifier); | 2414 BindingPatternUnexpectedToken(classifier); |
2435 result = Traits::ParseDoExpression(CHECK_OK); | 2415 return Traits::ParseDoExpression(ok); |
2436 break; | |
2437 } | 2416 } |
2438 // If we're not allowing special syntax we fall-through to the | 2417 break; |
2439 // default case. | |
2440 | 2418 |
2441 default: { | 2419 default: |
2442 Next(); | 2420 break; |
2443 ReportUnexpectedToken(token); | |
2444 *ok = false; | |
2445 } | |
2446 } | 2421 } |
2447 | 2422 |
2448 return result; | 2423 ReportUnexpectedToken(Next()); |
| 2424 *ok = false; |
| 2425 return this->EmptyExpression(); |
2449 } | 2426 } |
2450 | 2427 |
2451 | 2428 |
2452 template <class Traits> | 2429 template <class Traits> |
2453 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2430 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2454 bool accept_IN, bool* ok) { | 2431 bool accept_IN, bool* ok) { |
2455 ExpressionClassifier classifier; | 2432 ExpressionClassifier classifier; |
2456 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 2433 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
2457 ValidateExpression(&classifier, CHECK_OK); | 2434 ValidateExpression(&classifier, CHECK_OK); |
2458 return result; | 2435 return result; |
(...skipping 1763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4222 return; | 4199 return; |
4223 } | 4200 } |
4224 has_seen_constructor_ = true; | 4201 has_seen_constructor_ = true; |
4225 return; | 4202 return; |
4226 } | 4203 } |
4227 } | 4204 } |
4228 } // namespace internal | 4205 } // namespace internal |
4229 } // namespace v8 | 4206 } // namespace v8 |
4230 | 4207 |
4231 #endif // V8_PREPARSER_H | 4208 #endif // V8_PREPARSER_H |
OLD | NEW |