Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Unified Diff: src/preparser.h

Issue 1189743003: [destructuring] Implement parameter pattern matching. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Done Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 862b7fb40dd894b53dfcec80d36aedde5b441e3f..8c346b26681f5503545818dbef6ca9c06f0c4364 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -70,6 +70,8 @@ class ParserBase : public Traits {
typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
typedef typename Traits::Type::Literal LiteralT;
typedef typename Traits::Type::ObjectLiteralProperty ObjectLiteralPropertyT;
+ typedef typename Traits::Type::FormalParameterParsingState
+ FormalParameterParsingStateT;
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
@@ -555,7 +557,7 @@ class ParserBase : public Traits {
ExpressionT expr, bool* ok) {
if (classifier->is_valid_binding_pattern()) {
// A simple arrow formal parameter: IDENTIFIER => BODY.
- if (!allow_harmony_destructuring() && !this->IsIdentifier(expr)) {
+ if (!this->IsIdentifier(expr)) {
Traits::ReportMessageAt(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(scanner()->current_token()));
@@ -644,9 +646,9 @@ class ParserBase : public Traits {
ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseMemberExpressionContinuation(
ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
- ExpressionT ParseArrowFunctionLiteral(Scope* function_scope, bool has_rest,
- const ExpressionClassifier& classifier,
- bool* ok);
+ ExpressionT ParseArrowFunctionLiteral(
+ const FormalParameterParsingStateT& parsing_state,
+ const ExpressionClassifier& classifier, bool* ok);
ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
ExpressionClassifier* classifier, bool* ok);
void AddTemplateExpression(ExpressionT);
@@ -658,9 +660,10 @@ class ParserBase : public Traits {
ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier,
bool* ok);
- void ParseFormalParameter(Scope* scope, bool is_rest,
+ void ParseFormalParameter(bool is_rest,
+ FormalParameterParsingStateT* parsing_result,
ExpressionClassifier* classifier, bool* ok);
- int ParseFormalParameterList(Scope* scope, bool* has_rest,
+ int ParseFormalParameterList(FormalParameterParsingStateT* parsing_state,
ExpressionClassifier* classifier, bool* ok);
void CheckArityRestrictions(
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
@@ -1252,6 +1255,15 @@ class PreParserFactory {
};
+struct PreParserFormalParameterParsingState {
+ explicit PreParserFormalParameterParsingState(Scope* scope)
+ : scope(scope), has_rest(false), is_simple_parameter_list(true) {}
+ Scope* scope;
+ bool has_rest;
+ bool is_simple_parameter_list;
+};
+
+
class PreParser;
class PreParserTraits {
@@ -1278,6 +1290,7 @@ class PreParserTraits {
typedef PreParserExpressionList PropertyList;
typedef PreParserIdentifier FormalParameter;
typedef PreParserStatementList StatementList;
+ typedef PreParserFormalParameterParsingState FormalParameterParsingState;
// For constructing objects returned by the traversing functions.
typedef PreParserFactory Factory;
@@ -1516,19 +1529,23 @@ class PreParserTraits {
return PreParserExpressionList();
}
+ static void AddParameterInitializationBlock(
+ const PreParserFormalParameterParsingState& formal_parameters,
+ PreParserStatementList list, bool* ok) {}
+
V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool* ok) {
UNREACHABLE();
}
- V8_INLINE PreParserStatementList
- ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
- Variable* fvar, Token::Value fvar_init_op,
- FunctionKind kind, bool* ok);
+ V8_INLINE PreParserStatementList ParseEagerFunctionBody(
+ PreParserIdentifier function_name, int pos,
+ const PreParserFormalParameterParsingState& formal_parameters,
+ Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok);
V8_INLINE void ParseArrowFunctionFormalParameters(
- Scope* scope, PreParserExpression expression,
- const Scanner::Location& params_loc, bool* has_rest,
+ PreParserFormalParameterParsingState* parsing_state,
+ PreParserExpression expression, const Scanner::Location& params_loc,
Scanner::Location* duplicate_loc, bool* ok);
struct TemplateLiteralState {};
@@ -1555,7 +1572,7 @@ class PreParserTraits {
return !tag.IsNoTemplateTag();
}
- void DeclareFormalParameter(Scope* scope, PreParserExpression pattern,
+ void DeclareFormalParameter(void* parsing_state, PreParserExpression pattern,
ExpressionClassifier* classifier, bool is_rest) {}
void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
@@ -1706,6 +1723,7 @@ class PreParser : public ParserBase<PreParserTraits> {
int* expected_property_count, bool* ok);
V8_INLINE PreParserStatementList
ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
+ const FormalParameterParsingStateT& formal_parameters,
Variable* fvar, Token::Value fvar_init_op,
FunctionKind kind, bool* ok);
@@ -1751,8 +1769,8 @@ PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function,
void PreParserTraits::ParseArrowFunctionFormalParameters(
- Scope* scope, PreParserExpression params,
- const Scanner::Location& params_loc, bool* has_rest,
+ PreParserFormalParameterParsingState* parsing_state,
+ PreParserExpression params, const Scanner::Location& params_loc,
Scanner::Location* duplicate_loc, bool* ok) {
// TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter
// lists that are too long.
@@ -1760,8 +1778,9 @@ void PreParserTraits::ParseArrowFunctionFormalParameters(
PreParserStatementList PreParser::ParseEagerFunctionBody(
- PreParserIdentifier function_name, int pos, Variable* fvar,
- Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
+ PreParserIdentifier function_name, int pos,
+ const PreParserFormalParameterParsingState& formal_parameters,
+ Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
ParseStatementList(Token::RBRACE, ok);
@@ -1773,10 +1792,11 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
- PreParserIdentifier function_name, int pos, Variable* fvar,
- Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
- return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
- fvar_init_op, kind, ok);
+ PreParserIdentifier function_name, int pos,
+ const PreParserFormalParameterParsingState& formal_parameters,
+ Variable* fvar, Token::Value fvar_init_op, FunctionKind kind, bool* ok) {
+ return pre_parser_->ParseEagerFunctionBody(
+ function_name, pos, formal_parameters, fvar, fvar_init_op, kind, ok);
}
@@ -2154,20 +2174,22 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
Token::String(Token::RPAREN));
Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
+ FormalParameterParsingStateT parsing_state(scope);
scope->set_start_position(beg_pos);
ExpressionClassifier args_classifier;
- bool has_rest = false;
- result = this->ParseArrowFunctionLiteral(scope, has_rest,
- args_classifier, CHECK_OK);
+ result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier,
+ CHECK_OK);
} else if (allow_harmony_arrow_functions() &&
allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
// (...x) => y
Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
+ FormalParameterParsingStateT parsing_state(scope);
scope->set_start_position(beg_pos);
ExpressionClassifier args_classifier;
- const bool has_rest = true;
- this->ParseFormalParameter(scope, has_rest, &args_classifier, CHECK_OK);
+ const bool is_rest = true;
+ this->ParseFormalParameter(is_rest, &parsing_state, &args_classifier,
+ CHECK_OK);
if (peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest);
@@ -2175,8 +2197,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
return this->EmptyExpression();
}
Expect(Token::RPAREN, CHECK_OK);
- result = this->ParseArrowFunctionLiteral(scope, has_rest,
- args_classifier, CHECK_OK);
+ result = this->ParseArrowFunctionLiteral(parsing_state, args_classifier,
+ CHECK_OK);
} else {
// Heuristically try to detect immediately called functions before
// seeing the call parentheses.
@@ -2391,6 +2413,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
// Fall through.
default:
*name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
+ if (classifier->duplicate_finder() != nullptr && !*is_get && !*is_set &&
+ scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
+ classifier->RecordDuplicateFormalParameterError(scanner()->location());
arv (Not doing code reviews) 2015/06/19 19:25:26 The following is not supposed to be an error. f
Dmitry Lomov (no reviews) 2015/06/22 10:14:10 Done.
+ }
break;
}
@@ -2718,15 +2744,15 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
scope->set_start_position(lhs_location.beg_pos);
Scanner::Location duplicate_loc = Scanner::Location::invalid();
- bool has_rest = false;
- this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
+ FormalParameterParsingStateT parsing_state(scope);
+ this->ParseArrowFunctionFormalParameters(&parsing_state, expression, loc,
&duplicate_loc, CHECK_OK);
if (duplicate_loc.IsValid()) {
arrow_formals_classifier.RecordDuplicateFormalParameterError(
duplicate_loc);
}
expression = this->ParseArrowFunctionLiteral(
- scope, has_rest, arrow_formals_classifier, CHECK_OK);
+ parsing_state, arrow_formals_classifier, CHECK_OK);
return expression;
}
@@ -3489,9 +3515,9 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
template <class Traits>
-void ParserBase<Traits>::ParseFormalParameter(Scope* scope, bool is_rest,
- ExpressionClassifier* classifier,
- bool* ok) {
+void ParserBase<Traits>::ParseFormalParameter(
+ bool is_rest, FormalParameterParsingStateT* parsing_state,
+ ExpressionClassifier* classifier, bool* ok) {
// FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter]
wingo 2015/06/22 10:22:14 if is_rest is true then we are parsing BindingRest
@@ -3508,13 +3534,19 @@ void ParserBase<Traits>::ParseFormalParameter(Scope* scope, bool is_rest,
return;
}
- Traits::DeclareFormalParameter(scope, pattern, classifier, is_rest);
+ if (parsing_state->is_simple_parameter_list) {
+ parsing_state->is_simple_parameter_list =
+ !is_rest && Traits::IsIdentifier(pattern);
+ }
+ parsing_state->has_rest = is_rest;
+ Traits::DeclareFormalParameter(parsing_state, pattern, classifier, is_rest);
}
template <class Traits>
int ParserBase<Traits>::ParseFormalParameterList(
- Scope* scope, bool* is_rest, ExpressionClassifier* classifier, bool* ok) {
+ FormalParameterParsingStateT* parsing_state,
+ ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield,GeneratorParameter] :
// [empty]
// FormalParameterList[?Yield, ?GeneratorParameter]
@@ -3538,12 +3570,12 @@ int ParserBase<Traits>::ParseFormalParameterList(
*ok = false;
return -1;
}
- *is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
- ParseFormalParameter(scope, *is_rest, classifier, ok);
+ bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
+ ParseFormalParameter(is_rest, parsing_state, classifier, ok);
if (!*ok) return -1;
- } while (!*is_rest && Check(Token::COMMA));
+ } while (!parsing_state->has_rest && Check(Token::COMMA));
- if (*is_rest && peek() == Token::COMMA) {
+ if (parsing_state->has_rest && peek() == Token::COMMA) {
ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kParamAfterRest);
*ok = false;
@@ -3588,8 +3620,8 @@ void ParserBase<Traits>::CheckArityRestrictions(
template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseArrowFunctionLiteral(
- Scope* scope, bool has_rest, const ExpressionClassifier& formals_classifier,
- bool* ok) {
+ const FormalParameterParsingStateT& formal_parameters,
+ const ExpressionClassifier& formals_classifier, bool* ok) {
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
// ASI inserts `;` after arrow parameters if a line terminator is found.
// `=> ...` is never a valid expression, so report as syntax error.
@@ -3600,15 +3632,16 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
}
typename Traits::Type::StatementList body;
- int num_parameters = scope->num_parameters();
+ int num_parameters = formal_parameters.scope->num_parameters();
int materialized_literal_count = -1;
int expected_property_count = -1;
Scanner::Location super_loc;
{
typename Traits::Type::Factory function_factory(ast_value_factory());
- FunctionState function_state(&function_state_, &scope_, scope,
- kArrowFunction, &function_factory);
+ FunctionState function_state(&function_state_, &scope_,
+ formal_parameters.scope, kArrowFunction,
+ &function_factory);
Expect(Token::ARROW, CHECK_OK);
@@ -3623,8 +3656,8 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
&expected_property_count, CHECK_OK);
} else {
body = this->ParseEagerFunctionBody(
- this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL,
- Token::INIT_VAR, kArrowFunction, CHECK_OK);
+ this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
+ NULL, Token::INIT_VAR, kArrowFunction, CHECK_OK);
wingo 2015/06/22 10:22:14 Nit: const Variable *name = nullptr, pass by name?
materialized_literal_count =
function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
@@ -3638,13 +3671,14 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
ParseAssignmentExpression(true, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK);
body = this->NewStatementList(1, zone());
+ this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
body->Add(factory()->NewReturnStatement(expression, pos), zone());
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
}
super_loc = function_state.super_location();
- scope->set_end_position(scanner()->location().end_pos);
+ formal_parameters.scope->set_end_position(scanner()->location().end_pos);
// Arrow function formal parameters are parsed as StrictFormalParameterList,
// which is not the same as "parameters of a strict function"; it only means
@@ -3656,21 +3690,23 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
// Validate strict mode.
if (is_strict(language_mode())) {
- CheckStrictOctalLiteral(scope->start_position(),
+ CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
scanner()->location().end_pos, CHECK_OK);
- this->CheckConflictingVarDeclarations(scope, CHECK_OK);
+ this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
}
}
FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
- this->EmptyIdentifierString(), ast_value_factory(), scope, body,
- materialized_literal_count, expected_property_count, num_parameters,
+ this->EmptyIdentifierString(), ast_value_factory(),
+ formal_parameters.scope, body, materialized_literal_count,
+ expected_property_count, num_parameters,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
- scope->start_position());
+ formal_parameters.scope->start_position());
- function_literal->set_function_token_position(scope->start_position());
+ function_literal->set_function_token_position(
+ formal_parameters.scope->start_position());
if (super_loc.IsValid()) function_state_->set_super_location(super_loc);
if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);

Powered by Google App Engine
This is Rietveld 408576698