Title: [188018] trunk
Revision
188018
Author
rn...@webkit.org
Date
2015-08-05 21:01:00 -0700 (Wed, 05 Aug 2015)

Log Message

[ES6] Class parser does not allow methods named set and get.
https://bugs.webkit.org/show_bug.cgi?id=147150

Reviewed by Oliver Hunt.

Source/_javascript_Core:

The bug was caused by parseClass assuming identifiers "get" and "set" could only appear
as the leading token for getter and setter methods. Fixed the bug by generalizing the code
so that we only treat them as such when it's followed by another token that could be a method name.

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):

LayoutTests:

Added a regression test and rebaselined a test.

* js/class-syntax-method-names-expected.txt: Added.
* js/class-syntax-method-names.html: Added.
* js/class-syntax-semicolon-expected.txt: Rebaselined as the error message got improved.
* js/script-tests/class-syntax-method-names.js: Added.
* js/script-tests/class-syntax-semicolon.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (188017 => 188018)


--- trunk/LayoutTests/ChangeLog	2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/LayoutTests/ChangeLog	2015-08-06 04:01:00 UTC (rev 188018)
@@ -1,3 +1,18 @@
+2015-08-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [ES6] Class parser does not allow methods named set and get.
+        https://bugs.webkit.org/show_bug.cgi?id=147150
+
+        Reviewed by Oliver Hunt.
+
+        Added a regression test and rebaselined a test.
+
+        * js/class-syntax-method-names-expected.txt: Added.
+        * js/class-syntax-method-names.html: Added.
+        * js/class-syntax-semicolon-expected.txt: Rebaselined as the error message got improved.
+        * js/script-tests/class-syntax-method-names.js: Added.
+        * js/script-tests/class-syntax-semicolon.js:
+
 2015-08-05  Nikita Vasilyev  <nvasil...@apple.com>
 
         Web Inspector: Logging error objects should have a better UI

Added: trunk/LayoutTests/js/class-syntax-method-names-expected.txt (0 => 188018)


--- trunk/LayoutTests/js/class-syntax-method-names-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/class-syntax-method-names-expected.txt	2015-08-06 04:01:00 UTC (rev 188018)
@@ -0,0 +1,23 @@
+Tests for various method names
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS class A { 0.1() { return 1; } }; (new A)[0.1]() is 1
+PASS class A { get() { return 2; } }; (new A).get() is 2
+PASS class A { set() { return 3; } }; (new A).set() is 3
+PASS class A { get get() { return 4; } }; (new A).get is 4
+PASS class A { get set() { return 5; } }; (new A).set is 5
+PASS setterValue = undefined; class A { set get(x) { setterValue = x; } }; (new A).get = 6; setterValue is 6
+PASS setterValue = undefined; class A { set set(x) { setterValue = x; } }; (new A).set = 7; setterValue is 7
+PASS class A { static 0.1() { return 101; } }; A[0.1]() is 101
+PASS class A { static get() { return 102; } }; A.get() is 102
+PASS class A { static set() { return 103; } }; A.set() is 103
+PASS class A { static get get() { return 104; } }; A.get is 104
+PASS class A { static get set() { return 105; } }; A.set is 105
+PASS setterValue = undefined; class A { static set get(x) { setterValue = x; } }; A.get = 106; setterValue is 106
+PASS setterValue = undefined; class A { static set set(x) { setterValue = x; } }; A.set = 107; setterValue is 107
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/class-syntax-method-names.html (0 => 188018)


--- trunk/LayoutTests/js/class-syntax-method-names.html	                        (rev 0)
+++ trunk/LayoutTests/js/class-syntax-method-names.html	2015-08-06 04:01:00 UTC (rev 188018)
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/js/class-syntax-semicolon-expected.txt (188017 => 188018)


--- trunk/LayoutTests/js/class-syntax-semicolon-expected.txt	2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/LayoutTests/js/class-syntax-semicolon-expected.txt	2015-08-06 04:01:00 UTC (rev 188018)
@@ -5,10 +5,10 @@
 
 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 an opening '(' before a method's parameter list..
 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 an opening '(' before a method's parameter list..
 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.

