Chromium Code Reviews| 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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1543 switch (peek()) { | 1543 switch (peek()) { |
| 1544 case Token::THIS: { | 1544 case Token::THIS: { |
| 1545 BindingPatternUnexpectedToken(classifier); | 1545 BindingPatternUnexpectedToken(classifier); |
| 1546 Consume(Token::THIS); | 1546 Consume(Token::THIS); |
| 1547 return this->ThisExpression(scope(), factory(), beg_pos); | 1547 return this->ThisExpression(scope(), factory(), beg_pos); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 case Token::NULL_LITERAL: | 1550 case Token::NULL_LITERAL: |
| 1551 case Token::TRUE_LITERAL: | 1551 case Token::TRUE_LITERAL: |
| 1552 case Token::FALSE_LITERAL: | 1552 case Token::FALSE_LITERAL: |
| 1553 BindingPatternUnexpectedToken(classifier); | |
| 1554 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | |
|
vogelheim
2016/07/28 09:35:01
[drive-by cleanup]
| |
| 1555 case Token::SMI: | 1553 case Token::SMI: |
| 1556 case Token::NUMBER: | 1554 case Token::NUMBER: |
| 1557 BindingPatternUnexpectedToken(classifier); | 1555 BindingPatternUnexpectedToken(classifier); |
| 1558 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1556 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1559 | 1557 |
| 1560 case Token::ASYNC: | 1558 case Token::ASYNC: |
| 1561 if (allow_harmony_async_await() && | 1559 if (allow_harmony_async_await() && |
| 1562 !scanner()->HasAnyLineTerminatorAfterNext() && | 1560 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 1563 PeekAhead() == Token::FUNCTION) { | 1561 PeekAhead() == Token::FUNCTION) { |
| 1564 Consume(Token::ASYNC); | 1562 Consume(Token::ASYNC); |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2270 | 2268 |
| 2271 return result; | 2269 return result; |
| 2272 } | 2270 } |
| 2273 | 2271 |
| 2274 // Precedence = 2 | 2272 // Precedence = 2 |
| 2275 template <class Traits> | 2273 template <class Traits> |
| 2276 typename ParserBase<Traits>::ExpressionT | 2274 typename ParserBase<Traits>::ExpressionT |
| 2277 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2275 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| 2278 ExpressionClassifier* classifier, | 2276 ExpressionClassifier* classifier, |
| 2279 bool* ok) { | 2277 bool* ok) { |
| 2278 // Parser shortcut: The following scope is a micro-optimization to reduce | |
|
marja
2016/07/28 10:01:28
Can you put all this into a separate function, jus
vogelheim
2016/07/28 12:54:59
Done.
The hardest part was to figure out how to t
| |
| 2279 // parsing time and should be functionally neutral. When we encounter | |
| 2280 // [SMI|NUMBER|{NULL,TRUE,FALSE}_LITERAL|THIS|STRING|IDENTIFIER] | |
| 2281 // followed by | |
| 2282 // [COMMA|RPAREN|RBRACK|SEMICOLON] | |
| 2283 // then this will result in a single AST node. Instead of parsing this | |
| 2284 // 'properly' (a call chain 11-levels deep), we will just generate the | |
| 2285 // appropriate AST nodes right here. | |
| 2286 { | |
| 2287 Token::Value peek_token = peek(); | |
| 2288 bool is_number = peek_token == Token::SMI || peek_token == Token::NUMBER; | |
| 2289 bool is_literal = peek_token == Token::NULL_LITERAL || | |
| 2290 peek_token == Token::TRUE_LITERAL || | |
| 2291 peek_token == Token::FALSE_LITERAL; | |
| 2292 bool is_string = peek_token == Token::STRING; | |
| 2293 bool is_identifier = peek_token == Token::IDENTIFIER; | |
| 2294 bool is_this = peek_token == Token::THIS; | |
| 2295 if (is_number || is_literal || is_string || is_identifier || is_this) { | |
| 2296 // PeekAhead() is expensive & may not always be called, so we only call it | |
| 2297 // after checking peek(). | |
| 2298 Token::Value peek_ahead = PeekAhead(); | |
| 2299 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || | |
| 2300 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { | |
| 2301 Scanner::Location pos = scanner()->peek_location(); | |
| 2302 if (is_string) { | |
| 2303 FuncNameInferrer::State fni_state(fni_); | |
| 2304 classifier->RecordBindingPatternError( | |
| 2305 pos, MessageTemplate::kUnexpectedTokenString); | |
| 2306 Consume(Token::STRING); | |
| 2307 return this->ExpressionFromString(pos.beg_pos, scanner(), factory()); | |
| 2308 } else if (is_this) { | |
| 2309 classifier->RecordBindingPatternError( | |
| 2310 pos, MessageTemplate::kUnexpectedToken, Token::Name(Token::THIS)); | |
| 2311 Consume(Token::THIS); | |
| 2312 return this->ThisExpression(scope(), factory(), pos.beg_pos); | |
| 2313 } else if (is_number) { | |
| 2314 classifier->RecordBindingPatternError( | |
| 2315 pos, MessageTemplate::kUnexpectedTokenNumber); | |
| 2316 Consume(peek_token); | |
| 2317 return this->ExpressionFromLiteral(peek_token, pos.beg_pos, scanner(), | |
| 2318 factory()); | |
| 2319 } else if (is_literal) { | |
| 2320 classifier->RecordBindingPatternError( | |
| 2321 pos, MessageTemplate::kUnexpectedToken, Token::Name(peek_token)); | |
| 2322 Consume(peek_token); | |
| 2323 return this->ExpressionFromLiteral(peek_token, pos.beg_pos, scanner(), | |
| 2324 factory()); | |
| 2325 } else if (is_identifier) { | |
| 2326 FuncNameInferrer::State fni_state(fni_); | |
|
marja
2016/07/28 10:01:29
I don't understand the expression classifying stuf
| |
| 2327 ExpressionClassifier arrow_formals_classifier( | |
| 2328 this, classifier->duplicate_finder()); | |
| 2329 IdentifierT name = | |
| 2330 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | |
| 2331 typename ParserBase<Traits>::ExpressionT shortcut_result = | |
| 2332 this->ExpressionFromIdentifier(name, pos.beg_pos, pos.end_pos, | |
| 2333 scope(), factory()); | |
| 2334 if (this->IsAssignableIdentifier(shortcut_result)) { | |
| 2335 arrow_formals_classifier.ForgiveAssignmentPatternError(); | |
| 2336 } | |
| 2337 classifier->Accumulate( | |
| 2338 &arrow_formals_classifier, | |
| 2339 ExpressionClassifier::StandardProductions | | |
| 2340 ExpressionClassifier::FormalParametersProductions | | |
| 2341 ExpressionClassifier::CoverInitializedNameProduction | | |
| 2342 ExpressionClassifier::AsyncArrowFormalParametersProduction | | |
| 2343 ExpressionClassifier::AsyncBindingPatternProduction, | |
| 2344 false); | |
| 2345 DCHECK(!Token::IsAssignmentOp(peek_ahead)); | |
| 2346 classifier->MergeNonPatterns(&arrow_formals_classifier); | |
| 2347 return shortcut_result; | |
| 2348 } else { | |
| 2349 UNREACHABLE(); | |
| 2350 } | |
| 2351 } | |
| 2352 } | |
| 2353 // No applicable shortcut found: Proceed w/ regular parsing. | |
| 2354 } | |
| 2355 | |
| 2280 // AssignmentExpression :: | 2356 // AssignmentExpression :: |
| 2281 // ConditionalExpression | 2357 // ConditionalExpression |
| 2282 // ArrowFunction | 2358 // ArrowFunction |
| 2283 // YieldExpression | 2359 // YieldExpression |
| 2284 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2360 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2285 bool is_destructuring_assignment = false; | 2361 bool is_destructuring_assignment = false; |
| 2286 int lhs_beg_pos = peek_position(); | 2362 int lhs_beg_pos = peek_position(); |
| 2287 | 2363 |
| 2288 if (peek() == Token::YIELD && is_generator()) { | 2364 if (peek() == Token::YIELD && is_generator()) { |
| 2289 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2365 return this->ParseYieldExpression(accept_IN, classifier, ok); |
| (...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3697 has_seen_constructor_ = true; | 3773 has_seen_constructor_ = true; |
| 3698 return; | 3774 return; |
| 3699 } | 3775 } |
| 3700 } | 3776 } |
| 3701 | 3777 |
| 3702 | 3778 |
| 3703 } // namespace internal | 3779 } // namespace internal |
| 3704 } // namespace v8 | 3780 } // namespace v8 |
| 3705 | 3781 |
| 3706 #endif // V8_PARSING_PARSER_BASE_H | 3782 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |