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 <saambarati1 at gmail.com>
+
+ 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 <ddkilzer at apple.com>
</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: "function f() { var = 7 }"
</span><span class="cx"> PASS Invalid: "var c (6)"
</span><span class="cx"> PASS Invalid: "function f() { var c (6) }"
</span><del>-PASS Valid: "if (a) var a,b; else const b, c"
-PASS Valid: "function f() { if (a) var a,b; else const b, c }"
</del><ins>+PASS Valid: "if (a) var a,b; else { const b, c }"
+PASS Valid: "function f() { if (a) var a,b; else { const b, c } }"
</ins><span class="cx"> PASS Invalid: "var 5 = 6"
</span><span class="cx"> PASS Invalid: "function f() { var 5 = 6 }"
</span><span class="cx"> PASS Valid: "while (0) var a, b, c=6, d, e, f=5*6, g=f*h, h"
</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("with({foo:42}) const bar = 5;");
</del><ins>+ eval("with({foo:42}) { const bar = 5; }");
</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("var");
</span><span class="cx"> invalid("var = 7");
</span><span class="cx"> invalid("var c (6)");
</span><del>-valid ("if (a) var a,b; else const b, c");
</del><ins>+valid ("if (a) var a,b; else { const b, c }");
</ins><span class="cx"> invalid("var 5 = 6");
</span><span class="cx"> valid ("while (0) var a, b, c=6, d, e, f=5*6, g=f*h, h");
</span><span class="cx"> invalid("var a = if (b) { c }");
</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(
+ "See spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements"
+);
+
+var AllShouldThrow = "AllShouldThrow";
+var NoneShouldThrow = "NoneShouldThrow";
+
+function testSyntax(asBlock, body, throwStatus) {
+ var open = asBlock ? '{' : '';
+ var close = asBlock ? '}' : '';
+
+ var commonLanguageConstructs = [
+ `for (var i = 0; i < 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 = [
+ "class C {};",
+ "class C extends (class A {}) {};",
+ "const c = 40;",
+ "const c = 40, d = 50;"
+ ];
+ 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 "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Did not have syntax error: 'for (var i = 0; i < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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>+<!DOCTYPE html>
+<html>
+<body>
+<script src="../resources/js-test-pre.js"></script>
+<script src="script-tests/statement-list-item-syntax-errors.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
</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 <saambarati1 at gmail.com>
+
+ 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 "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):
+
</ins><span class="cx"> 2015-07-06 Alex Christensen <achristensen at webkit.org>
</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, &directiveLiteralLength)) {
</del><ins>+ while (TreeStatement statement = parseStatementListItem(context, directive, &directiveLiteralLength)) {
</ins><span class="cx"> if (mode == CheckForStrictMode && !seenNonDirective) {
</span><span class="cx"> if (directive) {
</span><span class="cx"> // "use strict" 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 <typename LexerType>
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& 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 <typename LexerType>
</span><span class="cx"> template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaration(TreeBuilder& 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, "Class declaration is not allowed in a lexically nested statement");
- result = parseClassDeclaration(context);
- break;
-#endif
</del><span class="cx"> case FUNCTION:
</span><span class="cx"> failIfFalseIfStrict(m_statementDepth == 1, "Strict mode does not allow function declarations in a lexically nested statement");
</span><span class="cx"> result = parseFunctionDeclaration(context);
</span><span class="lines">@@ -1938,6 +1953,19 @@
</span><span class="cx"> template <typename LexerType>
</span><span class="cx"> template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& 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("'class' declaration is not directly within a block statement");
+ break;
+ default:
+ // FIXME: when implementing 'let' we should fail when we see the token sequence "let [".
+ // 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 <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode, FunctionParseType);
</span><ins>+ template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
</ins><span class="cx"> template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
</span><span class="cx"> #if ENABLE(ES6_CLASS_SYNTAX)
</span><span class="cx"> template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&);
</span></span></pre>
</div>
</div>
</body>
</html>
More information about the webkit-changes
mailing list