Title: [181724] trunk
Revision
181724
Author
[email protected]
Date
2015-03-18 20:27:00 -0700 (Wed, 18 Mar 2015)

Log Message

ES6 Classes: Extends should accept an _expression_ without parenthesis
https://bugs.webkit.org/show_bug.cgi?id=142840

Reviewed by Ryosuke Niwa.

Source/_javascript_Core:

* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
"extends" allows a LeftHandExpression (new _expression_ / call _expression_,
which includes a member _expression_), not a primary _expression_. Our
parseMemberExpression does all of these.

LayoutTests:

* js/class-syntax-extends-expected.txt:
* js/script-tests/class-syntax-extends.js:
Extend the test to test cases of extends with different types of expressions.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (181723 => 181724)


--- trunk/LayoutTests/ChangeLog	2015-03-19 03:26:58 UTC (rev 181723)
+++ trunk/LayoutTests/ChangeLog	2015-03-19 03:27:00 UTC (rev 181724)
@@ -1,3 +1,14 @@
+2015-03-18  Joseph Pecoraro  <[email protected]>
+
+        ES6 Classes: Extends should accept an _expression_ without parenthesis
+        https://bugs.webkit.org/show_bug.cgi?id=142840
+
+        Reviewed by Ryosuke Niwa.
+
+        * js/class-syntax-extends-expected.txt:
+        * js/script-tests/class-syntax-extends.js:
+        Extend the test to test cases of extends with different types of expressions.
+
 2015-03-18  Said Abou-Hallawa  <[email protected]>
 
         Switching between two SVG images with no intrinsic sizes causes them to get the default SVG size instead of the container size.

Modified: trunk/LayoutTests/js/class-syntax-extends-expected.txt (181723 => 181724)


--- trunk/LayoutTests/js/class-syntax-extends-expected.txt	2015-03-19 03:26:58 UTC (rev 181723)
+++ trunk/LayoutTests/js/class-syntax-extends-expected.txt	2015-03-19 03:27:00 UTC (rev 181724)
@@ -25,6 +25,28 @@
 PASS baseWithBadPrototype.prototype = "abc" did not throw exception.
 PASS x = class extends baseWithBadPrototype { constructor() { } } threw exception TypeError: The superclass's prototype is not an object..
 PASS baseWithBadPrototype.prototype = null; x = class extends baseWithBadPrototype { constructor() { } } did not throw exception.
