Commit 1447f743 authored by adamk's avatar adamk Committed by Commit bot

[cleanup] Make control flow in ParsePrimaryExpression more consistent

The previous code had a mix of breaks, early returns, and switch/case/if
with fallthrough. Now the pattern is to either return for known errors
or break to the bottom of the switch for unhandled tokens.

Also cleaned up random other stuff in the function: removed unnecessary
local vars, shortened position-fetching calls.

Review URL: https://codereview.chromium.org/1412313009

Cr-Commit-Position: refs/heads/master@{#31843}
parent e33c4b45
...@@ -2246,11 +2246,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2246,11 +2246,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
// TemplateLiteral // TemplateLiteral
// do Block // do Block
int beg_pos = scanner()->peek_location().beg_pos; int beg_pos = peek_position();
int end_pos = scanner()->peek_location().end_pos; switch (peek()) {
ExpressionT result = this->EmptyExpression();
Token::Value token = peek();
switch (token) {
case Token::THIS: { case Token::THIS: {
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
Consume(Token::THIS); Consume(Token::THIS);
...@@ -2260,29 +2257,22 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2260,29 +2257,22 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
if (IsClassConstructor(function_state_->kind())) { if (IsClassConstructor(function_state_->kind())) {
ReportMessage(MessageTemplate::kStrongConstructorThis); ReportMessage(MessageTemplate::kStrongConstructorThis);
*ok = false; *ok = false;
break; return this->EmptyExpression();
} }
} }
result = this->ThisExpression(scope_, factory(), beg_pos); return this->ThisExpression(scope_, factory(), beg_pos);
break;
} }
case Token::NULL_LITERAL: case Token::NULL_LITERAL:
case Token::TRUE_LITERAL: case Token::TRUE_LITERAL:
case Token::FALSE_LITERAL: case Token::FALSE_LITERAL:
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
Next(); return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
result =
this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
break;
case Token::SMI: case Token::SMI:
case Token::NUMBER: case Token::NUMBER:
classifier->RecordBindingPatternError( classifier->RecordBindingPatternError(
scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
Next(); return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
result =
this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
break;
case Token::IDENTIFIER: case Token::IDENTIFIER:
case Token::LET: case Token::LET:
...@@ -2291,46 +2281,40 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2291,46 +2281,40 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
case Token::FUTURE_STRICT_RESERVED_WORD: { case Token::FUTURE_STRICT_RESERVED_WORD: {
// Using eval or arguments in this context is OK even in strict mode. // Using eval or arguments in this context is OK even in strict mode.
IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, return this->ExpressionFromIdentifier(
factory()); name, beg_pos, scanner()->location().end_pos, scope_, factory());
break;
} }
case Token::STRING: { case Token::STRING: {
classifier->RecordBindingPatternError( classifier->RecordBindingPatternError(
scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString); scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
Consume(Token::STRING); Consume(Token::STRING);
result = this->ExpressionFromString(beg_pos, scanner(), factory()); return this->ExpressionFromString(beg_pos, scanner(), factory());
break;
} }
case Token::ASSIGN_DIV: case Token::ASSIGN_DIV:
classifier->RecordBindingPatternError( classifier->RecordBindingPatternError(
scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); return this->ParseRegExpLiteral(true, classifier, ok);
break;
case Token::DIV: case Token::DIV:
classifier->RecordBindingPatternError( classifier->RecordBindingPatternError(
scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); return this->ParseRegExpLiteral(false, classifier, ok);
break;
case Token::LBRACK: case Token::LBRACK:
if (!allow_harmony_destructuring()) { if (!allow_harmony_destructuring()) {
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
} }
result = this->ParseArrayLiteral(classifier, CHECK_OK); return this->ParseArrayLiteral(classifier, ok);
break;
case Token::LBRACE: case Token::LBRACE:
if (!allow_harmony_destructuring()) { if (!allow_harmony_destructuring()) {
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
} }
result = this->ParseObjectLiteral(classifier, CHECK_OK); return this->ParseObjectLiteral(classifier, ok);
break;
case Token::LPAREN: case Token::LPAREN: {
// Arrow function formal parameters are either a single identifier or a // Arrow function formal parameters are either a single identifier or a
// list of BindingPattern productions enclosed in parentheses. // list of BindingPattern productions enclosed in parentheses.
// Parentheses are not valid on the LHS of a BindingPattern, so we use the // Parentheses are not valid on the LHS of a BindingPattern, so we use the
...@@ -2350,28 +2334,27 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2350,28 +2334,27 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
classifier->RecordBindingPatternError(scanner()->location(), classifier->RecordBindingPatternError(scanner()->location(),
MessageTemplate::kUnexpectedToken, MessageTemplate::kUnexpectedToken,
Token::String(Token::RPAREN)); Token::String(Token::RPAREN));
result = factory()->NewEmptyParentheses(beg_pos); return factory()->NewEmptyParentheses(beg_pos);
} else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) { } else if (allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
// (...x)=>x. The continuation that looks for the => is in // (...x)=>x. The continuation that looks for the => is in
// ParseAssignmentExpression. // ParseAssignmentExpression.
int ellipsis_pos = scanner()->location().beg_pos; int ellipsis_pos = position();
classifier->RecordExpressionError(scanner()->location(), classifier->RecordExpressionError(scanner()->location(),
MessageTemplate::kUnexpectedToken, MessageTemplate::kUnexpectedToken,
Token::String(Token::ELLIPSIS)); Token::String(Token::ELLIPSIS));
classifier->RecordNonSimpleParameter(); classifier->RecordNonSimpleParameter();
Scanner::Location expr_loc = scanner()->peek_location(); Scanner::Location expr_loc = scanner()->peek_location();
Token::Value tok = peek(); Token::Value tok = peek();
result = this->ParseAssignmentExpression(true, classifier, CHECK_OK); ExpressionT expr =
this->ParseAssignmentExpression(true, classifier, CHECK_OK);
// Patterns are not allowed as rest parameters. There is no way we can // Patterns are not allowed as rest parameters. There is no way we can
// succeed so go ahead and use the convenient ReportUnexpectedToken // succeed so go ahead and use the convenient ReportUnexpectedToken
// interface. // interface.
if (!Traits::IsIdentifier(result)) { if (!Traits::IsIdentifier(expr)) {
ReportUnexpectedTokenAt(expr_loc, tok); ReportUnexpectedTokenAt(expr_loc, tok);
*ok = false; *ok = false;
return this->EmptyExpression(); return this->EmptyExpression();
} }
result = factory()->NewSpread(result, ellipsis_pos);
if (peek() == Token::COMMA) { if (peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(), ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest); MessageTemplate::kParamAfterRest);
...@@ -2379,14 +2362,15 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2379,14 +2362,15 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression(); return this->EmptyExpression();
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
} else { return factory()->NewSpread(expr, ellipsis_pos);
}
// Heuristically try to detect immediately called functions before // Heuristically try to detect immediately called functions before
// seeing the call parentheses. // seeing the call parentheses.
parenthesized_function_ = (peek() == Token::FUNCTION); parenthesized_function_ = (peek() == Token::FUNCTION);
result = this->ParseExpression(true, classifier, CHECK_OK); ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
return expr;
} }
break;
case Token::CLASS: { case Token::CLASS: {
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
...@@ -2394,7 +2378,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2394,7 +2378,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
ReportMessage(MessageTemplate::kSloppyLexical); ReportMessage(MessageTemplate::kSloppyLexical);
*ok = false; *ok = false;
break; return this->EmptyExpression();
} }
int class_token_position = position(); int class_token_position = position();
IdentifierT name = this->EmptyIdentifier(); IdentifierT name = this->EmptyIdentifier();
...@@ -2405,10 +2389,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2405,10 +2389,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
CHECK_OK); CHECK_OK);
class_name_location = scanner()->location(); class_name_location = scanner()->location();
} }
result = this->ParseClassLiteral(name, class_name_location, return this->ParseClassLiteral(name, class_name_location,
is_strict_reserved_name, is_strict_reserved_name,
class_token_position, CHECK_OK); class_token_position, ok);
break;
} }
case Token::TEMPLATE_SPAN: case Token::TEMPLATE_SPAN:
...@@ -2416,35 +2399,29 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -2416,35 +2399,29 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
classifier->RecordBindingPatternError( classifier->RecordBindingPatternError(
scanner()->peek_location(), scanner()->peek_location(),
MessageTemplate::kUnexpectedTemplateString); MessageTemplate::kUnexpectedTemplateString);
result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
classifier, CHECK_OK); classifier, ok);
break;
case Token::MOD: case Token::MOD:
if (allow_natives() || extension_ != NULL) { if (allow_natives() || extension_ != NULL) {
result = this->ParseV8Intrinsic(CHECK_OK); return this->ParseV8Intrinsic(ok);
break;
} }
break;
case Token::DO: case Token::DO:
// TODO(caitp): reorganize ParsePrimaryExpression() to not require this if (allow_harmony_do_expressions()) {
// extra `token == Token::DO` test due to potential fall-through
if (token == Token::DO && allow_harmony_do_expressions()) {
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
result = Traits::ParseDoExpression(CHECK_OK); return Traits::ParseDoExpression(ok);
break;
} }
// If we're not allowing special syntax we fall-through to the break;
// default case.
default: { default:
Next(); break;
ReportUnexpectedToken(token);
*ok = false;
}
} }
return result; ReportUnexpectedToken(Next());
*ok = false;
return this->EmptyExpression();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment