[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(NoCatchOrFinally, "Missing catch or finally after try") \
|
||||||
T(NotIsvar, "builtin %%IS_VAR: not a variable") \
|
T(NotIsvar, "builtin %%IS_VAR: not a variable") \
|
||||||
T(ParamAfterRest, "Rest parameter must be last formal parameter") \
|
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(ParenthesisInArgString, "Function arg string contains parenthesis") \
|
||||||
T(SingleFunctionLiteral, "Single function literal required") \
|
T(SingleFunctionLiteral, "Single function literal required") \
|
||||||
T(SloppyLexical, \
|
T(SloppyLexical, \
|
||||||
|
@ -3892,8 +3892,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
|||||||
Expect(Token::RPAREN, CHECK_OK);
|
Expect(Token::RPAREN, CHECK_OK);
|
||||||
int formals_end_position = scanner()->location().end_pos;
|
int formals_end_position = scanner()->location().end_pos;
|
||||||
|
|
||||||
CheckArityRestrictions(num_parameters, arity_restriction, start_position,
|
CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
|
||||||
formals_end_position, CHECK_OK);
|
start_position, formals_end_position, CHECK_OK);
|
||||||
|
|
||||||
Expect(Token::LBRACE, CHECK_OK);
|
Expect(Token::LBRACE, CHECK_OK);
|
||||||
|
|
||||||
|
@ -1034,21 +1034,21 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
|||||||
&factory);
|
&factory);
|
||||||
ExpressionClassifier formals_classifier;
|
ExpressionClassifier formals_classifier;
|
||||||
|
|
||||||
bool is_rest = false;
|
bool has_rest = false;
|
||||||
Expect(Token::LPAREN, CHECK_OK);
|
Expect(Token::LPAREN, CHECK_OK);
|
||||||
int start_position = scanner()->location().beg_pos;
|
int start_position = scanner()->location().beg_pos;
|
||||||
function_scope->set_start_position(start_position);
|
function_scope->set_start_position(start_position);
|
||||||
int num_parameters;
|
int num_parameters;
|
||||||
{
|
{
|
||||||
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
|
||||||
num_parameters = ParseFormalParameterList(&duplicate_finder, &is_rest,
|
num_parameters = ParseFormalParameterList(&duplicate_finder, &has_rest,
|
||||||
&formals_classifier, CHECK_OK);
|
&formals_classifier, CHECK_OK);
|
||||||
}
|
}
|
||||||
Expect(Token::RPAREN, CHECK_OK);
|
Expect(Token::RPAREN, CHECK_OK);
|
||||||
int formals_end_position = scanner()->location().end_pos;
|
int formals_end_position = scanner()->location().end_pos;
|
||||||
|
|
||||||
CheckArityRestrictions(num_parameters, arity_restriction, start_position,
|
CheckArityRestrictions(num_parameters, arity_restriction, has_rest,
|
||||||
formals_end_position, CHECK_OK);
|
start_position, formals_end_position, CHECK_OK);
|
||||||
|
|
||||||
// See Parser::ParseFunctionLiteral for more information about lazy parsing
|
// See Parser::ParseFunctionLiteral for more information about lazy parsing
|
||||||
// and lazy compilation.
|
// and lazy compilation.
|
||||||
@ -1068,7 +1068,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
|||||||
// function, since the function can declare itself strict.
|
// function, since the function can declare itself strict.
|
||||||
CheckFunctionName(language_mode(), kind, function_name,
|
CheckFunctionName(language_mode(), kind, function_name,
|
||||||
name_is_strict_reserved, function_name_location, CHECK_OK);
|
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 =
|
const bool allow_duplicate_parameters =
|
||||||
is_sloppy(language_mode()) && !strict_formal_parameters;
|
is_sloppy(language_mode()) && !strict_formal_parameters;
|
||||||
ValidateFormalParameters(&formals_classifier, language_mode(),
|
ValidateFormalParameters(&formals_classifier, language_mode(),
|
||||||
|
@ -893,7 +893,7 @@ class ParserBase : public Traits {
|
|||||||
ExpressionClassifier* classifier, bool* ok);
|
ExpressionClassifier* classifier, bool* ok);
|
||||||
void CheckArityRestrictions(
|
void CheckArityRestrictions(
|
||||||
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
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
|
// 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,
|
// left-hand side of assignments). Although ruled out by ECMA as early errors,
|
||||||
@ -3657,7 +3657,7 @@ int ParserBase<Traits>::ParseFormalParameterList(
|
|||||||
template <class Traits>
|
template <class Traits>
|
||||||
void ParserBase<Traits>::CheckArityRestrictions(
|
void ParserBase<Traits>::CheckArityRestrictions(
|
||||||
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
|
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) {
|
switch (arity_restriction) {
|
||||||
case FunctionLiteral::GETTER_ARITY:
|
case FunctionLiteral::GETTER_ARITY:
|
||||||
if (param_count != 0) {
|
if (param_count != 0) {
|
||||||
@ -3672,6 +3672,11 @@ void ParserBase<Traits>::CheckArityRestrictions(
|
|||||||
MessageTemplate::kBadSetterArity);
|
MessageTemplate::kBadSetterArity);
|
||||||
*ok = false;
|
*ok = false;
|
||||||
}
|
}
|
||||||
|
if (has_rest) {
|
||||||
|
ReportMessageAt(Scanner::Location(formals_start_pos, formals_end_pos),
|
||||||
|
MessageTemplate::kBadSetterRestParameter);
|
||||||
|
*ok = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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) {
|
TEST(RestParametersEvalArguments) {
|
||||||
const char* strict_context_data[][2] =
|
const char* strict_context_data[][2] =
|
||||||
{{"'use strict';(function(",
|
{{"'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