Reviewers: arv,
Message:
PTAL
Description:
[parser] report SyntaxError if rest parameter used in Setter
MethodDefinition
BUG=v8:4107, v8:2159
LOG=N
[email protected]
Please review this at https://codereview.chromium.org/1141223002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+43, -14 lines):
M src/messages.js
M src/parser.cc
M src/preparser.h
M src/preparser.cc
A + test/message/rest-param-class-setter-strict.js
A test/message/rest-param-class-setter-strict.out
A + test/message/rest-param-object-setter-sloppy.js
A test/message/rest-param-object-setter-sloppy.out
A + test/message/rest-param-object-setter-strict.js
A test/message/rest-param-object-setter-strict.out
Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index
eb6e07fb07bdf6df49ead6f9288edf183127dae0..bb5789fd60a7ab84f3b964234b4cd03c4d3f9946
100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -141,6 +141,7 @@ var kMessages = {
super_constructor_call: ["A 'super' constructor call may only
appear as the first statement of a function, and its arguments may not
access 'this'. Other forms are not yet supported."],
duplicate_proto: ["Duplicate __proto__ fields are not
allowed in object literals"],
param_after_rest: ["Rest parameter must be last formal
parameter"],
+ setter_rest_param: ["Setter function argument must not be a
rest parameter"],
derived_constructor_return: ["Derived constructors may only return
object or undefined"],
for_in_loop_initializer: ["for-in loop variable declaration may
not have an initializer."],
for_of_loop_initializer: ["for-of loop variable declaration may
not have an initializer."],
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
5be6d82b67d582b11601b227c0f7b9d739ba2480..8e2d306bc0c1ece9af81dcd4592b81617b5de402
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3883,8 +3883,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);
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index
f2502bbbb72fa84ea6f8fa3adc4819547a10e591..d8b33120f61119783eb881c4cf713c06825bead0
100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -1026,21 +1026,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.
@@ -1060,7 +1060,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(),
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index
aeef700bfe7593a8369b4c4b5f0350fa8dc5b707..072ebca27cbacea94c730e070e792e7d17ee675a
100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -881,7 +881,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,
@@ -3623,7 +3623,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) {
@@ -3638,6 +3638,11 @@ void ParserBase<Traits>::CheckArityRestrictions(
"bad_setter_arity");
*ok = false;
}
+ if (has_rest) {
+ ReportMessageAt(Scanner::Location(formals_start_pos,
formals_end_pos),
+ "setter_rest_param");
+ *ok = false;
+ }
break;
default:
break;
Index: test/message/rest-param-class-setter-strict.js
diff --git a/test/message/super-in-function.js
b/test/message/rest-param-class-setter-strict.js
similarity index 52%
copy from test/message/super-in-function.js
copy to test/message/rest-param-class-setter-strict.js
index
edaa0e4eadc7befdb7ed28a3e06eaa827c4388f0..d37edb6f3f70373b0b513e29363eddcafb343f1b
100644
--- a/test/message/super-in-function.js
+++ b/test/message/rest-param-class-setter-strict.js
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// Flags: --harmony-classes
+// Flags: --harmony-rest-parameters --harmony-classes
'use strict';
-function f() {
- super.x();
+var _bad = "setting this should fail!";
+class C {
+ get bad() { return _bad; }
+ set bad(...args) { _bad = args[0]; }
}
Index: test/message/rest-param-class-setter-strict.out
diff --git a/test/message/rest-param-class-setter-strict.out
b/test/message/rest-param-class-setter-strict.out
new file mode 100644
index
0000000000000000000000000000000000000000..3296a0f2c8dcc7decb8cd64cd83288d4c44de6d7
--- /dev/null
+++ b/test/message/rest-param-class-setter-strict.out
@@ -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
Index: test/message/rest-param-object-setter-sloppy.js
diff --git a/test/message/formal-parameters-bad-rest.js
b/test/message/rest-param-object-setter-sloppy.js
similarity index 65%
copy from test/message/formal-parameters-bad-rest.js
copy to test/message/rest-param-object-setter-sloppy.js
index
c67e1de93fed808fb0578e9029dabef201ab51e4..08c03298dc26dfee9f31e39108ba0b1519a96988
100644
--- a/test/message/formal-parameters-bad-rest.js
+++ b/test/message/rest-param-object-setter-sloppy.js
@@ -4,4 +4,8 @@
//
// Flags: --harmony-rest-parameters
-function foo(...b, a) { return a }
+var _bad = "this should fail!";
+({
+ get bad() { return _bad; },
+ set bad(...args) { _bad = args[0]; }
+});
Index: test/message/rest-param-object-setter-sloppy.out
diff --git a/test/message/rest-param-object-setter-sloppy.out
b/test/message/rest-param-object-setter-sloppy.out
new file mode 100644
index
0000000000000000000000000000000000000000..9400a2a9ce3ee16a535b5663d6ea70322a89e521
--- /dev/null
+++ b/test/message/rest-param-object-setter-sloppy.out
@@ -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
Index: test/message/rest-param-object-setter-strict.js
diff --git a/test/message/formal-parameters-bad-rest.js
b/test/message/rest-param-object-setter-strict.js
similarity index 62%
copy from test/message/formal-parameters-bad-rest.js
copy to test/message/rest-param-object-setter-strict.js
index
c67e1de93fed808fb0578e9029dabef201ab51e4..e3a8f604e64ae75b5941c878c34280f352af7d00
100644
--- a/test/message/formal-parameters-bad-rest.js
+++ b/test/message/rest-param-object-setter-strict.js
@@ -3,5 +3,10 @@
// found in the LICENSE file.
//
// Flags: --harmony-rest-parameters
+'use strict';
-function foo(...b, a) { return a }
+var _bad = "this should fail!";
+({
+ get bad() { return _bad; },
+ set bad(...args) { _bad = args[0]; }
+});
Index: test/message/rest-param-object-setter-strict.out
diff --git a/test/message/rest-param-object-setter-strict.out
b/test/message/rest-param-object-setter-strict.out
new file mode 100644
index
0000000000000000000000000000000000000000..3296a0f2c8dcc7decb8cd64cd83288d4c44de6d7
--- /dev/null
+++ b/test/message/rest-param-object-setter-strict.out
@@ -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
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.