Commit 8be0499f authored by wingo's avatar wingo Committed by Commit bot

Allow eval/arguments in arrow functions

Originally landed in https://codereview.chromium.org/1061983004;
re-landing after re-landing formal parameter parsing refactors.

R=marja@chromium.org
BUG=v8:4020
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#27971}
parent d76c1193
......@@ -166,7 +166,9 @@ var kMessages = {
for_of_loop_initializer: ["for-of loop variable declaration may not have an initializer."],
for_inof_loop_multi_bindings: ["Invalid left-hand side in ", "%0", " loop: Must have a single binding."],
bad_getter_arity: ["Getter must not have any formal parameters."],
bad_setter_arity: ["Setter must have exactly one formal parameter."]
bad_setter_arity: ["Setter must have exactly one formal parameter."],
this_formal_parameter: ["'this' is not a valid formal parameter name"],
duplicate_arrow_function_formal_parameter: ["Arrow function may not have duplicate parameter names"]
};
......
This diff is collapsed.
......@@ -696,7 +696,6 @@ class ParserTraits {
static Expression* EmptyExpression() {
return NULL;
}
static Expression* EmptyArrowParamList() { return NULL; }
static Literal* EmptyLiteral() {
return NULL;
}
......@@ -746,11 +745,6 @@ class ParserTraits {
V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type,
FunctionKind kind = kNormalFunction);
// Utility functions
int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
FormalParameterErrorLocations* locs,
bool* ok);
bool DeclareFormalParameter(Scope* scope, const AstRawString* name,
bool is_rest) {
bool is_duplicate = false;
......@@ -764,6 +758,14 @@ class ParserTraits {
return is_duplicate;
}
void DeclareArrowFunctionParameters(Scope* scope, Expression* expr,
const Scanner::Location& params_loc,
FormalParameterErrorLocations* error_locs,
bool* ok);
void ParseArrowFunctionFormalParameters(
Scope* scope, Expression* params, const Scanner::Location& params_loc,
FormalParameterErrorLocations* error_locs, bool* is_rest, bool* ok);
// Temporary glue; these functions will move to ParserBase.
Expression* ParseV8Intrinsic(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
......@@ -1060,8 +1062,6 @@ class Parser : public ParserBase<ParserTraits> {
ScriptCompiler::CompileOptions compile_options_;
ParseData* cached_parse_data_;
bool parsing_lazy_arrow_parameters_; // for lazily parsed arrow functions.
PendingCompilationErrorHandler pending_error_handler_;
// Other information which will be stored in Parser and moved to Isolate after
......
This diff is collapsed.
......@@ -3502,20 +3502,23 @@ TEST(ErrorsArrowFunctions) {
"(x, (y, z)) => 0",
"((x, y), z) => 0",
// Parameter lists are always validated as strict, so those are errors.
"eval => {}",
"arguments => {}",
"yield => {}",
"interface => {}",
"(eval) => {}",
"(arguments) => {}",
"(yield) => {}",
"(interface) => {}",
"(eval, bar) => {}",
"(bar, eval) => {}",
"(bar, arguments) => {}",
"(bar, yield) => {}",
"(bar, interface) => {}",
// Arrow function formal parameters are parsed as StrictFormalParameters,
// which confusingly only implies that there are no duplicates. Words
// reserved in strict mode, and eval or arguments, are indeed valid in
// sloppy mode.
"eval => { 'use strict'; 0 }",
"arguments => { 'use strict'; 0 }",
"yield => { 'use strict'; 0 }",
"interface => { 'use strict'; 0 }",
"(eval) => { 'use strict'; 0 }",
"(arguments) => { 'use strict'; 0 }",
"(yield) => { 'use strict'; 0 }",
"(interface) => { 'use strict'; 0 }",
"(eval, bar) => { 'use strict'; 0 }",
"(bar, eval) => { 'use strict'; 0 }",
"(bar, arguments) => { 'use strict'; 0 }",
"(bar, yield) => { 'use strict'; 0 }",
"(bar, interface) => { 'use strict'; 0 }",
// TODO(aperez): Detecting duplicates does not work in PreParser.
// "(bar, bar) => {}",
......@@ -3622,6 +3625,66 @@ TEST(NoErrorsArrowFunctions) {
}
TEST(ArrowFunctionsSloppyParameterNames) {
const char* strong_context_data[][2] = {
{"'use strong'; ", ";"},
{"'use strong'; bar ? (", ") : baz;"},
{"'use strong'; bar ? baz : (", ");"},
{"'use strong'; bar, ", ";"},
{"'use strong'; ", ", bar;"},
{NULL, NULL}
};
const char* strict_context_data[][2] = {
{"'use strict'; ", ";"},
{"'use strict'; bar ? (", ") : baz;"},
{"'use strict'; bar ? baz : (", ");"},
{"'use strict'; bar, ", ";"},
{"'use strict'; ", ", bar;"},
{NULL, NULL}
};
const char* sloppy_context_data[][2] = {
{"", ";"},
{"bar ? (", ") : baz;"},
{"bar ? baz : (", ");"},
{"bar, ", ";"},
{"", ", bar;"},
{NULL, NULL}
};
const char* statement_data[] = {
"eval => {}",
"arguments => {}",
"yield => {}",
"interface => {}",
"(eval) => {}",
"(arguments) => {}",
"(yield) => {}",
"(interface) => {}",
"(eval, bar) => {}",
"(bar, eval) => {}",
"(bar, arguments) => {}",
"(bar, yield) => {}",
"(bar, interface) => {}",
"(interface, eval) => {}",
"(interface, arguments) => {}",
"(eval, interface) => {}",
"(arguments, interface) => {}",
NULL
};
static const ParserFlag always_flags[] = { kAllowHarmonyArrowFunctions,
kAllowStrongMode};
RunParserSyncTest(strong_context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(sloppy_context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
TEST(SuperNoErrors) {
// Tests that parser and preparser accept 'super' keyword in right places.
const char* context_data[][2] = {
......
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