Added: trunk/LayoutTests/js/script-tests/class-syntax-method-names.js (0 => 188018)


--- trunk/LayoutTests/js/script-tests/class-syntax-method-names.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/class-syntax-method-names.js	2015-08-06 04:01:00 UTC (rev 188018)
@@ -0,0 +1,17 @@
+description('Tests for various method names');
+
+shouldBe("class A { 0.1() { return 1; } }; (new A)[0.1]()", "1");
+shouldBe("class A { get() { return 2; } }; (new A).get()", "2");
+shouldBe("class A { set() { return 3; } }; (new A).set()", "3");
+shouldBe("class A { get get() { return 4; } }; (new A).get", "4");
+shouldBe("class A { get set() { return 5; } }; (new A).set", "5");
+shouldBe("setterValue = undefined; class A { set get(x) { setterValue = x; } }; (new A).get = 6; setterValue", "6");
+shouldBe("setterValue = undefined; class A { set set(x) { setterValue = x; } }; (new A).set = 7; setterValue", "7");
+
+shouldBe("class A { static 0.1() { return 101; } }; A[0.1]()", "101");
+shouldBe("class A { static get() { return 102; } }; A.get()", "102");
+shouldBe("class A { static set() { return 103; } }; A.set()", "103");
+shouldBe("class A { static get get() { return 104; } }; A.get", "104");
+shouldBe("class A { static get set() { return 105; } }; A.set", "105");
+shouldBe("setterValue = undefined; class A { static set get(x) { setterValue = x; } }; A.get = 106; setterValue", "106");
+shouldBe("setterValue = undefined; class A { static set set(x) { setterValue = x; } }; A.set = 107; setterValue", "107");

Modified: trunk/LayoutTests/js/script-tests/class-syntax-semicolon.js (188017 => 188018)


--- trunk/LayoutTests/js/script-tests/class-syntax-semicolon.js	2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/LayoutTests/js/script-tests/class-syntax-semicolon.js	2015-08-06 04:01:00 UTC (rev 188018)
@@ -4,10 +4,10 @@
 
 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 an opening \\'(\\' before a method\\'s parameter list.'");
 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 an opening \\'(\\' before a method\\'s parameter list.'");
 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.'");
 

Modified: trunk/Source/_javascript_Core/ChangeLog (188017 => 188018)


--- trunk/Source/_javascript_Core/ChangeLog	2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-08-06 04:01:00 UTC (rev 188018)
@@ -1,3 +1,17 @@
+2015-08-05  Ryosuke Niwa  <rn...@webkit.org>
+
+        [ES6] Class parser does not allow methods named set and get.
+        https://bugs.webkit.org/show_bug.cgi?id=147150
+
+        Reviewed by Oliver Hunt.
+
+        The bug was caused by parseClass assuming identifiers "get" and "set" could only appear
+        as the leading token for getter and setter methods. Fixed the bug by generalizing the code
+        so that we only treat them as such when it's followed by another token that could be a method name.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+
 2015-08-05  Filip Pizlo  <fpi...@apple.com>
 
         Unreviewed, roll out http://trac.webkit.org/changeset/187972.

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (188017 => 188018)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2015-08-06 04:01:00 UTC (rev 188018)
@@ -1950,9 +1950,12 @@
             break;
         case IDENT:
             ident = m_token.m_data.ident;
-            isGetter = *ident == propertyNames.get;
-            isSetter = *ident == propertyNames.set;
             ASSERT(ident);
+            next();
+            if (match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER)) {
+                isGetter = *ident == propertyNames.get;
+                isSetter = *ident == propertyNames.set;
+            }
             break;
         case DOUBLE:
         case INTEGER:
@@ -1967,7 +1970,6 @@
         TreeProperty property;
         const bool alwaysStrictInsideClass = true;
         if (isGetter || isSetter) {
-            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
             property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart,
                 ConstructorKind::None, SuperBinding::Needed);
             failIfFalse(property, "Cannot parse this method");
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to