No subject


Tue Jan 27 15:54:36 PST 2015


1. Section 13.6 The if Statement (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-if-statement)
 says that IfStatements only takes Statements for the "then-else" clauses, not StatementListItems.
 (Same with 'while/for/do-while' loop bodies).
2. Section 13 ECMAScript Language: Statements and Declarations
 (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ecmascript-language-statements-and-declarations)
 defines the syntax of Statements, and they do not include ClassDeclarations and LexicalDeclarations
 (const, let, see 13.3.1 Let and Const Declarations).
 Declarations can only be in the “then-else” clauses when embedded in a StatementListItem in a BlockStatement (see 13.2).

Hence, the following style of declarations are no longer allowed:
    'if/for/while (condition) const x = 40;'
    'if/for/while (condition) class C { }'

Instead, we mandate such declaration constructs are within a StatementList
       (which is the production that JSC's Parser::parseSourceElements function parses):
   'if/for/while (condition) { const x = 40; }'
   'if/for/while (condition) { class C { } }'

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseSourceElements):
(JSC::Parser<LexerType>::parseStatementListItem):
(JSC::Parser<LexerType>::parseVarDeclaration):
(JSC::Parser<LexerType>::parseStatement):
(JSC::Parser<LexerType>::parseExpressionStatement):
* parser/Parser.h:
(JSC::Parser::getLabel):

LayoutTests:

