+2015-04-26 Ryosuke Niwa <rniwa@webkit.org>
+
+ Class body ending with a semicolon throws a SyntaxError
+ https://bugs.webkit.org/show_bug.cgi?id=144244
+
+ Reviewed by Darin Adler.
+
+ Added a regression test for having a semicolon inside the class definition.
+
+ * js/class-syntax-semicolon-expected.txt: Added.
+ * js/class-syntax-semicolon.html: Added.
+ * js/script-tests/class-syntax-semicolon.js: Added.
+
2015-04-26 Ryosuke Niwa <rniwa@webkit.org>
Getter or setter method named "prototype" or "constrcutor" should throw SyntaxError
--- /dev/null
+Tests for ES6 class syntax containing semicolon in the class body
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS class A { foo;() { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '(' before a method's parameter list..
+PASS class A { foo() ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a method body..
+PASS class A { get ; foo() { } } threw exception SyntaxError: Unexpected token ';'.
+PASS class A { get foo;() { } } threw exception SyntaxError: Unexpected token ';'. Expected a parameter list for getter definition..
+PASS class A { get foo() ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a getter body..
+PASS class A { set ; foo(x) { } } threw exception SyntaxError: Unexpected token ';'.
+PASS class A { set foo;(x) { } } threw exception SyntaxError: Unexpected token ';'. Expected a parameter list for setter definition..
+PASS class A { set foo(x) ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a setter body..
+PASS class A { ; } did not throw exception.
+PASS class A { foo() { } ; } did not throw exception.
+PASS class A { get foo() { } ; } did not throw exception.
+PASS class A { set foo(x) { } ; } did not throw exception.
+PASS class A { static foo() { } ; } did not throw exception.
+PASS class A { static get foo() { } ; } did not throw exception.
+PASS class A { static set foo(x) { } ; } did not throw exception.
+PASS class A { ; foo() { } } did not throw exception.
+PASS class A { ; get foo() { } } did not throw exception.
+PASS class A { ; set foo(x) { } } did not throw exception.
+PASS class A { ; static foo() { } } did not throw exception.
+PASS class A { ; static get foo() { } } did not throw exception.
+PASS class A { ; static set foo(x) { } } did not throw exception.
+PASS class A { foo() { } ; foo() {} } did not throw exception.
+PASS class A { foo() { } ; get foo() {} } did not throw exception.
+PASS class A { foo() { } ; set foo(x) {} } did not throw exception.
+PASS class A { foo() { } ; static foo() {} } did not throw exception.
+PASS class A { foo() { } ; static get foo() {} } did not throw exception.
+PASS class A { foo() { } ; static set foo(x) {} } did not throw exception.
+PASS class A { get foo() { } ; foo() {} } did not throw exception.
+PASS class A { get foo() { } ; get foo() {} } did not throw exception.
+PASS class A { get foo() { } ; set foo(x) {} } did not throw exception.
+PASS class A { get foo() { } ; static foo() {} } did not throw exception.
+PASS class A { get foo() { } ; static get foo() {} } did not throw exception.
+PASS class A { get foo() { } ; static set foo(x) {} } did not throw exception.
+PASS class A { set foo(x) { } ; foo() {} } did not throw exception.
+PASS class A { set foo(x) { } ; get foo() {} } did not throw exception.
+PASS class A { set foo(x) { } ; set foo(x) {} } did not throw exception.
+PASS class A { set foo(x) { } ; static foo() {} } did not throw exception.
+PASS class A { set foo(x) { } ; static get foo() {} } did not throw exception.
+PASS class A { set foo(x) { } ; static set foo(x) {} } did not throw exception.
+PASS class A { static foo() { } ; foo() {} } did not throw exception.
+PASS class A { static foo() { } ; get foo() {} } did not throw exception.
+PASS class A { static foo() { } ; set foo(x) {} } did not throw exception.
+PASS class A { static foo() { } ; static foo() {} } did not throw exception.
+PASS class A { static foo() { } ; static get foo() {} } did not throw exception.
+PASS class A { static foo() { } ; static set foo(x) {} } did not throw exception.
+PASS class A { static get foo() { } ; foo() {} } did not throw exception.
+PASS class A { static get foo() { } ; get foo() {} } did not throw exception.
+PASS class A { static get foo() { } ; set foo(x) {} } did not throw exception.
+PASS class A { static get foo() { } ; static foo() {} } did not throw exception.
+PASS class A { static get foo() { } ; static get foo() {} } did not throw exception.
+PASS class A { static get foo() { } ; static set foo(x) {} } did not throw exception.
+PASS class A { static set foo(x) { } ; foo() {} } did not throw exception.
+PASS class A { static set foo(x) { } ; get foo() {} } did not throw exception.
+PASS class A { static set foo(x) { } ; set foo(x) {} } did not throw exception.
+PASS class A { static set foo(x) { } ; static foo() {} } did not throw exception.
+PASS class A { static set foo(x) { } ; static get foo() {} } did not throw exception.
+PASS class A { static set foo(x) { } ; static set foo(x) {} } did not throw exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../resources/js-test-pre.js"></script>
+<script src="script-tests/class-syntax-semicolon.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+
+description('Tests for ES6 class syntax containing semicolon in the class body');
+
+shouldThrow("class A { foo;() { } }", "'SyntaxError: Unexpected token \\';\\'. Expected an opening \\'(\\' before a method\\'s parameter list.'");
+shouldThrow("class A { foo() ; { } }", "'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a method body.'");
+shouldThrow("class A { get ; foo() { } }", "'SyntaxError: Unexpected token \\';\\''");
+shouldThrow("class A { get foo;() { } }", "'SyntaxError: Unexpected token \\\';\\'. Expected a parameter list for getter definition.'");
+shouldThrow("class A { get foo() ; { } }", "'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a getter body.'");
+shouldThrow("class A { set ; foo(x) { } }", "'SyntaxError: Unexpected token \\';\\''");
+shouldThrow("class A { set foo;(x) { } }", "'SyntaxError: Unexpected token \\\';\\'. Expected a parameter list for setter definition.'");
+shouldThrow("class A { set foo(x) ; { } }", "'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a setter body.'");
+
+shouldNotThrow("class A { ; }");
+shouldNotThrow("class A { foo() { } ; }");
+shouldNotThrow("class A { get foo() { } ; }");
+shouldNotThrow("class A { set foo(x) { } ; }");
+shouldNotThrow("class A { static foo() { } ; }");
+shouldNotThrow("class A { static get foo() { } ; }");
+shouldNotThrow("class A { static set foo(x) { } ; }");
+
+shouldNotThrow("class A { ; foo() { } }");
+shouldNotThrow("class A { ; get foo() { } }");
+shouldNotThrow("class A { ; set foo(x) { } }");
+shouldNotThrow("class A { ; static foo() { } }");
+shouldNotThrow("class A { ; static get foo() { } }");
+shouldNotThrow("class A { ; static set foo(x) { } }");
+
+shouldNotThrow("class A { foo() { } ; foo() {} }");
+shouldNotThrow("class A { foo() { } ; get foo() {} }");
+shouldNotThrow("class A { foo() { } ; set foo(x) {} }");
+shouldNotThrow("class A { foo() { } ; static foo() {} }");
+shouldNotThrow("class A { foo() { } ; static get foo() {} }");
+shouldNotThrow("class A { foo() { } ; static set foo(x) {} }");
+
+shouldNotThrow("class A { get foo() { } ; foo() {} }");
+shouldNotThrow("class A { get foo() { } ; get foo() {} }");
+shouldNotThrow("class A { get foo() { } ; set foo(x) {} }");
+shouldNotThrow("class A { get foo() { } ; static foo() {} }");
+shouldNotThrow("class A { get foo() { } ; static get foo() {} }");
+shouldNotThrow("class A { get foo() { } ; static set foo(x) {} }");
+
+shouldNotThrow("class A { set foo(x) { } ; foo() {} }");
+shouldNotThrow("class A { set foo(x) { } ; get foo() {} }");
+shouldNotThrow("class A { set foo(x) { } ; set foo(x) {} }");
+shouldNotThrow("class A { set foo(x) { } ; static foo() {} }");
+shouldNotThrow("class A { set foo(x) { } ; static get foo() {} }");
+shouldNotThrow("class A { set foo(x) { } ; static set foo(x) {} }");
+
+shouldNotThrow("class A { static foo() { } ; foo() {} }");
+shouldNotThrow("class A { static foo() { } ; get foo() {} }");
+shouldNotThrow("class A { static foo() { } ; set foo(x) {} }");
+shouldNotThrow("class A { static foo() { } ; static foo() {} }");
+shouldNotThrow("class A { static foo() { } ; static get foo() {} }");
+shouldNotThrow("class A { static foo() { } ; static set foo(x) {} }");
+
+shouldNotThrow("class A { static get foo() { } ; foo() {} }");
+shouldNotThrow("class A { static get foo() { } ; get foo() {} }");
+shouldNotThrow("class A { static get foo() { } ; set foo(x) {} }");
+shouldNotThrow("class A { static get foo() { } ; static foo() {} }");
+shouldNotThrow("class A { static get foo() { } ; static get foo() {} }");
+shouldNotThrow("class A { static get foo() { } ; static set foo(x) {} }");
+
+shouldNotThrow("class A { static set foo(x) { } ; foo() {} }");
+shouldNotThrow("class A { static set foo(x) { } ; get foo() {} }");
+shouldNotThrow("class A { static set foo(x) { } ; set foo(x) {} }");
+shouldNotThrow("class A { static set foo(x) { } ; static foo() {} }");
+shouldNotThrow("class A { static set foo(x) { } ; static get foo() {} }");
+shouldNotThrow("class A { static set foo(x) { } ; static set foo(x) {} }");
+
+var successfullyParsed = true;
+2015-04-26 Ryosuke Niwa <rniwa@webkit.org>
+
+ Class body ending with a semicolon throws a SyntaxError
+ https://bugs.webkit.org/show_bug.cgi?id=144244
+
+ Reviewed by Darin Adler.
+
+ The bug was caused by parseClass's inner loop for method definitions not moving onto the next iteration
+ it encounters a semicolon. As a result, we always expected a method to appear after a semicolon. Fixed
+ it by continue'ing when it encounters a semicolon.
+
+ * parser/Parser.cpp:
+ (JSC::Parser<LexerType>::parseClass):
+
2015-04-26 Ryosuke Niwa <rniwa@webkit.org>
Getter or setter method named "prototype" or "constrcutor" should throw SyntaxError
TreePropertyList instanceMethodsTail = 0;
TreePropertyList staticMethodsTail = 0;
while (!match(CLOSEBRACE)) {
- if (match(SEMICOLON))
+ if (match(SEMICOLON)) {
next();
+ continue;
+ }
JSTokenLocation methodLocation(tokenLocation());
unsigned methodStart = tokenStart();