<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[188018] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/188018">188018</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2015-08-05 21:01:00 -0700 (Wed, 05 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[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/JavaScriptCore:

The bug was caused by parseClass assuming identifiers &quot;get&quot; and &quot;set&quot; 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&lt;LexerType&gt;::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:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsclasssyntaxsemicolonexpectedtxt">trunk/LayoutTests/js/class-syntax-semicolon-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsclasssyntaxsemicolonjs">trunk/LayoutTests/js/script-tests/class-syntax-semicolon.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsclasssyntaxmethodnamesexpectedtxt">trunk/LayoutTests/js/class-syntax-method-names-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsclasssyntaxmethodnameshtml">trunk/LayoutTests/js/class-syntax-method-names.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsclasssyntaxmethodnamesjs">trunk/LayoutTests/js/script-tests/class-syntax-method-names.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (188017 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/LayoutTests/ChangeLog        2015-08-06 04:01:00 UTC (rev 188018)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2015-08-05  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        [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:
+
</ins><span class="cx"> 2015-08-05  Nikita Vasilyev  &lt;nvasilyev@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Logging error objects should have a better UI
</span></span></pre></div>
<a id="trunkLayoutTestsjsclasssyntaxmethodnamesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/class-syntax-method-names-expected.txt (0 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+Tests for various method names
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+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
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsclasssyntaxmethodnameshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/class-syntax-method-names.html (0 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/class-syntax-method-names.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsclasssyntaxsemicolonexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/class-syntax-semicolon-expected.txt (188017 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -5,10 +5,10 @@
</span><span class="cx"> 
</span><span class="cx"> PASS class A { foo;() { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '(' before a method's parameter list..
</span><span class="cx"> PASS class A { foo() ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a method body..
</span><del>-PASS class A { get ; foo() { } } threw exception SyntaxError: Unexpected token ';'.
</del><ins>+PASS class A { get ; foo() { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '(' before a method's parameter list..
</ins><span class="cx"> PASS class A { get foo;() { } } threw exception SyntaxError: Unexpected token ';'. Expected a parameter list for getter definition..
</span><span class="cx"> PASS class A { get foo() ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a getter body..
</span><del>-PASS class A { set ; foo(x) { } } threw exception SyntaxError: Unexpected token ';'.
</del><ins>+PASS class A { set ; foo(x) { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '(' before a method's parameter list..
</ins><span class="cx"> PASS class A { set foo;(x) { } } threw exception SyntaxError: Unexpected token ';'. Expected a parameter list for setter definition..
</span><span class="cx"> PASS class A { set foo(x) ; { } } threw exception SyntaxError: Unexpected token ';'. Expected an opening '{' at the start of a setter body..
</span><span class="cx"> PASS class A { ; } did not throw exception.
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsclasssyntaxmethodnamesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/class-syntax-method-names.js (0 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+description('Tests for various method names');
+
+shouldBe(&quot;class A { 0.1() { return 1; } }; (new A)[0.1]()&quot;, &quot;1&quot;);
+shouldBe(&quot;class A { get() { return 2; } }; (new A).get()&quot;, &quot;2&quot;);
+shouldBe(&quot;class A { set() { return 3; } }; (new A).set()&quot;, &quot;3&quot;);
+shouldBe(&quot;class A { get get() { return 4; } }; (new A).get&quot;, &quot;4&quot;);
+shouldBe(&quot;class A { get set() { return 5; } }; (new A).set&quot;, &quot;5&quot;);
+shouldBe(&quot;setterValue = undefined; class A { set get(x) { setterValue = x; } }; (new A).get = 6; setterValue&quot;, &quot;6&quot;);
+shouldBe(&quot;setterValue = undefined; class A { set set(x) { setterValue = x; } }; (new A).set = 7; setterValue&quot;, &quot;7&quot;);
+
+shouldBe(&quot;class A { static 0.1() { return 101; } }; A[0.1]()&quot;, &quot;101&quot;);
+shouldBe(&quot;class A { static get() { return 102; } }; A.get()&quot;, &quot;102&quot;);
+shouldBe(&quot;class A { static set() { return 103; } }; A.set()&quot;, &quot;103&quot;);
+shouldBe(&quot;class A { static get get() { return 104; } }; A.get&quot;, &quot;104&quot;);
+shouldBe(&quot;class A { static get set() { return 105; } }; A.set&quot;, &quot;105&quot;);
+shouldBe(&quot;setterValue = undefined; class A { static set get(x) { setterValue = x; } }; A.get = 106; setterValue&quot;, &quot;106&quot;);
+shouldBe(&quot;setterValue = undefined; class A { static set set(x) { setterValue = x; } }; A.set = 107; setterValue&quot;, &quot;107&quot;);
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsclasssyntaxsemicolonjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/class-syntax-semicolon.js (188017 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -4,10 +4,10 @@
</span><span class="cx"> 
</span><span class="cx"> shouldThrow(&quot;class A { foo;() { } }&quot;, &quot;'SyntaxError: Unexpected token \\';\\'. Expected an opening \\'(\\' before a method\\'s parameter list.'&quot;);
</span><span class="cx"> shouldThrow(&quot;class A { foo() ; { } }&quot;, &quot;'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a method body.'&quot;);
</span><del>-shouldThrow(&quot;class A { get ; foo() { } }&quot;, &quot;'SyntaxError: Unexpected token \\';\\''&quot;);
</del><ins>+shouldThrow(&quot;class A { get ; foo() { } }&quot;, &quot;'SyntaxError: Unexpected token \\';\\'. Expected an opening \\'(\\' before a method\\'s parameter list.'&quot;);
</ins><span class="cx"> shouldThrow(&quot;class A { get foo;() { } }&quot;, &quot;'SyntaxError: Unexpected token \\\';\\'. Expected a parameter list for getter definition.'&quot;);
</span><span class="cx"> shouldThrow(&quot;class A { get foo() ; { } }&quot;, &quot;'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a getter body.'&quot;);
</span><del>-shouldThrow(&quot;class A { set ; foo(x) { } }&quot;, &quot;'SyntaxError: Unexpected token \\';\\''&quot;);
</del><ins>+shouldThrow(&quot;class A { set ; foo(x) { } }&quot;, &quot;'SyntaxError: Unexpected token \\';\\'. Expected an opening \\'(\\' before a method\\'s parameter list.'&quot;);
</ins><span class="cx"> shouldThrow(&quot;class A { set foo;(x) { } }&quot;, &quot;'SyntaxError: Unexpected token \\\';\\'. Expected a parameter list for setter definition.'&quot;);
</span><span class="cx"> shouldThrow(&quot;class A { set foo(x) ; { } }&quot;, &quot;'SyntaxError: Unexpected token \\\';\\'. Expected an opening \\'{\\' at the start of a setter body.'&quot;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (188017 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-08-06 04:01:00 UTC (rev 188018)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-08-05  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        [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 &quot;get&quot; and &quot;set&quot; 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&lt;LexerType&gt;::parseClass):
+
</ins><span class="cx"> 2015-08-05  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, roll out http://trac.webkit.org/changeset/187972.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (188017 => 188018)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-08-06 03:58:07 UTC (rev 188017)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp        2015-08-06 04:01:00 UTC (rev 188018)
</span><span class="lines">@@ -1950,9 +1950,12 @@
</span><span class="cx">             break;
</span><span class="cx">         case IDENT:
</span><span class="cx">             ident = m_token.m_data.ident;
</span><del>-            isGetter = *ident == propertyNames.get;
-            isSetter = *ident == propertyNames.set;
</del><span class="cx">             ASSERT(ident);
</span><ins>+            next();
+            if (match(IDENT) || match(STRING) || match(DOUBLE) || match(INTEGER)) {
+                isGetter = *ident == propertyNames.get;
+                isSetter = *ident == propertyNames.set;
+            }
</ins><span class="cx">             break;
</span><span class="cx">         case DOUBLE:
</span><span class="cx">         case INTEGER:
</span><span class="lines">@@ -1967,7 +1970,6 @@
</span><span class="cx">         TreeProperty property;
</span><span class="cx">         const bool alwaysStrictInsideClass = true;
</span><span class="cx">         if (isGetter || isSetter) {
</span><del>-            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
</del><span class="cx">             property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart,
</span><span class="cx">                 ConstructorKind::None, SuperBinding::Needed);
</span><span class="cx">             failIfFalse(property, &quot;Cannot parse this method&quot;);
</span></span></pre>
</div>
</div>

</body>
</html>