[parser] report SyntaxError if rest parameter used in Setter MethodDefinition
BUG=v8:4107, v8:2159 LOG=N R=arv@chromium.org Review URL: https://codereview.chromium.org/1141223002 Cr-Commit-Position: refs/heads/master@{#28454}
This commit is contained in:
parent
5bd4f9dd5a
commit
e160e6debb
@ -320,6 +320,8 @@ class CallSite {
|
||||
T(NoCatchOrFinally, "Missing catch or finally after try") \
|
||||
T(NotIsvar, "builtin %%IS_VAR: not a variable") \
|
||||
T(ParamAfterRest, "Rest parameter must be last formal parameter") \
|
||||
T(BadSetterRestParameter, \
|
||||
"Setter function argument must not be a rest parameter") \
|
||||
T(ParenthesisInArgString, "Function arg string contains parenthesis") \
|
||||
T(SingleFunctionLiteral, "Single function literal required") \
|
||||
T(SloppyLexical, \
|
||||
|
@ -3892,8 +3892,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
int formals_end_position = scanner()->location().end_pos;
|
||||
|
||||
CheckArityRestrictions(num_parameters, arity_restriction, start_position,
|
||||
formals_end_position, CHECK_OK);
|
||||
CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
|
||||
start_position, formals_end_position, CHECK_OK);
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK);
|
||||
|
||||
|
@ -1034,21 +1034,21 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
&factory);
|
||||
ExpressionClassifier formals_classifier;
|
||||
|
||||
bool is_rest = false;
|
||||
bool has_rest = false;
|
||||
Expect(Token::LPAREN, CHECK_OK);
|
||||
int start_position = scanner()->location().beg_pos;
|
||||
function_scope->set_start_position(start_position);
|
||||
int num_parameters;
|
||||
{
|
||||
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
||||
num_parameters = ParseFormalParameterList(&duplicate_finder, &is_rest,
|
||||
num_parameters = ParseFormalParameterList(&duplicate_finder, &has_rest,
|
||||
&formals_classifier, CHECK_OK);
|
||||
}
|
||||
Expect(Token::RPAREN, CHECK_OK);
|
||||
int formals_end_position = scanner()->location().end_pos;
|
||||
|
||||
CheckArityRestrictions(num_parameters, arity_restriction, start_position,
|
||||
formals_end_position, CHECK_OK);
|
||||
CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
|
||||
start_position, formals_end_position, CHECK_OK);
|
||||
|
||||
// See Parser::ParseFunctionLiteral for more information about lazy parsing
|
||||
// and lazy compilation.
|
||||
@ -1068,7 +1068,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
// function, since the function can declare itself strict.
|
||||
CheckFunctionName(language_mode(), kind, function_name,
|
||||
name_is_strict_reserved, function_name_location, CHECK_OK);
|
||||
const bool strict_formal_parameters = is_rest || IsConciseMethod(kind);
|
||||
const bool strict_formal_parameters = has_rest || IsConciseMethod(kind);
|
||||
const bool allow_duplicate_parameters =
|
||||
is_sloppy(language_mode()) && !strict_formal_parameters;
|
||||
ValidateFormalParameters(&formals_classifier, language_mode(),
|
||||
|
@ -893,7 +893,7 @@ class ParserBase : public Traits {
|
||||
ExpressionClassifier* classifier, bool* ok);
|
||||
void CheckArityRestrictions(
|
||||
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
||||
int formals_start_pos, int formals_end_pos, bool* ok);
|
||||
bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
|
||||
|
||||
// Checks if the expression is a valid reference expression (e.g., on the
|
||||
// left-hand side of assignments). Although ruled out by ECMA as early errors,
|
||||
@ -3657,7 +3657,7 @@ int ParserBase<Traits>::ParseFormalParameterList(
|
||||
template <class Traits>
|
||||
void ParserBase<Traits>::CheckArityRestrictions(
|
||||
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
||||
int formals_start_pos, int formals_end_pos, bool* ok) {
|
||||
bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok) {
|
||||
switch (arity_restriction) {
|
||||
case FunctionLiteral::GETTER_ARITY:
|
||||
if (param_count != 0) {
|
||||
@ -3672,6 +3672,11 @@ void ParserBase<Traits>::CheckArityRestrictions(
|
||||
MessageTemplate::kBadSetterArity);
|
||||
*ok = false;
|
||||
}
|
||||
if (has_rest) {
|
||||
ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
||||
MessageTemplate::kBadSetterRestParameter);
|
||||
*ok = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -5109,6 +5109,24 @@ TEST(ParseRestParametersErrors) {
|
||||
}
|
||||
|
||||
|
||||
TEST(RestParameterInSetterMethodError) {
|
||||
const char* context_data[][2] = {
|
||||
{"'use strict';({ set prop(", ") {} }).prop = 1;"},
|
||||
{"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
|
||||
{"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
|
||||
{"({ set prop(", ") {} }).prop = 1;"},
|
||||
{"(class { static set prop(", ") {} }).prop = 1;"},
|
||||
{"(new (class { set prop(", ") {} })).prop = 1;"},
|
||||
{nullptr, nullptr}};
|
||||
const char* data[] = {"...a", "...arguments", "...eval", nullptr};
|
||||
|
||||
static const ParserFlag always_flags[] = {
|
||||
kAllowHarmonyRestParameters, kAllowHarmonyClasses, kAllowHarmonySloppy};
|
||||
RunParserSyncTest(context_data, data, kError, nullptr, 0, always_flags,
|
||||
arraysize(always_flags));
|
||||
}
|
||||
|
||||
|
||||
TEST(RestParametersEvalArguments) {
|
||||
const char* strict_context_data[][2] =
|
||||
{{"'use strict';(function(",
|
||||
|
12
test/message/rest-param-class-setter-strict.js
Normal file
12
test/message/rest-param-class-setter-strict.js
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --harmony-rest-parameters --harmony-classes
|
||||
'use strict';
|
||||
|
||||
var _bad = "setting this should fail!";
|
||||
class C {
|
||||
get bad() { return _bad; }
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
}
|
4
test/message/rest-param-class-setter-strict.out
Normal file
4
test/message/rest-param-class-setter-strict.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
^^^^^^^^^
|
||||
SyntaxError: Setter function argument must not be a rest parameter
|
11
test/message/rest-param-object-setter-sloppy.js
Normal file
11
test/message/rest-param-object-setter-sloppy.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --harmony-rest-parameters
|
||||
|
||||
var _bad = "this should fail!";
|
||||
({
|
||||
get bad() { return _bad; },
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
});
|
4
test/message/rest-param-object-setter-sloppy.out
Normal file
4
test/message/rest-param-object-setter-sloppy.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:10: SyntaxError: Setter function argument must not be a rest parameter
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
^^^^^^^^^
|
||||
SyntaxError: Setter function argument must not be a rest parameter
|
12
test/message/rest-param-object-setter-strict.js
Normal file
12
test/message/rest-param-object-setter-strict.js
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Flags: --harmony-rest-parameters
|
||||
'use strict';
|
||||
|
||||
var _bad = "this should fail!";
|
||||
({
|
||||
get bad() { return _bad; },
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
});
|
4
test/message/rest-param-object-setter-strict.out
Normal file
4
test/message/rest-param-object-setter-strict.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:11: SyntaxError: Setter function argument must not be a rest parameter
|
||||
set bad(...args) { _bad = args[0]; }
|
||||
^^^^^^^^^
|
||||
SyntaxError: Setter function argument must not be a rest parameter
|
Loading…
Reference in New Issue
Block a user