* js/parser-syntax-check-expected.txt:
* js/script-tests/const.js:
(with1):
(with2):
* js/script-tests/parser-syntax-check.js:
* js/script-tests/statement-list-item-syntax-errors.js: Added.
(testSyntax):
(runTests):
* js/statement-list-item-syntax-errors-expected.txt: Added.
* js/statement-list-item-syntax-errors.html: Added.
* sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsparsersyntaxcheckexpectedtxt">trunk/LayoutTests/js/parser-syntax-check-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsconstjs">trunk/LayoutTests/js/script-tests/const.js</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsparsersyntaxcheckjs">trunk/LayoutTests/js/script-tests/parser-syntax-check.js</a></li>
<li><a href="#trunkLayoutTestssputnikConformance07_Lexical_Conventions75_Tokens753_Future_Reserved_WordsS753_A15expectedtxt">trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParsercpp">trunk/Source/JavaScriptCore/parser/Parser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserh">trunk/Source/JavaScriptCore/parser/Parser.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsscripttestsstatementlistitemsyntaxerrorsjs">trunk/LayoutTests/js/script-tests/statement-list-item-syntax-errors.js</a></li>
<li><a href="#trunkLayoutTestsjsstatementlistitemsyntaxerrorsexpectedtxt">trunk/LayoutTests/js/statement-list-item-syntax-errors-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsstatementlistitemsyntaxerrorshtml">trunk/LayoutTests/js/statement-list-item-syntax-errors.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/LayoutTests/ChangeLog	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2015-07-06  Saam barati  &lt;saambarati1 at gmail.com&gt;
+
+        JSC's parser should follow the ES6 spec with respect to parsing Declarations
+        https://bugs.webkit.org/show_bug.cgi?id=146621
+
+        Reviewed by Mark Lam.
+
+        * js/parser-syntax-check-expected.txt:
+        * js/script-tests/const.js:
+        (with1):
+        (with2):
+        * js/script-tests/parser-syntax-check.js:
+        * js/script-tests/statement-list-item-syntax-errors.js: Added.
+        (testSyntax):
+        (runTests):
+        * js/statement-list-item-syntax-errors-expected.txt: Added.
+        * js/statement-list-item-syntax-errors.html: Added.
+        * sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt:
+
</ins><span class="cx"> 2015-07-06  David Kilzer  &lt;ddkilzer at apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag.html crashes on Windows sometimes
</span></span></pre></div>
<a id="trunkLayoutTestsjsparsersyntaxcheckexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/parser-syntax-check-expected.txt	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -327,8 +327,8 @@
</span><span class="cx"> PASS Invalid: &quot;function f() { var = 7 }&quot;
</span><span class="cx"> PASS Invalid: &quot;var c (6)&quot;
</span><span class="cx"> PASS Invalid: &quot;function f() { var c (6) }&quot;
</span><del>-PASS Valid:   &quot;if (a) var a,b; else const b, c&quot;
-PASS Valid:   &quot;function f() { if (a) var a,b; else const b, c }&quot;
</del><ins>+PASS Valid:   &quot;if (a) var a,b; else { const b, c }&quot;
+PASS Valid:   &quot;function f() { if (a) var a,b; else { const b, c } }&quot;
</ins><span class="cx"> PASS Invalid: &quot;var 5 = 6&quot;
</span><span class="cx"> PASS Invalid: &quot;function f() { var 5 = 6 }&quot;
</span><span class="cx"> PASS Valid:   &quot;while (0) var a, b, c=6, d, e, f=5*6, g=f*h, h&quot;
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsconstjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/const.js (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/const.js	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/LayoutTests/js/script-tests/const.js	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -140,13 +140,13 @@
</span><span class="cx"> 
</span><span class="cx"> function with1() {
</span><span class="cx">     var bar;
</span><del>-    eval(&quot;with({foo:42}) const bar = 5;&quot;);
</del><ins>+    eval(&quot;with({foo:42}) { const bar = 5; }&quot;);
</ins><span class="cx">     return bar;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function with2() {
</span><span class="cx">     var bar;
</span><del>-    with({foo:42}) const bar = 5;
</del><ins>+    with({foo:42}) { const bar = 5; }
</ins><span class="cx">     return bar;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsparsersyntaxcheckjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -236,7 +236,7 @@
</span><span class="cx"> invalid(&quot;var&quot;);
</span><span class="cx"> invalid(&quot;var = 7&quot;);
</span><span class="cx"> invalid(&quot;var c (6)&quot;);
</span><del>-valid  (&quot;if (a) var a,b; else const b, c&quot;);
</del><ins>+valid  (&quot;if (a) var a,b; else { const b, c }&quot;);
</ins><span class="cx"> invalid(&quot;var 5 = 6&quot;);
</span><span class="cx"> valid  (&quot;while (0) var a, b, c=6, d, e, f=5*6, g=f*h, h&quot;);
</span><span class="cx"> invalid(&quot;var a = if (b) { c }&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsstatementlistitemsyntaxerrorsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/statement-list-item-syntax-errors.js (0 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/statement-list-item-syntax-errors.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/statement-list-item-syntax-errors.js	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+description(
+    &quot;See spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements&quot;
+);
+
+var AllShouldThrow = &quot;AllShouldThrow&quot;;
+var NoneShouldThrow = &quot;NoneShouldThrow&quot;;
+
+function testSyntax(asBlock, body, throwStatus) {
+    var open = asBlock ? '{' : '';
+    var close = asBlock ? '}' : '';
+
+    var commonLanguageConstructs = [
+        `for (var i = 0; i &lt; 4; i++) ${open} ${body} ${close}`,
+        `for (var i in {}) ${open} ${body} ${close}`,
+        `for (i in {}) ${open} ${body} ${close}`,
+        `for (var i of []) ${open} ${body} ${close}`,
+        `for (i of []) ${open} ${body} ${close}`,
+        `while (i = 0) ${open} ${body} ${close}`,
+        `do ${open} ${body} ${close} while (i = 0)`,
+        `if (i = 0) ${open} ${body} ${close}`,
+        `if (i = 0) ${open} ${body} ${close} else ${open} ${body} ${close}`,
+        `if (i = 0) i++; else ${open} ${body} ${close}`,
+        `if (i = 0) ${open} ${body} ${close} else i++;`,
+        `with ({}) ${open} ${body} ${close}`,
+    ];
+
+    for (var languageFeature of commonLanguageConstructs) {
+        try {
+            eval(languageFeature);
+            if (throwStatus === AllShouldThrow) {
+                testFailed(languageFeature);
+                return;
+            }
+            testPassed(`Did not have syntax error: '${languageFeature}'`);
+        } catch (e) {
+            if (throwStatus === NoneShouldThrow) {
+                testFailed(languageFeature);
+                return;
+            }
+            testPassed(`Had syntax error '${languageFeature}'`);
+        }
+    }
+}
+
+function runTests() {
+    // FIXME: This needs to consider 'let' in bug:
+    // https://bugs.webkit.org/show_bug.cgi?id=142944
+    var bodies = [
+        &quot;class C {};&quot;,
+        &quot;class C extends (class A {}) {};&quot;,
+        &quot;const c = 40;&quot;,
+        &quot;const c = 40, d = 50;&quot;
+    ];
+    for (var body of bodies) {
+        testSyntax(true, body, NoneShouldThrow);
+        testSyntax(false, body, AllShouldThrow);
+    }
+}
+runTests();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsstatementlistitemsyntaxerrorsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/statement-list-item-syntax-errors-expected.txt (0 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/statement-list-item-syntax-errors-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/statement-list-item-syntax-errors-expected.txt	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -0,0 +1,105 @@
</span><ins>+See spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS Did not have syntax error: 'for (var i = 0; i &lt; 4; i++) { class C {}; }'
+PASS Did not have syntax error: 'for (var i in {}) { class C {}; }'
+PASS Did not have syntax error: 'for (i in {}) { class C {}; }'
+PASS Did not have syntax error: 'for (var i of []) { class C {}; }'
+PASS Did not have syntax error: 'for (i of []) { class C {}; }'
+PASS Did not have syntax error: 'while (i = 0) { class C {}; }'
+PASS Did not have syntax error: 'do { class C {}; } while (i = 0)'
+PASS Did not have syntax error: 'if (i = 0) { class C {}; }'
+PASS Did not have syntax error: 'if (i = 0) { class C {}; } else { class C {}; }'
+PASS Did not have syntax error: 'if (i = 0) i++; else { class C {}; }'
+PASS Did not have syntax error: 'if (i = 0) { class C {}; } else i++;'
+PASS Did not have syntax error: 'with ({}) { class C {}; }'
+PASS Had syntax error 'for (var i = 0; i &lt; 4; i++)  class C {}; '
+PASS Had syntax error 'for (var i in {})  class C {}; '
+PASS Had syntax error 'for (i in {})  class C {}; '
+PASS Had syntax error 'for (var i of [])  class C {}; '
+PASS Had syntax error 'for (i of [])  class C {}; '
+PASS Had syntax error 'while (i = 0)  class C {}; '
+PASS Had syntax error 'do  class C {};  while (i = 0)'
+PASS Had syntax error 'if (i = 0)  class C {}; '
+PASS Had syntax error 'if (i = 0)  class C {};  else  class C {}; '
+PASS Had syntax error 'if (i = 0) i++; else  class C {}; '
+PASS Had syntax error 'if (i = 0)  class C {};  else i++;'
+PASS Had syntax error 'with ({})  class C {}; '
+PASS Did not have syntax error: 'for (var i = 0; i &lt; 4; i++) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'for (var i in {}) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'for (i in {}) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'for (var i of []) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'for (i of []) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'while (i = 0) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'do { class C extends (class A {}) {}; } while (i = 0)'
+PASS Did not have syntax error: 'if (i = 0) { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'if (i = 0) { class C extends (class A {}) {}; } else { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'if (i = 0) i++; else { class C extends (class A {}) {}; }'
+PASS Did not have syntax error: 'if (i = 0) { class C extends (class A {}) {}; } else i++;'
+PASS Did not have syntax error: 'with ({}) { class C extends (class A {}) {}; }'
+PASS Had syntax error 'for (var i = 0; i &lt; 4; i++)  class C extends (class A {}) {}; '
+PASS Had syntax error 'for (var i in {})  class C extends (class A {}) {}; '
+PASS Had syntax error 'for (i in {})  class C extends (class A {}) {}; '
+PASS Had syntax error 'for (var i of [])  class C extends (class A {}) {}; '
+PASS Had syntax error 'for (i of [])  class C extends (class A {}) {}; '
+PASS Had syntax error 'while (i = 0)  class C extends (class A {}) {}; '
+PASS Had syntax error 'do  class C extends (class A {}) {};  while (i = 0)'
+PASS Had syntax error 'if (i = 0)  class C extends (class A {}) {}; '
+PASS Had syntax error 'if (i = 0)  class C extends (class A {}) {};  else  class C extends (class A {}) {}; '
+PASS Had syntax error 'if (i = 0) i++; else  class C extends (class A {}) {}; '
+PASS Had syntax error 'if (i = 0)  class C extends (class A {}) {};  else i++;'
+PASS Had syntax error 'with ({})  class C extends (class A {}) {}; '
+PASS Did not have syntax error: 'for (var i = 0; i &lt; 4; i++) { const c = 40; }'
+PASS Did not have syntax error: 'for (var i in {}) { const c = 40; }'
+PASS Did not have syntax error: 'for (i in {}) { const c = 40; }'
+PASS Did not have syntax error: 'for (var i of []) { const c = 40; }'
+PASS Did not have syntax error: 'for (i of []) { const c = 40; }'
+PASS Did not have syntax error: 'while (i = 0) { const c = 40; }'
+PASS Did not have syntax error: 'do { const c = 40; } while (i = 0)'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40; }'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40; } else { const c = 40; }'
+PASS Did not have syntax error: 'if (i = 0) i++; else { const c = 40; }'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40; } else i++;'
+PASS Did not have syntax error: 'with ({}) { const c = 40; }'
+PASS Had syntax error 'for (var i = 0; i &lt; 4; i++)  const c = 40; '
+PASS Had syntax error 'for (var i in {})  const c = 40; '
+PASS Had syntax error 'for (i in {})  const c = 40; '
+PASS Had syntax error 'for (var i of [])  const c = 40; '
+PASS Had syntax error 'for (i of [])  const c = 40; '
+PASS Had syntax error 'while (i = 0)  const c = 40; '
+PASS Had syntax error 'do  const c = 40;  while (i = 0)'
+PASS Had syntax error 'if (i = 0)  const c = 40; '
+PASS Had syntax error 'if (i = 0)  const c = 40;  else  const c = 40; '
+PASS Had syntax error 'if (i = 0) i++; else  const c = 40; '
+PASS Had syntax error 'if (i = 0)  const c = 40;  else i++;'
+PASS Had syntax error 'with ({})  const c = 40; '
+PASS Did not have syntax error: 'for (var i = 0; i &lt; 4; i++) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'for (var i in {}) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'for (i in {}) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'for (var i of []) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'for (i of []) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'while (i = 0) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'do { const c = 40, d = 50; } while (i = 0)'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40, d = 50; } else { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'if (i = 0) i++; else { const c = 40, d = 50; }'
+PASS Did not have syntax error: 'if (i = 0) { const c = 40, d = 50; } else i++;'
+PASS Did not have syntax error: 'with ({}) { const c = 40, d = 50; }'
+PASS Had syntax error 'for (var i = 0; i &lt; 4; i++)  const c = 40, d = 50; '
+PASS Had syntax error 'for (var i in {})  const c = 40, d = 50; '
+PASS Had syntax error 'for (i in {})  const c = 40, d = 50; '
+PASS Had syntax error 'for (var i of [])  const c = 40, d = 50; '
+PASS Had syntax error 'for (i of [])  const c = 40, d = 50; '
+PASS Had syntax error 'while (i = 0)  const c = 40, d = 50; '
+PASS Had syntax error 'do  const c = 40, d = 50;  while (i = 0)'
+PASS Had syntax error 'if (i = 0)  const c = 40, d = 50; '
+PASS Had syntax error 'if (i = 0)  const c = 40, d = 50;  else  const c = 40, d = 50; '
+PASS Had syntax error 'if (i = 0) i++; else  const c = 40, d = 50; '
+PASS Had syntax error 'if (i = 0)  const c = 40, d = 50;  else i++;'
+PASS Had syntax error 'with ({})  const c = 40, d = 50; '
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsstatementlistitemsyntaxerrorshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/statement-list-item-syntax-errors.html (0 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/statement-list-item-syntax-errors.html	                        (rev 0)
+++ trunk/LayoutTests/js/statement-list-item-syntax-errors.html	2015-07-06 22:18:58 UTC (rev 186379)
</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/statement-list-item-syntax-errors.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="trunkLayoutTestssputnikConformance07_Lexical_Conventions75_Tokens753_Future_Reserved_WordsS753_A15expectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/LayoutTests/sputnik/Conformance/07_Lexical_Conventions/7.5_Tokens/7.5.3_Future_Reserved_Words/S7.5.3_A1.5-expected.txt	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-CONSOLE MESSAGE: line 76: SyntaxError: Unexpected keyword 'class'. Class declaration is not allowed in a lexically nested statement.
</del><ins>+CONSOLE MESSAGE: line 76: SyntaxError: Unexpected token '='
</ins><span class="cx"> S7.5.3_A1.5
</span><span class="cx"> 
</span><span class="cx"> PASS Expected parsing failure
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/Source/JavaScriptCore/ChangeLog	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2015-07-06  Saam barati  &lt;saambarati1 at gmail.com&gt;
+
+        JSC's parser should follow the ES6 spec with respect to parsing Declarations
+        https://bugs.webkit.org/show_bug.cgi?id=146621
+
+        Reviewed by Mark Lam.
+
+        There were a few locations where JSC would allow declaration statements
+        in incorrect ways. JSC didn't distinguish between 'Statement' and
+        'StatementListItem' grammar productions. The relevant grammar is here:
+        http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
+
+        From the ECMA Script 6.0 spec:
+        1. Section 13.6 The if Statement (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-if-statement) 
+         says that IfStatements only takes Statements for the &quot;then-else&quot; clauses, not StatementListItems.
+         (Same with 'while/for/do-while' loop bodies).
+        2. Section 13 ECMAScript Language: Statements and Declarations 
+         (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-ecmascript-language-statements-and-declarations)
+         defines the syntax of Statements, and they do not include ClassDeclarations and LexicalDeclarations 
+         (const, let, see 13.3.1 Let and Const Declarations).
+         Declarations can only be in the “then-else” clauses when embedded in a StatementListItem in a BlockStatement (see 13.2).
+
+        Hence, the following style of declarations are no longer allowed:
+            'if/for/while (condition) const x = 40;'
+            'if/for/while (condition) class C { }'
+
+        Instead, we mandate such declaration constructs are within a StatementList 
+       (which is the production that JSC's Parser::parseSourceElements function parses):
+           'if/for/while (condition) { const x = 40; }'
+           'if/for/while (condition) { class C { } }'
+
+        * parser/Parser.cpp:
+        (JSC::Parser&lt;LexerType&gt;::parseSourceElements):
+        (JSC::Parser&lt;LexerType&gt;::parseStatementListItem):
+        (JSC::Parser&lt;LexerType&gt;::parseVarDeclaration):
+        (JSC::Parser&lt;LexerType&gt;::parseStatement):
+        (JSC::Parser&lt;LexerType&gt;::parseExpressionStatement):
+        * parser/Parser.h:
+        (JSC::Parser::getLabel):
+
</ins><span class="cx"> 2015-07-06  Alex Christensen  &lt;achristensen at webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed debug build fix after r186358.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.cpp (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.cpp	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/Source/JavaScriptCore/parser/Parser.cpp	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -369,7 +369,7 @@
</span><span class="cx">     UNUSED_PARAM(functionParseType);
</span><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    while (TreeStatement statement = parseStatement(context, directive, &amp;directiveLiteralLength)) {
</del><ins>+    while (TreeStatement statement = parseStatementListItem(context, directive, &amp;directiveLiteralLength)) {
</ins><span class="cx">         if (mode == CheckForStrictMode &amp;&amp; !seenNonDirective) {
</span><span class="cx">             if (directive) {
</span><span class="cx">                 // &quot;use strict&quot; must be the exact literal without escape sequences or line continuation.
</span><span class="lines">@@ -402,7 +402,31 @@
</span><span class="cx">     propagateError();
</span><span class="cx">     return sourceElements;
</span><span class="cx"> }
</span><ins>+template &lt;typename LexerType&gt;
+template &lt;class TreeBuilder&gt; TreeStatement Parser&lt;LexerType&gt;::parseStatementListItem(TreeBuilder&amp; context, const Identifier*&amp; directive, unsigned* directiveLiteralLength)
+{
+    // The grammar is documented here:
+    // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
+    TreeStatement result = 0;
+    switch (m_token.m_type) {
+    case CONSTTOKEN:
+        result = parseConstDeclaration(context);
+        break;
+#if ENABLE(ES6_CLASS_SYNTAX)
+    case CLASSTOKEN:
+        result = parseClassDeclaration(context);
+        break;
+#endif
+    default:
+        // FIXME: This needs to consider 'let' in bug:
+        // https://bugs.webkit.org/show_bug.cgi?id=142944
+        result = parseStatement(context, directive, directiveLiteralLength);
+        break;
+    }
</ins><span class="cx"> 
</span><ins>+    return result;
+}
+
</ins><span class="cx"> template &lt;typename LexerType&gt;
</span><span class="cx"> template &lt;class TreeBuilder&gt; TreeStatement Parser&lt;LexerType&gt;::parseVarDeclaration(TreeBuilder&amp; context)
</span><span class="cx"> {
</span><span class="lines">@@ -1263,15 +1287,6 @@
</span><span class="cx">     case VAR:
</span><span class="cx">         result = parseVarDeclaration(context);
</span><span class="cx">         break;
</span><del>-    case CONSTTOKEN:
-        result = parseConstDeclaration(context);
-        break;
-#if ENABLE(ES6_CLASS_SYNTAX)
-    case CLASSTOKEN:
-        failIfFalse(m_statementDepth == 1, &quot;Class declaration is not allowed in a lexically nested statement&quot;);
-        result = parseClassDeclaration(context);
-        break;
-#endif
</del><span class="cx">     case FUNCTION:
</span><span class="cx">         failIfFalseIfStrict(m_statementDepth == 1, &quot;Strict mode does not allow function declarations in a lexically nested statement&quot;);
</span><span class="cx">         result = parseFunctionDeclaration(context);
</span><span class="lines">@@ -1938,6 +1953,19 @@
</span><span class="cx"> template &lt;typename LexerType&gt;
</span><span class="cx"> template &lt;class TreeBuilder&gt; TreeStatement Parser&lt;LexerType&gt;::parseExpressionStatement(TreeBuilder&amp; context)
</span><span class="cx"> {
</span><ins>+    switch (m_token.m_type) {
+    // Consult: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-expression-statement
+    // The ES6 spec mandates that we should fail from FUNCTION token here. We handle this case 
+    // in parseStatement() which is the only caller of parseExpressionStatement().
+    // We actually allow FUNCTION in situations where it should not be allowed unless we're in strict mode.
+    case CLASSTOKEN:
+        failWithMessage(&quot;'class' declaration is not directly within a block statement&quot;);
+        break;
+    default:
+        // FIXME: when implementing 'let' we should fail when we see the token sequence &quot;let [&quot;.
+        // https://bugs.webkit.org/show_bug.cgi?id=142944
+        break;
+    }
</ins><span class="cx">     JSTextPosition start = tokenStartPosition();
</span><span class="cx">     JSTokenLocation location(tokenLocation());
</span><span class="cx">     TreeExpression expression = parseExpression(context);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (186378 => 186379)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h	2015-07-06 22:03:37 UTC (rev 186378)
+++ trunk/Source/JavaScriptCore/parser/Parser.h	2015-07-06 22:18:58 UTC (rev 186379)
</span><span class="lines">@@ -767,6 +767,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeSourceElements parseSourceElements(TreeBuilder&amp;, SourceElementsMode, FunctionParseType);
</span><ins>+    template &lt;class TreeBuilder&gt; TreeStatement parseStatementListItem(TreeBuilder&amp;, const Identifier*&amp; directive, unsigned* directiveLiteralLength);
</ins><span class="cx">     template &lt;class TreeBuilder&gt; TreeStatement parseStatement(TreeBuilder&amp;, const Identifier*&amp; directive, unsigned* directiveLiteralLength = 0);
</span><span class="cx"> #if ENABLE(ES6_CLASS_SYNTAX)
</span><span class="cx">     template &lt;class TreeBuilder&gt; TreeStatement parseClassDeclaration(TreeBuilder&amp;);
</span></span></pre>
</div>
</div>

</body>
</html>


More information about the webkit-changes mailing list