Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index 4774e04b2481ce6925585ab53251852fe2398849..fce0ffd67acf8bc2cae9af5812563a1ac8ce82a7 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -1550,8 +1550,6 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
case Token::NULL_LITERAL: |
case Token::TRUE_LITERAL: |
case Token::FALSE_LITERAL: |
- BindingPatternUnexpectedToken(classifier); |
- return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
vogelheim
2016/07/28 09:35:01
[drive-by cleanup]
|
case Token::SMI: |
case Token::NUMBER: |
BindingPatternUnexpectedToken(classifier); |
@@ -2277,6 +2275,84 @@ typename ParserBase<Traits>::ExpressionT |
ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
ExpressionClassifier* classifier, |
bool* ok) { |
+ // 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
|
+ // parsing time and should be functionally neutral. When we encounter |
+ // [SMI|NUMBER|{NULL,TRUE,FALSE}_LITERAL|THIS|STRING|IDENTIFIER] |
+ // followed by |
+ // [COMMA|RPAREN|RBRACK|SEMICOLON] |
+ // then this will result in a single AST node. Instead of parsing this |
+ // 'properly' (a call chain 11-levels deep), we will just generate the |
+ // appropriate AST nodes right here. |
+ { |
+ Token::Value peek_token = peek(); |
+ bool is_number = peek_token == Token::SMI || peek_token == Token::NUMBER; |
+ bool is_literal = peek_token == Token::NULL_LITERAL || |
+ peek_token == Token::TRUE_LITERAL || |
+ peek_token == Token::FALSE_LITERAL; |
+ bool is_string = peek_token == Token::STRING; |
+ bool is_identifier = peek_token == Token::IDENTIFIER; |
+ bool is_this = peek_token == Token::THIS; |
+ if (is_number || is_literal || is_string || is_identifier || is_this) { |
+ // PeekAhead() is expensive & may not always be called, so we only call it |
+ // after checking peek(). |
+ Token::Value peek_ahead = PeekAhead(); |
+ if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || |
+ peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { |
+ Scanner::Location pos = scanner()->peek_location(); |
+ if (is_string) { |
+ FuncNameInferrer::State fni_state(fni_); |
+ classifier->RecordBindingPatternError( |
+ pos, MessageTemplate::kUnexpectedTokenString); |
+ Consume(Token::STRING); |
+ return this->ExpressionFromString(pos.beg_pos, scanner(), factory()); |
+ } else if (is_this) { |
+ classifier->RecordBindingPatternError( |
+ pos, MessageTemplate::kUnexpectedToken, Token::Name(Token::THIS)); |
+ Consume(Token::THIS); |
+ return this->ThisExpression(scope(), factory(), pos.beg_pos); |
+ } else if (is_number) { |
+ classifier->RecordBindingPatternError( |
+ pos, MessageTemplate::kUnexpectedTokenNumber); |
+ Consume(peek_token); |
+ return this->ExpressionFromLiteral(peek_token, pos.beg_pos, scanner(), |
+ factory()); |
+ } else if (is_literal) { |
+ classifier->RecordBindingPatternError( |
+ pos, MessageTemplate::kUnexpectedToken, Token::Name(peek_token)); |
+ Consume(peek_token); |
+ return this->ExpressionFromLiteral(peek_token, pos.beg_pos, scanner(), |
+ factory()); |
+ } else if (is_identifier) { |
+ FuncNameInferrer::State fni_state(fni_); |
marja
2016/07/28 10:01:29
I don't understand the expression classifying stuf
|
+ ExpressionClassifier arrow_formals_classifier( |
+ this, classifier->duplicate_finder()); |
+ IdentifierT name = |
+ ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
+ typename ParserBase<Traits>::ExpressionT shortcut_result = |
+ this->ExpressionFromIdentifier(name, pos.beg_pos, pos.end_pos, |
+ scope(), factory()); |
+ if (this->IsAssignableIdentifier(shortcut_result)) { |
+ arrow_formals_classifier.ForgiveAssignmentPatternError(); |
+ } |
+ classifier->Accumulate( |
+ &arrow_formals_classifier, |
+ ExpressionClassifier::StandardProductions | |
+ ExpressionClassifier::FormalParametersProductions | |
+ ExpressionClassifier::CoverInitializedNameProduction | |
+ ExpressionClassifier::AsyncArrowFormalParametersProduction | |
+ ExpressionClassifier::AsyncBindingPatternProduction, |
+ false); |
+ DCHECK(!Token::IsAssignmentOp(peek_ahead)); |
+ classifier->MergeNonPatterns(&arrow_formals_classifier); |
+ return shortcut_result; |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ } |
+ } |
+ // No applicable shortcut found: Proceed w/ regular parsing. |
+ } |
+ |
// AssignmentExpression :: |
// ConditionalExpression |
// ArrowFunction |