Title: [202074] trunk
Revision
202074
Author
commit-qu...@webkit.org
Date
2016-06-14 17:45:25 -0700 (Tue, 14 Jun 2016)

Log Message

The parser doesn't properly parse "super" when default parameter is an
arrow function.
https://bugs.webkit.org/show_bug.cgi?id=157872.

Patch by Caio Lima <ticaiol...@gmail.com> on 2016-06-14
Reviewed by Saam Barati.

The "super" member or "super()" could not be used when default parameter is an
arrow function, resuling in sytax error. It happened because the
"closestOrdinaryFunctionScope" was not being initialized properly
before "parseFunctionParameters" step and the condition
"functionSuperBinding == SuperBinding::NotNeeded" or
"functionConstructorKind != ConstructorKind::Derived" on
"Parser<LexerType>::parseMemberExpression" step were being true
resulting in SyntaxError.

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionInfo): setting
"functionScope->setExpectedSuperBinding(expectedSuperBinding)" and
"functionScope->setConstructorKind(constructorKind)" before
"parseFunctionParameters" step.

Modified Paths

Diff

Modified: trunk/LayoutTests/js/parser-syntax-check-expected.txt (202073 => 202074)


--- trunk/LayoutTests/js/parser-syntax-check-expected.txt	2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/LayoutTests/js/parser-syntax-check-expected.txt	2016-06-15 00:45:25 UTC (rev 202074)
@@ -1259,6 +1259,18 @@
 PASS Invalid: "function f() { var f = cond ? x=>{x.foo :} : x=>x + x + x + x + x + x + x }"
 PASS Invalid: "var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x"
 PASS Invalid: "function f() { var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } } }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } } }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } } }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } } }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } } }"
+PASS Valid:   "class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }"
+PASS Valid:   "function f() { class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } } }"
 PASS e.line is 1
 PASS foo is 'PASS'
 PASS bar is 'PASS'

Modified: trunk/LayoutTests/js/script-tests/parser-syntax-check.js (202073 => 202074)


--- trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/LayoutTests/js/script-tests/parser-syntax-check.js	2016-06-15 00:45:25 UTC (rev 202074)
@@ -740,8 +740,13 @@
 invalid("var f = cond ? x=>x.foo : : x=>x + x + x + x + x + x + x");
 invalid("var f = cond ? x=>{x.foo :} : x=>x + x + x + x + x + x + x");
 invalid("var f = cond ? x=>{x.foo } => : x=>x + x + x + x + x + x + x");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => super.foo) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return super.foo}) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = () => {return () => super.foo}) { return y()(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { x(y = (y = () => super.foo) => {return y()}) { return y(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super.foo) { super(); this._x_f = x; } x() { return this._x_f(); } }");
+valid("class C { constructor() { this._x = 45; } get foo() { return this._x;} } class D extends C { constructor(x = () => super()) { x(); } x() { return super.foo; } }");
 
-
 try { eval("a.b.c = {};"); } catch(e1) { e=e1; shouldBe("e.line", "1") }
 foo = 'FAIL';
 bar = 'PASS';

Modified: trunk/Source/_javascript_Core/ChangeLog (202073 => 202074)


--- trunk/Source/_javascript_Core/ChangeLog	2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-06-15 00:45:25 UTC (rev 202074)
@@ -1,3 +1,26 @@
+2016-06-14  Caio Lima  <ticaiol...@gmail.com>
+
+        The parser doesn't properly parse "super" when default parameter is an
+        arrow function.
+        https://bugs.webkit.org/show_bug.cgi?id=157872.
+
+        Reviewed by Saam Barati.
+
+        The "super" member or "super()" could not be used when default parameter is an
+        arrow function, resuling in sytax error. It happened because the
+        "closestOrdinaryFunctionScope" was not being initialized properly
+        before "parseFunctionParameters" step and the condition
+        "functionSuperBinding == SuperBinding::NotNeeded" or
+        "functionConstructorKind != ConstructorKind::Derived" on
+        "Parser<LexerType>::parseMemberExpression" step were being true
+        resulting in SyntaxError.
+
+        * parser/Parser.cpp: 
+        (JSC::Parser<LexerType>::parseFunctionInfo): setting
+        "functionScope->setExpectedSuperBinding(expectedSuperBinding)" and
+        "functionScope->setConstructorKind(constructorKind)" before
+        "parseFunctionParameters" step.
+
 2016-06-14  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: Rename Timeline.setAutoCaptureInstruments to Timeline.setInstruments

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (202073 => 202074)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2016-06-15 00:45:25 UTC (rev 202074)
@@ -1927,6 +1927,8 @@
     bool upperScopeIsGenerator = currentScope()->isGenerator();
     AutoPopScopeRef functionScope(this, pushScope());
     functionScope->setSourceParseMode(mode);
+    functionScope->setExpectedSuperBinding(expectedSuperBinding);
+    functionScope->setConstructorKind(constructorKind);
     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
     int functionNameStart = m_token.m_location.startOffset;
     const Identifier* lastFunctionName = m_parserState.lastFunctionName;
@@ -1948,8 +1950,6 @@
 
             ConstructorKind constructorKind = static_cast<ConstructorKind>(cachedInfo->constructorKind);
             SuperBinding expectedSuperBinding = static_cast<SuperBinding>(cachedInfo->expectedSuperBinding);
-            functionScope->setConstructorKind(constructorKind);
-            functionScope->setExpectedSuperBinding(expectedSuperBinding);
 
             endLocation.line = cachedInfo->lastTokenLine;
             endLocation.startOffset = cachedInfo->lastTokenStartOffset;

Modified: trunk/Source/_javascript_Core/tests/stress/arrow-functions-as-default-parameter-values.js (202073 => 202074)


--- trunk/Source/_javascript_Core/tests/stress/arrow-functions-as-default-parameter-values.js	2016-06-15 00:43:23 UTC (rev 202073)
+++ trunk/Source/_javascript_Core/tests/stress/arrow-functions-as-default-parameter-values.js	2016-06-15 00:45:25 UTC (rev 202074)
@@ -106,23 +106,98 @@
     foo();
 });
 
-// FIXME: Our parser throws a syntax error here but it should not.
-// https://bugs.webkit.org/show_bug.cgi?id=157872
-/*
 test(function() {
     class C {
         constructor() { this._x = 45; }
         get foo() { return this._x;}
     }
     class D extends C {
-        //constructor(x = ()=>super.foo) {
-        //    super();
-        //    assert(x() === 45);
-        //}
+        constructor(x = () => super.foo) {
+            super();
+            assert(x() === 45);
+        }
         x(x = ()=>super.foo) {
             return x();
         }
     }
-    //(new D).x();
+    assert((new D).x() === 45);
 });
-*/
+
+test(function() {
+    class C {
+        constructor() { this._x = 45; }
+        get foo() { return this._x;}
+    }
+    class D extends C {
+        x(x = () => {return super.foo}) {
+            return x();
+        }
+    }
+    assert((new D).x() === 45);
+});
+
+test(function() {
+    class C {
+        constructor() { this._x = 45; }
+        get foo() { return this._x;}
+    }
+    class D extends C {
+        x(x = () => {return () => super.foo}) {
+            return x()();
+        }
+    }
+    assert((new D).x() === 45);
+});
+
+test(function() {
+    class C {
+        constructor() { this._x = 45; }
+        get foo() { return this._x;}
+    }
+
+    class D extends C {
+        x(y = (y = () => super.foo) => {return y()}) {
+            return y();
+        }
+    }
+    assert((new D).x() === 45);
+});
+
+test(function() {
+    class C {
+        constructor() { this._x = 45; }
+        get foo() { return this._x;}
+    }
+
+    class D extends C {
+        constructor(x = () => super.foo) {
+            super();
+            this._x_f = x;
+        }
+
+        x() {
+            return this._x_f(); 
+        }
+    }
+    assert((new D).x() === 45);
+});
+
+test(function() {
+    class C {
+        constructor() { this._x = 45; }
+        get foo() { return this._x;}
+    }
+
+    class D extends C {
+
+        constructor(x = () => super()) {
+            x();
+        }
+
+        x() {
+            return super.foo;
+        }
+    }
+    assert((new D).x() === 45);
+});
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to