[es6] Refactor FormalParameter
Store arity in FormalParameters; store name (instead of var) and is_rest flag in individual parameters. Ensure that the arity is always maintained consistently. This is preparation for more parameter destructuring adjustments. In particular, a follow-up CL will separate parameter recording from declaring the variables. R=adamk@chromium.org, littledan@chromium.org BUG=v8:811 LOG=N Review URL: https://codereview.chromium.org/1259013003 Cr-Commit-Position: refs/heads/master@{#30002}
This commit is contained in:
parent
479e0c0347
commit
56bd11a11a
@ -917,7 +917,7 @@ Parser::Parser(ParseInfo* info)
|
||||
set_allow_harmony_unicode(FLAG_harmony_unicode);
|
||||
set_allow_harmony_computed_property_names(
|
||||
FLAG_harmony_computed_property_names);
|
||||
set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
|
||||
set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
|
||||
set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
|
||||
set_allow_harmony_destructuring(FLAG_harmony_destructuring);
|
||||
set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
|
||||
@ -3854,7 +3854,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
|
||||
ParserFormalParameters* parameters, Expression* expr,
|
||||
const Scanner::Location& params_loc,
|
||||
Scanner::Location* duplicate_loc, bool* ok) {
|
||||
if (parameters->scope->num_parameters() >= Code::kMaxArguments) {
|
||||
if (parameters->arity >= Code::kMaxArguments) {
|
||||
ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
|
||||
*ok = false;
|
||||
return;
|
||||
@ -3908,6 +3908,7 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
|
||||
parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
|
||||
}
|
||||
|
||||
++parameters->arity;
|
||||
ExpressionClassifier classifier;
|
||||
DeclareFormalParameter(parameters, expr, is_rest, &classifier);
|
||||
if (!duplicate_loc->IsValid()) {
|
||||
@ -3996,7 +3997,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
: NewScope(scope_, FUNCTION_SCOPE, kind);
|
||||
scope->SetLanguageMode(language_mode);
|
||||
ZoneList<Statement*>* body = NULL;
|
||||
int arity = 0;
|
||||
int arity = -1;
|
||||
int materialized_literal_count = -1;
|
||||
int expected_property_count = -1;
|
||||
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
||||
@ -4030,7 +4031,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
int start_position = scanner()->location().beg_pos;
|
||||
scope_->set_start_position(start_position);
|
||||
ParserFormalParameters formals(scope);
|
||||
arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
|
||||
ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
|
||||
arity = formals.arity;
|
||||
DCHECK(arity == formals.params.length());
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
int formals_end_position = scanner()->location().end_pos;
|
||||
|
||||
@ -4294,7 +4297,8 @@ Block* Parser::BuildParameterInitializationBlock(
|
||||
DCHECK(scope_->is_function_scope());
|
||||
Block* init_block =
|
||||
factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
|
||||
for (auto parameter : parameters.params) {
|
||||
for (int i = 0; i < parameters.params.length(); ++i) {
|
||||
auto parameter = parameters.params[i];
|
||||
if (parameter.pattern == nullptr) continue;
|
||||
DeclarationDescriptor descriptor;
|
||||
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
|
||||
@ -4309,7 +4313,7 @@ Block* Parser::BuildParameterInitializationBlock(
|
||||
descriptor.init_op = Token::INIT_LET;
|
||||
DeclarationParsingResult::Declaration decl(
|
||||
parameter.pattern, parameter.pattern->position(),
|
||||
factory()->NewVariableProxy(parameter.var));
|
||||
factory()->NewVariableProxy(parameters.scope->parameter(i)));
|
||||
PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
|
||||
&decl, nullptr, CHECK_OK);
|
||||
}
|
||||
@ -4477,7 +4481,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
|
||||
SET_ALLOW(harmony_sloppy_let);
|
||||
SET_ALLOW(harmony_unicode);
|
||||
SET_ALLOW(harmony_computed_property_names);
|
||||
SET_ALLOW(harmony_rest_params);
|
||||
SET_ALLOW(harmony_rest_parameters);
|
||||
SET_ALLOW(harmony_spreadcalls);
|
||||
SET_ALLOW(harmony_destructuring);
|
||||
SET_ALLOW(harmony_spread_arrays);
|
||||
|
17
src/parser.h
17
src/parser.h
@ -541,10 +541,11 @@ class SingletonLogger;
|
||||
|
||||
struct ParserFormalParameters : public PreParserFormalParameters {
|
||||
struct Parameter {
|
||||
Parameter(Variable* var, Expression* pattern)
|
||||
: var(var), pattern(pattern) {}
|
||||
Variable* var;
|
||||
Parameter(const AstRawString* name, Expression* pattern, bool is_rest)
|
||||
: name(name), pattern(pattern), is_rest(is_rest) {}
|
||||
const AstRawString* name;
|
||||
Expression* pattern;
|
||||
bool is_rest;
|
||||
};
|
||||
|
||||
explicit ParserFormalParameters(Scope* scope)
|
||||
@ -552,8 +553,10 @@ struct ParserFormalParameters : public PreParserFormalParameters {
|
||||
|
||||
ZoneList<Parameter> params;
|
||||
|
||||
void AddParameter(Variable* var, Expression* pattern) {
|
||||
params.Add(Parameter(var, pattern), scope->zone());
|
||||
void AddParameter(
|
||||
const AstRawString* name, Expression* pattern, bool is_rest) {
|
||||
params.Add(Parameter(name, pattern, is_rest), scope->zone());
|
||||
DCHECK_EQ(arity, params.length());
|
||||
}
|
||||
};
|
||||
|
||||
@ -579,7 +582,7 @@ class ParserTraits {
|
||||
typedef ObjectLiteral::Property* ObjectLiteralProperty;
|
||||
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
|
||||
typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
|
||||
typedef const v8::internal::AstRawString* FormalParameter;
|
||||
typedef ParserFormalParameters::Parameter FormalParameter;
|
||||
typedef ParserFormalParameters FormalParameters;
|
||||
typedef ZoneList<v8::internal::Statement*>* StatementList;
|
||||
|
||||
@ -1320,7 +1323,7 @@ void ParserTraits::DeclareFormalParameter(
|
||||
VariableMode mode = is_simple ? VAR : TEMPORARY;
|
||||
Variable* var =
|
||||
parameters->scope->DeclareParameter(name, mode, is_rest, &is_duplicate);
|
||||
parameters->AddParameter(var, is_simple ? nullptr : pattern);
|
||||
parameters->AddParameter(name, is_simple ? nullptr : pattern, is_rest);
|
||||
if (is_duplicate) {
|
||||
classifier->RecordDuplicateFormalParameterError(
|
||||
parser_->scanner()->location());
|
||||
|
@ -1053,11 +1053,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
int start_position = scanner()->location().beg_pos;
|
||||
function_scope->set_start_position(start_position);
|
||||
PreParserFormalParameters formals(nullptr);
|
||||
int arity = ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
|
||||
ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
int formals_end_position = scanner()->location().end_pos;
|
||||
|
||||
CheckArityRestrictions(arity, arity_restriction,
|
||||
CheckArityRestrictions(formals.arity, arity_restriction,
|
||||
formals.has_rest, start_position,
|
||||
formals_end_position, CHECK_OK);
|
||||
|
||||
|
@ -103,7 +103,7 @@ class ParserBase : public Traits {
|
||||
allow_harmony_sloppy_(false),
|
||||
allow_harmony_sloppy_let_(false),
|
||||
allow_harmony_computed_property_names_(false),
|
||||
allow_harmony_rest_params_(false),
|
||||
allow_harmony_rest_parameters_(false),
|
||||
allow_harmony_spreadcalls_(false),
|
||||
allow_harmony_destructuring_(false),
|
||||
allow_harmony_spread_arrays_(false),
|
||||
@ -121,7 +121,7 @@ class ParserBase : public Traits {
|
||||
ALLOW_ACCESSORS(harmony_sloppy);
|
||||
ALLOW_ACCESSORS(harmony_sloppy_let);
|
||||
ALLOW_ACCESSORS(harmony_computed_property_names);
|
||||
ALLOW_ACCESSORS(harmony_rest_params);
|
||||
ALLOW_ACCESSORS(harmony_rest_parameters);
|
||||
ALLOW_ACCESSORS(harmony_spreadcalls);
|
||||
ALLOW_ACCESSORS(harmony_destructuring);
|
||||
ALLOW_ACCESSORS(harmony_spread_arrays);
|
||||
@ -702,8 +702,8 @@ class ParserBase : public Traits {
|
||||
void ParseFormalParameter(bool is_rest,
|
||||
FormalParametersT* parameters,
|
||||
ExpressionClassifier* classifier, bool* ok);
|
||||
int ParseFormalParameterList(FormalParametersT* parameters,
|
||||
ExpressionClassifier* classifier, bool* ok);
|
||||
void ParseFormalParameterList(FormalParametersT* parameters,
|
||||
ExpressionClassifier* classifier, bool* ok);
|
||||
void CheckArityRestrictions(
|
||||
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
||||
bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
|
||||
@ -801,7 +801,7 @@ class ParserBase : public Traits {
|
||||
bool allow_harmony_sloppy_;
|
||||
bool allow_harmony_sloppy_let_;
|
||||
bool allow_harmony_computed_property_names_;
|
||||
bool allow_harmony_rest_params_;
|
||||
bool allow_harmony_rest_parameters_;
|
||||
bool allow_harmony_spreadcalls_;
|
||||
bool allow_harmony_destructuring_;
|
||||
bool allow_harmony_spread_arrays_;
|
||||
@ -1315,10 +1315,12 @@ class PreParserFactory {
|
||||
struct PreParserFormalParameters {
|
||||
explicit PreParserFormalParameters(Scope* scope)
|
||||
: scope(scope),
|
||||
arity(0),
|
||||
has_rest(false),
|
||||
is_simple(true),
|
||||
materialized_literals_count(0) {}
|
||||
Scope* scope;
|
||||
int arity;
|
||||
bool has_rest;
|
||||
bool is_simple;
|
||||
int materialized_literals_count;
|
||||
@ -2274,7 +2276,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
||||
result = this->ParseArrowFunctionLiteral(parameters, args_classifier,
|
||||
CHECK_OK);
|
||||
} else if (allow_harmony_arrow_functions() &&
|
||||
allow_harmony_rest_params() && Check(Token::ELLIPSIS)) {
|
||||
allow_harmony_rest_parameters() && Check(Token::ELLIPSIS)) {
|
||||
// (...x) => y
|
||||
Scope* scope =
|
||||
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
|
||||
@ -2386,7 +2388,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
|
||||
}
|
||||
Consume(Token::COMMA);
|
||||
bool is_rest = false;
|
||||
if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) {
|
||||
if (allow_harmony_rest_parameters() && peek() == Token::ELLIPSIS) {
|
||||
// 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
|
||||
// as the formal parameters of'(x, y, ...z) => foo', and is not itself a
|
||||
// valid expression or binding pattern.
|
||||
@ -3645,12 +3647,13 @@ void ParserBase<Traits>::ParseFormalParameter(
|
||||
*ok = false;
|
||||
return;
|
||||
}
|
||||
++parameters->arity;
|
||||
Traits::DeclareFormalParameter(parameters, pattern, is_rest, classifier);
|
||||
}
|
||||
|
||||
|
||||
template <class Traits>
|
||||
int ParserBase<Traits>::ParseFormalParameterList(
|
||||
void ParserBase<Traits>::ParseFormalParameterList(
|
||||
FormalParametersT* parameters, ExpressionClassifier* classifier, bool* ok) {
|
||||
// FormalParameters[Yield,GeneratorParameter] :
|
||||
// [empty]
|
||||
@ -3666,29 +3669,26 @@ int ParserBase<Traits>::ParseFormalParameterList(
|
||||
// FormalsList[?Yield, ?GeneratorParameter] ,
|
||||
// FormalParameter[?Yield,?GeneratorParameter]
|
||||
|
||||
int arity = 0;
|
||||
DCHECK_EQ(0, parameters->arity);
|
||||
|
||||
if (peek() != Token::RPAREN) {
|
||||
do {
|
||||
if (++arity > Code::kMaxArguments) {
|
||||
if (parameters->arity > Code::kMaxArguments) {
|
||||
ReportMessage(MessageTemplate::kTooManyParameters);
|
||||
*ok = false;
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
bool is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
|
||||
bool is_rest = allow_harmony_rest_parameters() && Check(Token::ELLIPSIS);
|
||||
ParseFormalParameter(is_rest, parameters, classifier, ok);
|
||||
if (!*ok) return -1;
|
||||
if (!*ok) return;
|
||||
} while (!parameters->has_rest && Check(Token::COMMA));
|
||||
|
||||
if (parameters->has_rest && peek() == Token::COMMA) {
|
||||
ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kParamAfterRest);
|
||||
*ok = false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return arity;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1457,7 +1457,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
|
||||
parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
|
||||
parser->set_allow_harmony_arrow_functions(
|
||||
flags.Contains(kAllowHarmonyArrowFunctions));
|
||||
parser->set_allow_harmony_rest_params(
|
||||
parser->set_allow_harmony_rest_parameters(
|
||||
flags.Contains(kAllowHarmonyRestParameters));
|
||||
parser->set_allow_harmony_spreadcalls(
|
||||
flags.Contains(kAllowHarmonySpreadCalls));
|
||||
|
Loading…
Reference in New Issue
Block a user