+PASS x = 1; c = class extends ++x { constructor() { } }; threw exception SyntaxError: Unexpected token '++'.
+PASS x = 1; c = class extends x++ { constructor() { } }; threw exception SyntaxError: Unexpected token '++'. Expected opening '{' at the start of a class body..
+PASS x = 1; c = class extends (++x) { constructor() { } }; threw exception TypeError: The superclass is not an object..
+PASS x = 1; c = class extends (x++) { constructor() { } }; threw exception TypeError: The superclass is not an object..
+PASS x = 1; try { c = class extends (++x) { constructor() { } } } catch (e) { }; x is 2
+PASS x = 1; try { c = class extends (x++) { constructor() { } } } catch (e) { }; x is 2
+PASS namespace = {}; namespace.A = class { }; namespace.B = class extends namespace.A { } did not throw exception.
+PASS namespace = {}; namespace.A = class A { }; namespace.B = class B extends namespace.A { } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace.A { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class A { constructor() { } }; namespace.B = class B extends namespace.A { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A) { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace["A"] { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; function getClassA() { return namespace.A }; namespace.B = class extends getClassA() { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; function getClass(prop) { return namespace[prop] }; namespace.B = class extends getClass("A") { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (false||null||namespace.A) { constructor() { } } did not throw exception.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends false||null||namespace.A { constructor() { } } threw exception SyntaxError: Unexpected token '||'. Expected opening '{' at the start of a class body..
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (x++, namespace.A) { constructor() { } }; did not throw exception.
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A, x++) { constructor() { } }; threw exception TypeError: The superclass is not an object..
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A { constructor() { } } threw exception TypeError: The superclass's prototype is not an object..
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A() { constructor() { } } threw exception TypeError: The superclass's prototype is not an object..
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (x++, namespace.A) { constructor() { } } } catch (e) { } x is 2
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x is 2
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/script-tests/class-syntax-extends.js (181723 => 181724)


--- trunk/LayoutTests/js/script-tests/class-syntax-extends.js	2015-03-19 03:26:58 UTC (rev 181723)
+++ trunk/LayoutTests/js/script-tests/class-syntax-extends.js	2015-03-19 03:27:00 UTC (rev 181724)
@@ -39,4 +39,28 @@
 shouldThrow('x = class extends baseWithBadPrototype { constructor() { } }', '"TypeError: The superclass\'s prototype is not an object."');
 shouldNotThrow('baseWithBadPrototype.prototype = null; x = class extends baseWithBadPrototype { constructor() { } }');
 
+shouldThrow('x = 1; c = class extends ++x { constructor() { } };');
+shouldThrow('x = 1; c = class extends x++ { constructor() { } };');
+shouldThrow('x = 1; c = class extends (++x) { constructor() { } };');
+shouldThrow('x = 1; c = class extends (x++) { constructor() { } };');
+shouldBe('x = 1; try { c = class extends (++x) { constructor() { } } } catch (e) { }; x', '2');
+shouldBe('x = 1; try { c = class extends (x++) { constructor() { } } } catch (e) { }; x', '2');
+
+shouldNotThrow('namespace = {}; namespace.A = class { }; namespace.B = class extends namespace.A { }');
+shouldNotThrow('namespace = {}; namespace.A = class A { }; namespace.B = class B extends namespace.A { }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace.A { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class A { constructor() { } }; namespace.B = class B extends namespace.A { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A) { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace["A"] { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; function getClassA() { return namespace.A }; namespace.B = class extends getClassA() { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; function getClass(prop) { return namespace[prop] }; namespace.B = class extends getClass("A") { constructor() { } }');
+shouldNotThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (false||null||namespace.A) { constructor() { } }');
+shouldThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends false||null||namespace.A { constructor() { } }');
+shouldNotThrow('x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (x++, namespace.A) { constructor() { } };');
+shouldThrow('x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A, x++) { constructor() { } };');
+shouldThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A { constructor() { } }');
+shouldThrow('namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A() { constructor() { } }');
+shouldBe('x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (x++, namespace.A) { constructor() { } } } catch (e) { } x', '2');
+shouldBe('x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x', '2');
+
 var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (181723 => 181724)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-19 03:26:58 UTC (rev 181723)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-19 03:27:00 UTC (rev 181724)
@@ -1,5 +1,18 @@
 2015-03-18  Joseph Pecoraro  <[email protected]>
 
+        ES6 Classes: Extends should accept an _expression_ without parenthesis
+        https://bugs.webkit.org/show_bug.cgi?id=142840
+
+        Reviewed by Ryosuke Niwa.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClass):
+        "extends" allows a LeftHandExpression (new _expression_ / call _expression_,
+        which includes a member _expression_), not a primary _expression_. Our
+        parseMemberExpression does all of these.
+
+2015-03-18  Joseph Pecoraro  <[email protected]>
+
         Web Inspector: Debugger Popovers and Probes should use FormattedValue/ObjectTreeView instead of Custom/ObjectPropertiesSection
         https://bugs.webkit.org/show_bug.cgi?id=142830
 

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (181723 => 181724)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2015-03-19 03:26:58 UTC (rev 181723)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2015-03-19 03:27:00 UTC (rev 181724)
@@ -1485,7 +1485,7 @@
 
     TreeExpression parentClass = 0;
     if (consume(EXTENDS)) {
-        parentClass = parsePrimaryExpression(context);
+        parentClass = parseMemberExpression(context);
         failIfFalse(parentClass, "Cannot parse the parent class name");
     }
     const ConstructorKind constructorKind = parentClass ? ConstructorKind::Derived : ConstructorKind::Base;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to