ES6 class syntax should use block scoping
authorsaambarati1@gmail.com <saambarati1@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jul 2015 21:05:19 +0000 (21:05 +0000)
committersaambarati1@gmail.com <saambarati1@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jul 2015 21:05:19 +0000 (21:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142567

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

We treat class declarations like we do "let" declarations.
The class name is under TDZ until the class declaration
statement is evaluated. Class declarations also follow
the same rules as "let": No duplicate definitions inside
a lexical environment.

* parser/ASTBuilder.h:
(JSC::ASTBuilder::createClassDeclStatement):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClassDeclaration):
* tests/stress/class-syntax-block-scoping.js: Added.
(assert):
(truth):
(.):
* tests/stress/class-syntax-definition-semantics.js: Added.
(shouldBeSyntaxError):
(shouldNotBeSyntaxError):
(truth):
* tests/stress/class-syntax-tdz.js:
(assert):
(shouldThrowTDZ):
(truth):
(.):

LayoutTests:

* js/class-constructor-return-expected.txt:
* js/class-syntax-call-expected.txt:
* js/class-syntax-declaration-expected.txt:
* js/class-syntax-default-constructor-expected.txt:
* js/class-syntax-extends-expected.txt:
* js/class-syntax-name-expected.txt:
* js/class-syntax-super-expected.txt:
* js/script-tests/class-constructor-return.js:
(shouldThrow):
(shouldNotThrow):
(shouldBeTrue):
(shouldBeFalse):
* js/script-tests/class-syntax-call.js:
(A):
(B):
(shouldThrow):
(shouldNotThrow):
* js/script-tests/class-syntax-declaration.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
* js/script-tests/class-syntax-default-constructor.js:
(shouldThrow):
(shouldBe):
(shouldBeTrue):
(assert):
(A):
(B):
* js/script-tests/class-syntax-extends.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(Base):
(Base.prototype.baseMethod):
* js/script-tests/class-syntax-name.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(runTestShouldBe):
* js/script-tests/class-syntax-super.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(shouldBeFalse):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
LayoutTests/ChangeLog
LayoutTests/js/class-constructor-return-expected.txt
LayoutTests/js/class-syntax-call-expected.txt
LayoutTests/js/class-syntax-declaration-expected.txt
LayoutTests/js/class-syntax-default-constructor-expected.txt
LayoutTests/js/class-syntax-extends-expected.txt
LayoutTests/js/class-syntax-name-expected.txt
LayoutTests/js/class-syntax-super-expected.txt
LayoutTests/js/intl-collator-expected.txt
LayoutTests/js/intl-datetimeformat-expected.txt
LayoutTests/js/intl-numberformat-expected.txt
LayoutTests/js/script-tests/class-constructor-return.js
LayoutTests/js/script-tests/class-syntax-call.js
LayoutTests/js/script-tests/class-syntax-declaration.js
LayoutTests/js/script-tests/class-syntax-default-constructor.js
LayoutTests/js/script-tests/class-syntax-extends.js
LayoutTests/js/script-tests/class-syntax-name.js
LayoutTests/js/script-tests/class-syntax-super.js
LayoutTests/js/script-tests/intl-collator.js
LayoutTests/js/script-tests/intl-datetimeformat.js
LayoutTests/js/script-tests/intl-numberformat.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/class-syntax-definition-semantics.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/class-syntax-tdz.js

index 406a2cc..4734ec2 100644 (file)
@@ -1,3 +1,58 @@
+2015-07-31  Saam barati  <saambarati1@gmail.com>
+
+        ES6 class syntax should use block scoping
+        https://bugs.webkit.org/show_bug.cgi?id=142567
+
+        Reviewed by Geoffrey Garen.
+
+        * js/class-constructor-return-expected.txt:
+        * js/class-syntax-call-expected.txt:
+        * js/class-syntax-declaration-expected.txt:
+        * js/class-syntax-default-constructor-expected.txt:
+        * js/class-syntax-extends-expected.txt:
+        * js/class-syntax-name-expected.txt:
+        * js/class-syntax-super-expected.txt:
+        * js/script-tests/class-constructor-return.js:
+        (shouldThrow):
+        (shouldNotThrow):
+        (shouldBeTrue):
+        (shouldBeFalse):
+        * js/script-tests/class-syntax-call.js:
+        (A):
+        (B):
+        (shouldThrow):
+        (shouldNotThrow):
+        * js/script-tests/class-syntax-declaration.js:
+        (shouldThrow):
+        (shouldNotThrow):
+        (shouldBe):
+        * js/script-tests/class-syntax-default-constructor.js:
+        (shouldThrow):
+        (shouldBe):
+        (shouldBeTrue):
+        (assert):
+        (A):
+        (B):
+        * js/script-tests/class-syntax-extends.js:
+        (shouldThrow):
+        (shouldNotThrow):
+        (shouldBe):
+        (shouldBeTrue):
+        (Base):
+        (Base.prototype.baseMethod):
+        * js/script-tests/class-syntax-name.js:
+        (shouldThrow):
+        (shouldNotThrow):
+        (shouldBe):
+        (shouldBeTrue):
+        (runTestShouldBe):
+        * js/script-tests/class-syntax-super.js:
+        (shouldThrow):
+        (shouldNotThrow):
+        (shouldBe):
+        (shouldBeTrue):
+        (shouldBeFalse):
+
 2015-07-30  Matt Rajca  <mrajca@apple.com>
 
         Media Session: add test for MediaSession.releaseSession()
index b892acc..de95d73 100644 (file)
@@ -4,92 +4,92 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 Base class
-PASS (new BaseNoReturn) instanceof BaseNoReturn is true
-PASS (new BaseReturnImplicit) instanceof BaseReturnImplicit is true
-PASS (new BaseReturnImplicit) !== undefined is true
-PASS (new BaseReturnUndefined) instanceof BaseReturnUndefined is true
-PASS (new BaseReturnUndefined) !== undefined is true
-PASS (new BaseReturnThis) instanceof BaseReturnThis is true
-PASS (new BaseReturnObject) instanceof BaseReturnObject is false
-PASS typeof (new BaseReturnObject) === "object" is true
-PASS (new BaseReturnObject2) instanceof BaseReturnObject is false
-PASS (new BaseReturnObject2) === globalVariable is true
-PASS (new BaseReturnString) instanceof BaseReturnString is true
-PASS typeof (new BaseReturnString) !== "string" is true
-PASS (new BaseReturnNumber) instanceof BaseReturnNumber is true
-PASS typeof (new BaseReturnNumber) !== "number" is true
-PASS (new BaseReturnNull) instanceof BaseReturnNull is true
-PASS (new BaseReturnNull) !== null is true
-PASS (new BaseReturnSymbol) instanceof BaseReturnSymbol is true
-PASS (new BaseReturnSymbol) !== globalSymbol is true
-PASS (new BaseThrow) threw exception Thrown Exception String.
+PASS (new BaseNoReturn) instanceof BaseNoReturn
+PASS (new BaseReturnImplicit) instanceof BaseReturnImplicit
+PASS (new BaseReturnImplicit) !== undefined
+PASS (new BaseReturnUndefined) instanceof BaseReturnUndefined
+PASS (new BaseReturnUndefined) !== undefined
+PASS (new BaseReturnThis) instanceof BaseReturnThis
+PASS (new BaseReturnObject) instanceof BaseReturnObject
+PASS typeof (new BaseReturnObject) === "object"
+PASS (new BaseReturnObject2) instanceof BaseReturnObject
+PASS (new BaseReturnObject2) === globalVariable
+PASS (new BaseReturnString) instanceof BaseReturnString
+PASS typeof (new BaseReturnString) !== "string"
+PASS (new BaseReturnNumber) instanceof BaseReturnNumber
+PASS typeof (new BaseReturnNumber) !== "number"
+PASS (new BaseReturnNull) instanceof BaseReturnNull
+PASS (new BaseReturnNull) !== null
+PASS (new BaseReturnSymbol) instanceof BaseReturnSymbol
+PASS (new BaseReturnSymbol) !== globalSymbol
+PASS (new BaseThrow)
 
 Function constructor (non-class)
-PASS (new FunctionNoReturn) instanceof FunctionNoReturn is true
-PASS (new FunctionReturnImplicit) instanceof FunctionReturnImplicit is true
-PASS (new FunctionReturnImplicit) !== undefined is true
-PASS (new FunctionReturnUndefined) instanceof FunctionReturnUndefined is true
-PASS (new FunctionReturnUndefined) !== undefined is true
-PASS (new FunctionReturnThis) instanceof FunctionReturnThis is true
-PASS (new FunctionReturnObject) instanceof FunctionReturnObject is false
-PASS typeof (new FunctionReturnObject) === "object" is true
-PASS (new FunctionReturnObject2) instanceof FunctionReturnObject is false
-PASS (new FunctionReturnObject2) === globalVariable is true
-PASS (new FunctionReturnString) instanceof FunctionReturnString is true
-PASS typeof (new FunctionReturnString) !== "string" is true
-PASS (new FunctionReturnNumber) instanceof FunctionReturnNumber is true
-PASS typeof (new FunctionReturnNumber) !== "number" is true
-PASS (new FunctionReturnNull) instanceof FunctionReturnNull is true
-PASS (new FunctionReturnNull) !== null is true
-PASS (new FunctionReturnSymbol) instanceof FunctionReturnSymbol is true
-PASS (new FunctionReturnSymbol) !== globalSymbol is true
-PASS (new FunctionThrow) threw exception Thrown Exception String.
+PASS (new FunctionNoReturn) instanceof FunctionNoReturn
+PASS (new FunctionReturnImplicit) instanceof FunctionReturnImplicit
+PASS (new FunctionReturnImplicit) !== undefined
+PASS (new FunctionReturnUndefined) instanceof FunctionReturnUndefined
+PASS (new FunctionReturnUndefined) !== undefined
+PASS (new FunctionReturnThis) instanceof FunctionReturnThis
+PASS (new FunctionReturnObject) instanceof FunctionReturnObject
+PASS typeof (new FunctionReturnObject) === "object"
+PASS (new FunctionReturnObject2) instanceof FunctionReturnObject
+PASS (new FunctionReturnObject2) === globalVariable
+PASS (new FunctionReturnString) instanceof FunctionReturnString
+PASS typeof (new FunctionReturnString) !== "string"
+PASS (new FunctionReturnNumber) instanceof FunctionReturnNumber
+PASS typeof (new FunctionReturnNumber) !== "number"
+PASS (new FunctionReturnNull) instanceof FunctionReturnNull
+PASS (new FunctionReturnNull) !== null
+PASS (new FunctionReturnSymbol) instanceof FunctionReturnSymbol
+PASS (new FunctionReturnSymbol) !== globalSymbol
+PASS (new FunctionThrow)
 
 Derived class calling super()
-PASS (new DerivedNoReturn) instanceof DerivedNoReturn is true
-PASS (new DerivedReturnImplicit) instanceof DerivedReturnImplicit is true
-PASS (new DerivedReturnImplicit) !== undefined is true
-PASS (new DerivedReturnUndefined) instanceof DerivedReturnUndefined is true
-PASS (new DerivedReturnUndefined) !== undefined is true
-PASS (new DerivedReturnThis) instanceof DerivedReturnThis is true
-PASS (new DerivedReturnObject) instanceof DerivedReturnObject is false
-PASS typeof (new DerivedReturnObject) === "object" is true
-PASS (new DerivedReturnObject2) instanceof DerivedReturnObject2 is false
-PASS (new DerivedReturnObject2) === globalVariable is true
-PASS (new DerivedReturnString) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedReturnNumber) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedReturnNull) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedReturnSymbol) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedThrow) threw exception Thrown Exception String.
+PASS (new DerivedNoReturn) instanceof DerivedNoReturn
+PASS (new DerivedReturnImplicit) instanceof DerivedReturnImplicit
+PASS (new DerivedReturnImplicit) !== undefined
+PASS (new DerivedReturnUndefined) instanceof DerivedReturnUndefined
+PASS (new DerivedReturnUndefined) !== undefined
+PASS (new DerivedReturnThis) instanceof DerivedReturnThis
+PASS (new DerivedReturnObject) instanceof DerivedReturnObject
+PASS typeof (new DerivedReturnObject) === "object"
+PASS (new DerivedReturnObject2) instanceof DerivedReturnObject2
+PASS (new DerivedReturnObject2) === globalVariable
+PASS (new DerivedReturnString)
+PASS (new DerivedReturnNumber)
+PASS (new DerivedReturnNull)
+PASS (new DerivedReturnSymbol)
+PASS (new DerivedThrow)
 
 Derived class not calling super()
-PASS (new DerivedNoSuperNoReturn) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS (new DerivedNoSuperReturnImplicit) threw exception ReferenceError: Can't find variable: DerivedNoSuperReturnImplicit.
-PASS (new DerivedNoSuperReturnUndefined) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS (new DerivedNoSuperReturnThis) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS (new DerivedNoSuperReturnObject) did not throw exception.
-PASS (new DerivedNoSuperReturnObject2) did not throw exception.
-PASS (new DerivedNoSuperReturnString) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedNoSuperReturnNumber) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedNoSuperReturnNull) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedNoSuperReturnSymbol) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS (new DerivedNoSuperThrow) threw exception Thrown Exception String.
+PASS (new DerivedNoSuperNoReturn)
+PASS (new DerivedNoSuperReturnImplicit)
+PASS (new DerivedNoSuperReturnUndefined)
+PASS (new DerivedNoSuperReturnThis)
+PASS (new DerivedNoSuperReturnObject)
+PASS (new DerivedNoSuperReturnObject2)
+PASS (new DerivedNoSuperReturnString)
+PASS (new DerivedNoSuperReturnNumber)
+PASS (new DerivedNoSuperReturnNull)
+PASS (new DerivedNoSuperReturnSymbol)
+PASS (new DerivedNoSuperThrow)
 
 Derived class with default constructor and base class returning different values
-PASS (new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn is true
-PASS (new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit is true
-PASS (new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined is true
-PASS (new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject is false
-PASS typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object" is true
-PASS (new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2 is false
-PASS (new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable is true
-PASS (new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis is true
-PASS (new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString is true
-PASS (new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber is true
-PASS (new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull is true
-PASS (new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol is true
-PASS (new DerivedDefaultConstructorWithBaseThrow) threw exception Thrown Exception String.
-PASS successfullyParsed is true
+PASS (new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn
+PASS (new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit
+PASS (new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined
+PASS (new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject
+PASS typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object"
+PASS (new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2
+PASS (new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable
+PASS (new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis
+PASS (new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString
+PASS (new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber
+PASS (new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull
+PASS (new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol
+PASS (new DerivedDefaultConstructorWithBaseThrow)
+PASS successfullyParsed
 
 TEST COMPLETE
 
index 70363e0..78704f3 100644 (file)
@@ -3,14 +3,14 @@ Tests for calling the constructors of ES6 classes
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS new A did not throw exception.
-PASS A() threw exception TypeError: Cannot call a class constructor.
-PASS new B did not throw exception.
-PASS B() threw exception TypeError: Cannot call a class constructor.
-PASS new (class { constructor() {} })() did not throw exception.
-PASS (class { constructor() {} })() threw exception TypeError: Cannot call a class constructor.
-PASS new (class extends null { constructor() { super() } })() threw exception TypeError: undefined is not an object (evaluating 'super()').
-PASS (class extends null { constructor() { super() } })() threw exception TypeError: Cannot call a class constructor.
+PASS new A
+PASS A():::"TypeError: Cannot call a class constructor"
+PASS new B
+PASS B():::"TypeError: Cannot call a class constructor"
+PASS new (class { constructor() {} })()
+PASS (class { constructor() {} })():::"TypeError: Cannot call a class constructor"
+PASS new (class extends null { constructor() { super() } })():::"TypeError: undefined is not an object (evaluating 'super()')"
+PASS (class extends null { constructor() { super() } })():::"TypeError: Cannot call a class constructor"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index af6b7fa..36316ef 100644 (file)
@@ -3,42 +3,42 @@ Tests for ES6 class syntax declarations
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS constructorCallCount is 0
-PASS A.someStaticMethod() is staticMethodValue
-PASS A.someStaticGetter is getterValue
-PASS setterValue = undefined; A.someStaticSetter = 123; setterValue is 123
-PASS (new A).someInstanceMethod() is instanceMethodValue
-PASS constructorCallCount is 1
-PASS (new A).someGetter is getterValue
-PASS constructorCallCount is 2
-PASS (new A).someGetter is getterValue
-PASS setterValue = undefined; (new A).someSetter = 789; setterValue is 789
-PASS (new A).__proto__ is A.prototype
-PASS A.prototype.constructor is A
-PASS class threw exception SyntaxError: Unexpected end of script.
-PASS class [ threw exception SyntaxError: Unexpected token '['.
-PASS class { threw exception SyntaxError: Class statements must have a name..
-PASS class X { threw exception SyntaxError: Unexpected end of script.
-PASS class X { ( } threw exception SyntaxError: Unexpected token '('.
-PASS class X {} did not throw exception.
-PASS class X { constructor() {} constructor() {} } threw exception SyntaxError: Cannot declare multiple constructors in a single class..
-PASS class X { get constructor() {} } threw exception SyntaxError: Cannot declare a getter or setter named 'constructor'..
-PASS class X { set constructor() {} } threw exception SyntaxError: Cannot declare a getter or setter named 'constructor'..
-PASS class X { constructor() {} static constructor() { return staticMethodValue; } } did not throw exception.
-PASS class X { constructor() {} static constructor() { return staticMethodValue; } }; X.constructor() is staticMethodValue
-PASS class X { constructor() {} static prototype() {} } threw exception SyntaxError: Cannot declare a static method named 'prototype'..
-PASS class X { constructor() {} static get prototype() {} } threw exception SyntaxError: Cannot declare a static method named 'prototype'..
-PASS class X { constructor() {} static set prototype() {} } threw exception SyntaxError: Cannot declare a static method named 'prototype'..
-PASS class X { constructor() {} prototype() { return instanceMethodValue; } } did not throw exception.
-PASS class X { constructor() {} prototype() { return instanceMethodValue; } }; (new X).prototype() is instanceMethodValue
-PASS class X { constructor() {} set foo(a) {} } did not throw exception.
-PASS class X { constructor() {} set foo({x, y}) {} } did not throw exception.
-PASS class X { constructor() {} set foo() {} } threw exception SyntaxError: Unexpected token ')'. setter functions must have one parameter..
-PASS class X { constructor() {} set foo(a, b) {} } threw exception SyntaxError: Unexpected token ','. setter functions must have one parameter..
-PASS class X { constructor() {} get foo() {} } did not throw exception.
-PASS class X { constructor() {} get foo(x) {} } threw exception SyntaxError: Unexpected identifier 'x'. getter functions must have no parameters..
-PASS class X { constructor() {} get foo({x, y}) {} } threw exception SyntaxError: Unexpected token '{'. getter functions must have no parameters..
-PASS successfullyParsed is true
+PASS constructorCallCount:::0
+PASS A.someStaticMethod():::staticMethodValue
+PASS A.someStaticGetter:::getterValue
+PASS setterValue = undefined; A.someStaticSetter = 123; setterValue:::123
+PASS (new A).someInstanceMethod():::instanceMethodValue
+PASS constructorCallCount:::1
+PASS (new A).someGetter:::getterValue
+PASS constructorCallCount:::2
+PASS (new A).someGetter:::getterValue
+PASS setterValue = undefined; (new A).someSetter = 789; setterValue:::789
+PASS (new A).__proto__:::A.prototype
+PASS A.prototype.constructor:::A
+PASS class:::SyntaxError: Unexpected end of script
+PASS class [:::SyntaxError: Unexpected token '['
+PASS class {:::SyntaxError: Class statements must have a name.
+PASS class X {:::SyntaxError: Unexpected end of script
+PASS class X { ( }:::SyntaxError: Unexpected token '('
+PASS class X {}
+PASS class X { constructor() {} constructor() {} }:::SyntaxError: Cannot declare multiple constructors in a single class.
+PASS class X { get constructor() {} }:::SyntaxError: Cannot declare a getter or setter named 'constructor'.
+PASS class X { set constructor() {} }:::SyntaxError: Cannot declare a getter or setter named 'constructor'.
+PASS class X { constructor() {} static constructor() { return staticMethodValue; } }
+PASS class X { constructor() {} static constructor() { return staticMethodValue; } }; X.constructor():::staticMethodValue
+PASS class X { constructor() {} static prototype() {} }:::SyntaxError: Cannot declare a static method named 'prototype'.
+PASS class X { constructor() {} static get prototype() {} }:::SyntaxError: Cannot declare a static method named 'prototype'.
+PASS class X { constructor() {} static set prototype() {} }:::SyntaxError: Cannot declare a static method named 'prototype'.
+PASS class X { constructor() {} prototype() { return instanceMethodValue; } }
+PASS class X { constructor() {} prototype() { return instanceMethodValue; } }; (new X).prototype():::instanceMethodValue
+PASS class X { constructor() {} set foo(a) {} }
+PASS class X { constructor() {} set foo({x, y}) {} }
+PASS class X { constructor() {} set foo() {} }:::SyntaxError: Unexpected token ')'. setter functions must have one parameter.
+PASS class X { constructor() {} set foo(a, b) {} }:::SyntaxError: Unexpected token ','. setter functions must have one parameter.
+PASS class X { constructor() {} get foo() {} }
+PASS class X { constructor() {} get foo(x) {} }:::SyntaxError: Unexpected identifier 'x'. getter functions must have no parameters.
+PASS class X { constructor() {} get foo({x, y}) {} }:::SyntaxError: Unexpected token '{'. getter functions must have no parameters.
+PASS successfullyParsed:::true
 
 TEST COMPLETE
 
index ed9cf7d..275d251 100644 (file)
@@ -3,17 +3,18 @@ Tests for ES6 class syntax default constructor
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS new A instanceof A is true
-PASS A() threw exception TypeError: Cannot call a class constructor.
-PASS A.prototype.constructor instanceof Function is true
-PASS A.prototype.constructor.name is "A"
-PASS new B instanceof A; new B instanceof A is true
-PASS B() threw exception TypeError: Cannot call a class constructor.
-PASS B.prototype.constructor.name is "B"
-PASS A !== B is true
-PASS A.prototype.constructor !== B.prototype.constructor is true
-PASS new (class extends (class { constructor(a, b) { return [a, b]; } }) {})(1, 2) is [1, 2]
-PASS successfullyParsed is true
+PASS new A instanceof A
+PASS A():::TypeError: Cannot call a class constructor
+PASS A.prototype.constructor instanceof Function
+PASS A.prototype.constructor.name:::"A"
+PASS new B instanceof A; new B instanceof A
+PASS B():::TypeError: Cannot call a class constructor
+PASS B.prototype.constructor.name:::"B"
+PASS A !== B
+PASS A.prototype.constructor !== B.prototype.constructor
+PASS Passed assert
+PASS Passed assert
+PASS successfullyParsed
 
 TEST COMPLETE
 
index ce1828c..690ca39 100644 (file)
@@ -3,69 +3,69 @@ Tests for ES6 class syntax "extends"
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS (new Base) instanceof Base is true
-PASS Object.getPrototypeOf(new Base) is Base.prototype
-PASS (new Derived) instanceof Derived is true
-PASS Object.getPrototypeOf(new Derived) is Derived.prototype
-PASS Object.getPrototypeOf(Derived.prototype) is Base.prototype
-PASS (new Derived).baseMethod() is "base"
-PASS (new Derived).overridenMethod() is "derived"
-PASS Derived.staticBaseMethod() is "base"
-PASS Derived.staticOverridenMethod() is "derived"
-PASS x = class extends threw exception SyntaxError: Unexpected end of script.
-PASS x = class extends threw exception SyntaxError: Unexpected end of script.
-PASS x = class extends Base { threw exception SyntaxError: Unexpected end of script.
-PASS x = class extends Base { } did not throw exception.
-PASS x = class extends Base { constructor() { } } did not throw exception.
-PASS x.__proto__ is Base
-PASS Object.getPrototypeOf(x) is Base
-PASS x.prototype.__proto__ is Base.prototype
-PASS Object.getPrototypeOf(x.prototype) is Base.prototype
-PASS x = class extends null { constructor() { } }; x.__proto__ is Function.prototype
-PASS x.__proto__ is Function.prototype
-PASS x = class extends 3 { constructor() { } }; x.__proto__ threw exception TypeError: The superclass is not an object..
-PASS x = class extends "abc" { constructor() { } }; x.__proto__ threw exception TypeError: The superclass is not an object..
-PASS baseWithBadPrototype = function () {}; baseWithBadPrototype.prototype = 3; new baseWithBadPrototype did not throw exception.
-PASS x = class extends baseWithBadPrototype { constructor() { } } threw exception TypeError: The superclass's prototype is not an object..
-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 Object.getPrototypeOf((class { constructor () { } }).prototype) is Object.prototype
-PASS Object.getPrototypeOf((class extends null { constructor () { super(); } }).prototype) is null
-PASS new (class extends undefined { constructor () { this } }) threw exception TypeError: The superclass is not an object..
-PASS x = undefined; new (class extends x { constructor () { super(); } }) threw exception TypeError: The superclass is not an object..
-PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
-PASS new (class extends null { constructor () { this; } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends null { constructor () { super(); } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
-PASS x = {}; new (class extends null { constructor () { return x } }) is x
-PASS y = 12; new (class extends null { constructor () { return y; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x is true
-PASS x = null; Object.getPrototypeOf((class extends x { }).prototype) is null
-PASS Object.prototype.isPrototypeOf(class { }) is true
-PASS Function.prototype.isPrototypeOf(class { }) is true
-PASS successfullyParsed is true
+PASS (new Base) instanceof Base
+PASS Object.getPrototypeOf(new Base):::Base.prototype
+PASS (new Derived) instanceof Derived
+PASS Object.getPrototypeOf(new Derived):::Derived.prototype
+PASS Object.getPrototypeOf(Derived.prototype):::Base.prototype
+PASS (new Derived).baseMethod():::"base"
+PASS (new Derived).overridenMethod():::"derived"
+PASS Derived.staticBaseMethod():::"base"
+PASS Derived.staticOverridenMethod():::"derived"
+PASS x = class extends:::SyntaxError: Unexpected end of script
+PASS x = class extends:::SyntaxError: Unexpected end of script
+PASS x = class extends Base {:::SyntaxError: Unexpected end of script
+PASS x = class extends Base { }
+PASS x = class extends Base { constructor() { } }
+PASS x.__proto__:::Base
+PASS Object.getPrototypeOf(x):::Base
+PASS x.prototype.__proto__:::Base.prototype
+PASS Object.getPrototypeOf(x.prototype):::Base.prototype
+PASS x = class extends null { constructor() { } }; x.__proto__:::Function.prototype
+PASS x.__proto__:::Function.prototype
+PASS x = class extends 3 { constructor() { } }; x.__proto__:::TypeError: The superclass is not an object.
+PASS x = class extends "abc" { constructor() { } }; x.__proto__:::TypeError: The superclass is not an object.
+PASS baseWithBadPrototype = function () {}; baseWithBadPrototype.prototype = 3; new baseWithBadPrototype
+PASS x = class extends baseWithBadPrototype { constructor() { } }:::TypeError: The superclass's prototype is not an object.
+PASS baseWithBadPrototype.prototype = "abc"
+PASS x = class extends baseWithBadPrototype { constructor() { } }:::TypeError: The superclass's prototype is not an object.
+PASS baseWithBadPrototype.prototype = null; x = class extends baseWithBadPrototype { constructor() { } }
+PASS x = 1; c = class extends ++x { constructor() { } };:::SyntaxError: Unexpected token '++'
+PASS x = 1; c = class extends x++ { constructor() { } };:::SyntaxError: Unexpected token '++'. Expected opening '{' at the start of a class body.
+PASS x = 1; c = class extends (++x) { constructor() { } };:::TypeError: The superclass is not an object.
+PASS x = 1; c = class extends (x++) { constructor() { } };:::TypeError: The superclass is not an object.
+PASS x = 1; try { c = class extends (++x) { constructor() { } } } catch (e) { }; x:::2
+PASS x = 1; try { c = class extends (x++) { constructor() { } } } catch (e) { }; x:::2
+PASS namespace = {}; namespace.A = class { }; namespace.B = class extends namespace.A { }
+PASS namespace = {}; namespace.A = class A { }; namespace.B = class B extends namespace.A { }
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace.A { constructor() { } }
+PASS namespace = {}; namespace.A = class A { constructor() { } }; namespace.B = class B extends namespace.A { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A) { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends namespace["A"] { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; function getClassA() { return namespace.A }; namespace.B = class extends getClassA() { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; function getClass(prop) { return namespace[prop] }; namespace.B = class extends getClass("A") { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (false||null||namespace.A) { constructor() { } }
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends false||null||namespace.A { constructor() { } }:::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() { } };
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends (namespace.A, x++) { constructor() { } };:::TypeError: The superclass is not an object.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A { constructor() { } }:::TypeError: The superclass's prototype is not an object.
+PASS namespace = {}; namespace.A = class { constructor() { } }; namespace.B = class extends new namespace.A() { constructor() { } }:::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:::2
+PASS x = 1; namespace = {}; namespace.A = class { constructor() { } }; try { namespace.B = class extends (namespace.A, x++) { constructor() { } } } catch (e) { } x:::2
+PASS Object.getPrototypeOf((class { constructor () { } }).prototype):::Object.prototype
+PASS Object.getPrototypeOf((class extends null { constructor () { super(); } }).prototype):::null
+PASS new (class extends undefined { constructor () { this } }):::TypeError: The superclass is not an object.
+PASS x = undefined; new (class extends x { constructor () { super(); } }):::TypeError: The superclass is not an object.
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x
+PASS new (class extends null { constructor () { this; } }):::ReferenceError: Cannot access uninitialized variable.
+PASS new (class extends null { constructor () { super(); } }):::TypeError: undefined is not an object (evaluating 'super()')
+PASS x = {}; new (class extends null { constructor () { return x } }):::x
+PASS y = 12; new (class extends null { constructor () { return y; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class.
+PASS class x {}; new (class extends null { constructor () { return new x; } }) instanceof x
+PASS x = null; Object.getPrototypeOf((class extends x { }).prototype):::null
+PASS Object.prototype.isPrototypeOf(class { })
+PASS Function.prototype.isPrototypeOf(class { })
+PASS successfullyParsed
 
 TEST COMPLETE
 
index 37828f2..a8cb8f5 100644 (file)
@@ -4,123 +4,123 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 Class statement
-PASS A threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; A threw exception ReferenceError: Can't find variable: A.
-PASS class {} threw exception SyntaxError: Class statements must have a name..
-PASS 'use strict'; class {} threw exception SyntaxError: Class statements must have a name..
-PASS class { constructor() {} } threw exception SyntaxError: Class statements must have a name..
-PASS 'use strict'; class { constructor() {} } threw exception SyntaxError: Class statements must have a name..
-PASS class A { constructor() {} } did not throw exception.
-PASS 'use strict'; class A { constructor() {} } did not throw exception.
-PASS class A { constructor() {} }; A.toString() is 'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; A.toString() is 'function A() {}'
-PASS class A { constructor() {} }; (new A) instanceof A is true
-PASS 'use strict'; class A { constructor() {} }; (new A) instanceof A is true
-PASS class A { constructor() { this.base = A; } }; (new A).base.toString() is 'function A() { this.base = A; }'
-PASS 'use strict'; class A { constructor() { this.base = A; } }; (new A).base.toString() is 'function A() { this.base = A; }'
-PASS class A { constructor() {} }; class B extends A {}; did not throw exception.
-PASS 'use strict'; class A { constructor() {} }; class B extends A {}; did not throw exception.
-PASS class A { constructor() {} }; class B extends A { constructor() {} }; B.toString() is 'function B() {}'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() {} }; B.toString() is 'function B() {}'
-PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof A is true
-PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof A is true
-PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof B is true
-PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof B is true
-PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString() is 'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString() is 'function A() {}'
-PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString() is 'function B() { super(); this.base = A; this.derived = B; }'
-PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString() is 'function B() { super(); this.base = A; this.derived = B; }'
+PASS A:::ReferenceError: Can't find variable: A
+PASS 'use strict'; A:::ReferenceError: Can't find variable: A
+PASS class {}:::SyntaxError: Class statements must have a name.
+PASS 'use strict'; class {}:::SyntaxError: Class statements must have a name.
+PASS class { constructor() {} }:::SyntaxError: Class statements must have a name.
+PASS 'use strict'; class { constructor() {} }:::SyntaxError: Class statements must have a name.
+PASS class A { constructor() {} }
+PASS 'use strict'; class A { constructor() {} }
+PASS class A { constructor() {} }; A.toString():::'function A() {}'
+PASS 'use strict'; class A { constructor() {} }; A.toString():::'function A() {}'
+PASS class A { constructor() {} }; (new A) instanceof A
+PASS 'use strict'; class A { constructor() {} }; (new A) instanceof A
+PASS class A { constructor() { this.base = A; } }; (new A).base.toString():::'function A() { this.base = A; }'
+PASS 'use strict'; class A { constructor() { this.base = A; } }; (new A).base.toString():::'function A() { this.base = A; }'
+PASS class A { constructor() {} }; class B extends A {};
+PASS 'use strict'; class A { constructor() {} }; class B extends A {};
+PASS class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'function B() {}'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() {} }; B.toString():::'function B() {}'
+PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof A
+PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof A
+PASS class A { constructor() {} }; class B extends A {}; (new B) instanceof B
+PASS 'use strict'; class A { constructor() {} }; class B extends A {}; (new B) instanceof B
+PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'function A() {}'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).base.toString():::'function A() {}'
+PASS class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
+PASS 'use strict'; class A { constructor() {} }; class B extends A { constructor() { super(); this.base = A; this.derived = B; } }; (new B).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
 
 Class expression
-PASS A threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; A threw exception ReferenceError: Can't find variable: A.
-PASS (class {}) did not throw exception.
-PASS 'use strict'; (class {}) did not throw exception.
-PASS (class { constructor(){} }) did not throw exception.
-PASS 'use strict'; (class { constructor(){} }) did not throw exception.
-PASS typeof (class {}) is "function"
-PASS 'use strict'; typeof (class {}) is "function"
-PASS (class A {}) did not throw exception.
-PASS 'use strict'; (class A {}) did not throw exception.
-PASS typeof (class A {}) is "function"
-PASS 'use strict'; typeof (class A {}) is "function"
-PASS (class A {}); A threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; (class A {}); A threw exception ReferenceError: Can't find variable: A.
-PASS new (class A {}) did not throw exception.
-PASS 'use strict'; new (class A {}) did not throw exception.
-PASS typeof (new (class A {})) is "object"
-PASS 'use strict'; typeof (new (class A {})) is "object"
-PASS (new (class A { constructor() { this.base = A; } })).base did not throw exception.
-PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base did not throw exception.
-PASS (new (class A { constructor() { this.base = A; } })).base.toString() is "function A() { this.base = A; }"
-PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base.toString() is "function A() { this.base = A; }"
-PASS class A {}; (class B extends A {}) did not throw exception.
-PASS 'use strict'; class A {}; (class B extends A {}) did not throw exception.
-PASS class A {}; (class B extends A {}); B threw exception ReferenceError: Can't find variable: B.
-PASS 'use strict'; class A {}; (class B extends A {}); B threw exception ReferenceError: Can't find variable: B.
-PASS class A {}; new (class B extends A {}) did not throw exception.
-PASS 'use strict'; class A {}; new (class B extends A {}) did not throw exception.
-PASS class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } }) did not throw exception.
-PASS 'use strict'; class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } }) did not throw exception.
-PASS class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A is true
-PASS 'use strict'; class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A is true
-PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString() is 'function A() {}'
-PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString() is 'function A() {}'
-PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString() is 'function B() { super(); this.base = A; this.derived = B; }'
-PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString() is 'function B() { super(); this.base = A; this.derived = B; }'
+PASS A:::ReferenceError: Can't find variable: A
+PASS 'use strict'; A:::ReferenceError: Can't find variable: A
+PASS (class {})
+PASS 'use strict'; (class {})
+PASS (class { constructor(){} })
+PASS 'use strict'; (class { constructor(){} })
+PASS typeof (class {}):::"function"
+PASS 'use strict'; typeof (class {}):::"function"
+PASS (class A {})
+PASS 'use strict'; (class A {})
+PASS typeof (class A {}):::"function"
+PASS 'use strict'; typeof (class A {}):::"function"
+PASS (class A {}); A:::ReferenceError: Can't find variable: A
+PASS 'use strict'; (class A {}); A:::ReferenceError: Can't find variable: A
+PASS new (class A {})
+PASS 'use strict'; new (class A {})
+PASS typeof (new (class A {})):::"object"
+PASS 'use strict'; typeof (new (class A {})):::"object"
+PASS (new (class A { constructor() { this.base = A; } })).base
+PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base
+PASS (new (class A { constructor() { this.base = A; } })).base.toString():::"function A() { this.base = A; }"
+PASS 'use strict'; (new (class A { constructor() { this.base = A; } })).base.toString():::"function A() { this.base = A; }"
+PASS class A {}; (class B extends A {})
+PASS 'use strict'; class A {}; (class B extends A {})
+PASS class A {}; (class B extends A {}); B:::ReferenceError: Can't find variable: B
+PASS 'use strict'; class A {}; (class B extends A {}); B:::ReferenceError: Can't find variable: B
+PASS class A {}; new (class B extends A {})
+PASS 'use strict'; class A {}; new (class B extends A {})
+PASS class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })
+PASS 'use strict'; class A {}; new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })
+PASS class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A
+PASS 'use strict'; class A {}; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })) instanceof A
+PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'function A() {}'
+PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).base.toString():::'function A() {}'
+PASS class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
+PASS 'use strict'; class A { constructor() {} }; (new (class B extends A { constructor() { super(); this.base = A; this.derived = B; } })).derived.toString():::'function B() { super(); this.base = A; this.derived = B; }'
 
 Class expression assignment to variable
-PASS A threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; A threw exception ReferenceError: Can't find variable: A.
-PASS var VarA = class {} did not throw exception.
-PASS 'use strict'; var VarA = class {} did not throw exception.
-PASS var VarA = class { constructor() {} }; VarA.toString() is 'function () {}'
-PASS 'use strict'; var VarA = class { constructor() {} }; VarA.toString() is 'function () {}'
-PASS VarA threw exception ReferenceError: Can't find variable: VarA.
-PASS 'use strict'; VarA threw exception ReferenceError: Can't find variable: VarA.
-PASS var VarA = class A { constructor() {} } did not throw exception.
-PASS 'use strict'; var VarA = class A { constructor() {} } did not throw exception.
-PASS var VarA = class A { constructor() {} }; VarA.toString() is 'function A() {}'
-PASS 'use strict'; var VarA = class A { constructor() {} }; VarA.toString() is 'function A() {}'
-PASS var VarA = class A { constructor() {} }; A.toString() threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; var VarA = class A { constructor() {} }; A.toString() threw exception ReferenceError: Can't find variable: A.
-PASS var VarA = class A { constructor() {} }; (new VarA) instanceof VarA is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; (new VarA) instanceof VarA is true
-PASS var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString() is 'function A() { this.base = A; }'
-PASS 'use strict'; var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString() is 'function A() { this.base = A; }'
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; did not throw exception.
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; did not throw exception.
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B threw exception ReferenceError: Can't find variable: B.
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B threw exception ReferenceError: Can't find variable: B.
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString() is 'function B() {}'
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString() is 'function B() {}'
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA is true
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB is true
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).base === VarA is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).base === VarA is true
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derived === VarB is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derived === VarB is true
-PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derivedVar === VarB is true
-PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derivedVar === VarB is true
+PASS A:::ReferenceError: Can't find variable: A
+PASS 'use strict'; A:::ReferenceError: Can't find variable: A
+PASS var VarA = class {}
+PASS 'use strict'; var VarA = class {}
+PASS var VarA = class { constructor() {} }; VarA.toString():::'function () {}'
+PASS 'use strict'; var VarA = class { constructor() {} }; VarA.toString():::'function () {}'
+PASS VarA:::ReferenceError: Can't find variable: VarA
+PASS 'use strict'; VarA:::ReferenceError: Can't find variable: VarA
+PASS var VarA = class A { constructor() {} }
+PASS 'use strict'; var VarA = class A { constructor() {} }
+PASS var VarA = class A { constructor() {} }; VarA.toString():::'function A() {}'
+PASS 'use strict'; var VarA = class A { constructor() {} }; VarA.toString():::'function A() {}'
+PASS var VarA = class A { constructor() {} }; A.toString():::ReferenceError: Can't find variable: A
+PASS 'use strict'; var VarA = class A { constructor() {} }; A.toString():::ReferenceError: Can't find variable: A
+PASS var VarA = class A { constructor() {} }; (new VarA) instanceof VarA
+PASS 'use strict'; var VarA = class A { constructor() {} }; (new VarA) instanceof VarA
+PASS var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'function A() { this.base = A; }'
+PASS 'use strict'; var VarA = class A { constructor() { this.base = A; } }; (new VarA).base.toString():::'function A() { this.base = A; }'
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} };
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} };
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B:::ReferenceError: Can't find variable: B
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; B:::ReferenceError: Can't find variable: B
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'function B() {}'
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() {} }; VarB.toString():::'function B() {}'
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarA
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { }; (new VarB) instanceof VarB
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).base === VarA
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).base === VarA
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derived === VarB
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derived === VarB
+PASS var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derivedVar === VarB
+PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B extends VarA { constructor() { super(); this.base = VarA; this.derived = B; this.derivedVar = VarB; } }; (new VarB).derivedVar === VarB
 
 Class statement binding in other circumstances
-PASS var result = A; result threw exception ReferenceError: Can't find variable: A.
-PASS 'use strict'; var result = A; result threw exception ReferenceError: Can't find variable: A.
-FAIL var result = A; class A {}; result should throw an exception. Was undefined.
-FAIL 'use strict'; var result = A; class A {}; result should throw an exception. Was undefined.
-PASS class A { constructor() { A = 1; } }; new A threw exception TypeError: Attempted to assign to readonly property..
-PASS 'use strict'; class A { constructor() { A = 1; } }; new A threw exception TypeError: Attempted to assign to readonly property..
-PASS class A { constructor() { } }; A = 1; A is 1
-PASS 'use strict'; class A { constructor() { } }; A = 1; A is 1
-PASS class A {}; var result = A; result did not throw exception.
-PASS 'use strict'; class A {}; var result = A; result did not throw exception.
-PASS eval('var Foo = 10'); Foo is 10
-PASS 'use strict'; eval('var Foo = 10'); Foo threw exception ReferenceError: Can't find variable: Foo.
-PASS eval('class Bar { constructor() {} }'); Bar.toString() is 'function Bar() {}'
-PASS 'use strict'; eval('class Bar { constructor() {} }'); Bar.toString() threw exception ReferenceError: Can't find variable: Bar.
-PASS successfullyParsed is true
+PASS var result = A; result:::ReferenceError: Can't find variable: A
+PASS 'use strict'; var result = A; result:::ReferenceError: Can't find variable: A
+PASS var result = A; class A {}; result:::ReferenceError: Cannot access uninitialized variable.
+PASS 'use strict'; var result = A; class A {}; result:::ReferenceError: Cannot access uninitialized variable.
+PASS class A { constructor() { A = 1; } }; new A:::TypeError: Attempted to assign to readonly property.
+PASS 'use strict'; class A { constructor() { A = 1; } }; new A:::TypeError: Attempted to assign to readonly property.
+PASS class A { constructor() { } }; A = 1; A:::1
+PASS 'use strict'; class A { constructor() { } }; A = 1; A:::1
+PASS class A {}; var result = A; result
+PASS 'use strict'; class A {}; var result = A; result
+PASS eval('var Foo = 10'); Foo:::10
+PASS 'use strict'; eval('var Foo = 10'); Foo:::ReferenceError: Can't find variable: Foo
+PASS eval('class Bar { constructor() {} }; Bar.toString()');:::'function Bar() {}'
+PASS 'use strict'; eval('class Bar { constructor() {} }'); Bar.toString():::ReferenceError: Can't find variable: Bar
+PASS successfullyParsed
 
 TEST COMPLETE
 
index 46efb35..76b5b0b 100644 (file)
@@ -3,45 +3,45 @@ Tests for ES6 class syntax "super"
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS (new Base) instanceof Base is true
-PASS (new Derived) instanceof Derived is true
-PASS (new Derived).callBaseMethod() is baseMethodValue
-PASS x = (new Derived).callBaseMethod; x() is baseMethodValue
-PASS (new Derived).callBaseMethodInGetter is baseMethodValue
-PASS (new Derived).callBaseMethodInSetter = 1; valueInSetter is baseMethodValue
-PASS (new Derived).baseMethodInGetterSetter is (new Base).baseMethod
-PASS (new Derived).baseMethodInGetterSetter = 1; valueInSetter is (new Base).baseMethod
-PASS Derived.staticMethod() is "base3"
-PASS (new SecondDerived).chainMethod() is ["base", "derived", "secondDerived"]
-PASS x = class extends Base { constructor() { super(); } super() {} } threw exception SyntaxError: Unexpected keyword 'super'.
-PASS x = class extends Base { constructor() { super(); } method() { super() } } threw exception SyntaxError: Cannot call super() outside of a class constructor..
-PASS x = class extends Base { constructor() { super(); } method() { super } } threw exception SyntaxError: Cannot reference super..
-PASS x = class extends Base { constructor() { super(); } method() { return new super } } threw exception SyntaxError: Cannot use new with super..
-PASS x = class extends Base { constructor() { super(); } method1() { delete (super.foo) } method2() { delete super["foo"] } } did not throw exception.
-PASS (new x).method1() threw exception ReferenceError: Cannot delete a super property.
-PASS (new x).method2() threw exception ReferenceError: Cannot delete a super property.
-PASS new (class { constructor() { return undefined; } }) instanceof Object is true
-PASS new (class { constructor() { return 1; } }) instanceof Object is true
-PASS new (class extends Base { constructor() { return undefined } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends Base { constructor() { super(); return undefined } }) instanceof Object is true
-PASS x = { }; new (class extends Base { constructor() { return x } }); is x
-PASS x instanceof Base is false
-PASS new (class extends Base { constructor() { } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends Base { constructor() { return 1; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS new (class extends null { constructor() { return undefined } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends null { constructor() { super(); return undefined } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
-PASS x = { }; new (class extends null { constructor() { return x } }); is x
-PASS x instanceof Object is true
-PASS new (class extends null { constructor() { } }) threw exception ReferenceError: Cannot access uninitialized variable..
-PASS new (class extends null { constructor() { return 1; } }) threw exception TypeError: Cannot return a non-object type in the constructor of a derived class..
-PASS new (class extends null { constructor() { super() } }) threw exception TypeError: undefined is not an object (evaluating 'super()').
-PASS new (class { constructor() { super() } }) threw exception SyntaxError: Cannot call super() in a base class constructor..
-PASS function x() { super(); } threw exception SyntaxError: Cannot call super() outside of a class constructor..
-PASS new (class extends Object { constructor() { function x() { super() } } }) threw exception SyntaxError: Cannot call super() outside of a class constructor..
-PASS new (class extends Object { constructor() { function x() { super.method } } }) threw exception SyntaxError: super can only be used in a method of a derived class..
-PASS function x() { super.method(); } threw exception SyntaxError: super can only be used in a method of a derived class..
-PASS function x() { super(); } threw exception SyntaxError: Cannot call super() outside of a class constructor..
-PASS successfullyParsed is true
+PASS (new Base) instanceof Base
+PASS (new Derived) instanceof Derived
+PASS (new Derived).callBaseMethod():::baseMethodValue
+PASS x = (new Derived).callBaseMethod; x():::baseMethodValue
+PASS (new Derived).callBaseMethodInGetter:::baseMethodValue
+PASS (new Derived).callBaseMethodInSetter = 1; valueInSetter:::baseMethodValue
+PASS (new Derived).baseMethodInGetterSetter:::(new Base).baseMethod
+PASS (new Derived).baseMethodInGetterSetter = 1; valueInSetter:::(new Base).baseMethod
+PASS Derived.staticMethod():::"base3"
+PASS (new SecondDerived).chainMethod().toString():::["base", "derived", "secondDerived"].toString()
+PASS x = class extends Base { constructor() { super(); } super() {} }:::SyntaxError: Unexpected keyword 'super'
+PASS x = class extends Base { constructor() { super(); } method() { super() } }:::SyntaxError: Cannot call super() outside of a class constructor.
+PASS x = class extends Base { constructor() { super(); } method() { super } }:::SyntaxError: Cannot reference super.
+PASS x = class extends Base { constructor() { super(); } method() { return new super } }:::SyntaxError: Cannot use new with super.
+PASS x = class extends Base { constructor() { super(); } method1() { delete (super.foo) } method2() { delete super["foo"] } }
+PASS (new x).method1():::ReferenceError: Cannot delete a super property
+PASS (new x).method2():::ReferenceError: Cannot delete a super property
+PASS new (class { constructor() { return undefined; } }) instanceof Object
+PASS new (class { constructor() { return 1; } }) instanceof Object
+PASS new (class extends Base { constructor() { return undefined } }):::ReferenceError: Cannot access uninitialized variable.
+PASS new (class extends Base { constructor() { super(); return undefined } }) instanceof Object
+PASS x = { }; new (class extends Base { constructor() { return x } });:::x
+PASS x instanceof Base
+PASS new (class extends Base { constructor() { } }):::ReferenceError: Cannot access uninitialized variable.
+PASS new (class extends Base { constructor() { return 1; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class.
+PASS new (class extends null { constructor() { return undefined } }):::ReferenceError: Cannot access uninitialized variable.
+PASS new (class extends null { constructor() { super(); return undefined } }):::TypeError: undefined is not an object (evaluating 'super()')
+PASS x = { }; new (class extends null { constructor() { return x } });:::x
+PASS x instanceof Object
+PASS new (class extends null { constructor() { } }):::ReferenceError: Cannot access uninitialized variable.
+PASS new (class extends null { constructor() { return 1; } }):::TypeError: Cannot return a non-object type in the constructor of a derived class.
+PASS new (class extends null { constructor() { super() } }):::TypeError: undefined is not an object (evaluating 'super()')
+PASS new (class { constructor() { super() } }):::SyntaxError: Cannot call super() in a base class constructor.
+PASS function x() { super(); }:::SyntaxError: Cannot call super() outside of a class constructor.
+PASS new (class extends Object { constructor() { function x() { super() } } }):::SyntaxError: Cannot call super() outside of a class constructor.
+PASS new (class extends Object { constructor() { function x() { super.method } } }):::SyntaxError: super can only be used in a method of a derived class.
+PASS function x() { super.method(); }:::SyntaxError: super can only be used in a method of a derived class.
+PASS function x() { super(); }:::SyntaxError: Cannot call super() outside of a class constructor.
+PASS successfullyParsed
 
 TEST COMPLETE
 
index face499..4d5fddf 100644 (file)
@@ -7,11 +7,11 @@ PASS Intl.Collator is an instance of Function
 PASS Intl.Collator() is an instance of Intl.Collator
 PASS Intl.Collator.call({}) is an instance of Intl.Collator
 PASS new Intl.Collator() is an instance of Intl.Collator
-PASS new DerivedCollator is an instance of DerivedCollator
-PASS new DerivedCollator is an instance of Intl.Collator
-PASS new DerivedCollator().compare('a', 'b') is -1
-PASS Object.getPrototypeOf(new DerivedCollator) is DerivedCollator.prototype
-PASS Object.getPrototypeOf(Object.getPrototypeOf(new DerivedCollator)) is Intl.Collator.prototype
+PASS class DerivedCollator extends Intl.Collator {};(new DerivedCollator) instanceof DerivedCollator is true
+PASS class DerivedCollator extends Intl.Collator {};(new DerivedCollator) instanceof Intl.Collator is true
+PASS class DerivedCollator extends Intl.Collator {};new DerivedCollator().compare('a', 'b') === -1 is true
+PASS class DerivedCollator extends Intl.Collator {};Object.getPrototypeOf(new DerivedCollator) === DerivedCollator.prototype is true
+PASS class DerivedCollator extends Intl.Collator {};Object.getPrototypeOf(Object.getPrototypeOf(new DerivedCollator)) === Intl.Collator.prototype is true
 PASS Intl.Collator.length is 0
 PASS Object.getOwnPropertyDescriptor(Intl.Collator, 'prototype').writable is false
 PASS Object.getOwnPropertyDescriptor(Intl.Collator, 'prototype').enumerable is false
index 29776f5..60173fe 100644 (file)
@@ -7,11 +7,11 @@ PASS Intl.DateTimeFormat is an instance of Function
 PASS Intl.DateTimeFormat() is an instance of Intl.DateTimeFormat
 PASS Intl.DateTimeFormat.call({}) is an instance of Intl.DateTimeFormat
 PASS new Intl.DateTimeFormat() is an instance of Intl.DateTimeFormat
-PASS new DerivedDateTimeFormat is an instance of DerivedDateTimeFormat
-PASS new DerivedDateTimeFormat is an instance of Intl.DateTimeFormat
-PASS new DerivedDateTimeFormat().format(0).length > 0 is true
-PASS Object.getPrototypeOf(new DerivedDateTimeFormat) is DerivedDateTimeFormat.prototype
-PASS Object.getPrototypeOf(Object.getPrototypeOf(new DerivedDateTimeFormat)) is Intl.DateTimeFormat.prototype
+PASS class DerivedDateTimeFormat extends Intl.DateTimeFormat {};(new DerivedDateTimeFormat) instanceof DerivedDateTimeFormat is true
+PASS class DerivedDateTimeFormat extends Intl.DateTimeFormat {};(new DerivedDateTimeFormat) instanceof Intl.DateTimeFormat is true
+PASS class DerivedDateTimeFormat extends Intl.DateTimeFormat {};new DerivedDateTimeFormat().format(0).length > 0 is true
+PASS class DerivedDateTimeFormat extends Intl.DateTimeFormat {};Object.getPrototypeOf(new DerivedDateTimeFormat) === DerivedDateTimeFormat.prototype is true
+PASS class DerivedDateTimeFormat extends Intl.DateTimeFormat {};Object.getPrototypeOf(Object.getPrototypeOf(new DerivedDateTimeFormat)) === Intl.DateTimeFormat.prototype is true
 PASS Intl.DateTimeFormat.length is 0
 PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat, 'prototype').writable is false
 PASS Object.getOwnPropertyDescriptor(Intl.DateTimeFormat, 'prototype').enumerable is false
index 46de012..521851e 100644 (file)
@@ -7,11 +7,11 @@ PASS Intl.NumberFormat is an instance of Function
 PASS Intl.NumberFormat() is an instance of Intl.NumberFormat
 PASS Intl.NumberFormat.call({}) is an instance of Intl.NumberFormat
 PASS new Intl.NumberFormat() is an instance of Intl.NumberFormat
-PASS new DerivedNumberFormat is an instance of DerivedNumberFormat
-PASS new DerivedNumberFormat is an instance of Intl.NumberFormat
-PASS new DerivedNumberFormat().format(1) is '1'
-PASS Object.getPrototypeOf(new DerivedNumberFormat) is DerivedNumberFormat.prototype
-PASS Object.getPrototypeOf(Object.getPrototypeOf(new DerivedNumberFormat)) is Intl.NumberFormat.prototype
+PASS class DerivedNumberFormat extends Intl.NumberFormat {};(new DerivedNumberFormat) instanceof DerivedNumberFormat is true
+PASS class DerivedNumberFormat extends Intl.NumberFormat {};(new DerivedNumberFormat) instanceof Intl.NumberFormat is true
+PASS class DerivedNumberFormat extends Intl.NumberFormat {};new DerivedNumberFormat().format(1) === '1' is true
+PASS class DerivedNumberFormat extends Intl.NumberFormat {};Object.getPrototypeOf(new DerivedNumberFormat) === DerivedNumberFormat.prototype is true
+PASS class DerivedNumberFormat extends Intl.NumberFormat {};Object.getPrototypeOf(Object.getPrototypeOf(new DerivedNumberFormat)) === Intl.NumberFormat.prototype is true
 PASS Intl.NumberFormat.length is 0
 PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat, 'prototype').writable is false
 PASS Object.getOwnPropertyDescriptor(Intl.NumberFormat, 'prototype').enumerable is false
index f393027..699008c 100644 (file)
@@ -1,5 +1,47 @@
 description('Tests for ES6 class constructor return values');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === message)
+            testPassed(s);
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
+function shouldBeTrue(s) {
+    if (eval(s) === true)
+        testPassed(s);
+    else 
+        testFailed(s);
+}
+
+function shouldBeFalse(s) {
+    if (eval(s) === false)
+        testPassed(s);
+    else 
+        testFailed(s);
+}
+
 // ES6
 // - 9.2.2 [[Construct]] (ECMAScript Function Objects)
 // - 12.3.5.1 Runtime Semantics: Evaluation (The super Keyword)
index 94a3121..87c4acb 100644 (file)
@@ -3,6 +3,34 @@ description('Tests for calling the constructors of ES6 classes');
 class A { constructor() {} };
 class B extends A { constructor() { super() } };
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (e.toString() === eval(message))
+            testPassed(s + ":::" + message);
+        else
+            testFailed(e.toString() + ":::" + message);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
 shouldNotThrow('new A');
 shouldThrow('A()', '"TypeError: Cannot call a class constructor"');
 shouldNotThrow('new B');
index 7d3b442..8fc1c96 100644 (file)
@@ -1,6 +1,41 @@
 
 description('Tests for ES6 class syntax declarations');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s + ":::" + e.toString() + ":::" + message);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
+function shouldBe(a, b) {
+    if (eval(a) === eval(b))
+        testPassed(a + ":::" + b);
+    else
+        testFailed(a + ":::" + b);
+}
+
 var constructorCallCount = 0;
 var staticMethodValue = [1];
 var instanceMethodValue = [2];
index 457faa4..eec4f33 100644 (file)
@@ -1,6 +1,44 @@
 
 description('Tests for ES6 class syntax default constructor');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldBe(a, b) {
+    var r1 = eval(a);
+    var r2 = eval(b)
+    if (r1 === r2)
+        testPassed(a + ":::" + b);
+    else
+        testFailed(r1 + ":::" + r2);
+}
+
+function shouldBeTrue(s) {
+    if (eval(s) === true)
+        testPassed(s);
+    else
+        testFailed(s);
+}
+
+function assert(b) {
+    if (!b)
+        testFailed("Failed assert");
+    else
+        testPassed("Passed assert");
+}
+
 class A { };
 class B extends A { };
 
@@ -13,6 +51,9 @@ shouldThrow('B()', '"TypeError: Cannot call a class constructor"');
 shouldBe('B.prototype.constructor.name', '"B"');
 shouldBeTrue('A !== B');
 shouldBeTrue('A.prototype.constructor !== B.prototype.constructor');
-shouldBe('new (class extends (class { constructor(a, b) { return [a, b]; } }) {})(1, 2)', '[1, 2]');
+var result = new (class extends (class { constructor(a, b) { return [a, b]; } }) {})(1, 2);
+assert(result[0] === 1);
+assert(result[1] === 2);
+
 
 var successfullyParsed = true;
index 6ff0c3d..fb10830 100644 (file)
@@ -1,6 +1,48 @@
 
 description('Tests for ES6 class syntax "extends"');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
+function shouldBe(a, b) {
+    if (eval(a) === eval(b))
+        testPassed(a + ":::" + b);
+    else
+        testFailed(a + ":::" + b);
+}
+
+function shouldBeTrue(s) {
+    if (eval(s) === true)
+        testPassed(s);
+    else
+        testFailed(s);
+}
+
 class Base {
     constructor() { }
     baseMethod() { return 'base'; }
index 561a617..705f56d 100644 (file)
@@ -1,5 +1,47 @@
 description('Tests for ES6 class name semantics in class statements and expressions');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
+function shouldBe(a, b) {
+    if (eval(a) === eval(b))
+        testPassed(a + ":::" + b);
+    else
+        testFailed(a + ":::" + b);
+}
+
+function shouldBeTrue(s) {
+    if (eval(s) === true)
+        testPassed(s);
+    else 
+        testFailed(s);
+}
+
 function runTestShouldBe(statement, result) {
     shouldBe(statement, result);
     shouldBe("'use strict'; " + statement, result);
@@ -86,5 +128,5 @@ runTestShouldBe("class A { constructor() { } }; A = 1; A", "1");
 runTestShouldNotThrow("class A {}; var result = A; result");
 shouldBe("eval('var Foo = 10'); Foo", "10");
 shouldThrow("'use strict'; eval('var Foo = 10'); Foo");
-shouldBe("eval('class Bar { constructor() {} }'); Bar.toString()", "'function Bar() {}'");
+shouldBe("eval('class Bar { constructor() {} }; Bar.toString()');", "'function Bar() {}'");
 shouldThrow("'use strict'; eval('class Bar { constructor() {} }'); Bar.toString()");
index e7114e1..2256c50 100644 (file)
@@ -1,6 +1,55 @@
 
 description('Tests for ES6 class syntax "super"');
 
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldNotThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+    }
+    if (threw)
+        testFailed(s);
+    else
+        testPassed(s);
+}
+
+function shouldBe(a, b) {
+    if (eval(a) === eval(b))
+        testPassed(a + ":::" + b);
+    else
+        testFailed(a + ":::" + b);
+}
+
+function shouldBeTrue(s) {
+    if (eval(s) === true)
+        testPassed(s);
+    else 
+        testFailed(s);
+}
+
+function shouldBeFalse(s) {
+    if (eval(s) === false)
+        testPassed(s);
+    else 
+        testFailed(s);
+}
+
 var baseMethodValue = {};
 var valueInSetter = null;
 
@@ -36,7 +85,7 @@ shouldBe('(new Derived).callBaseMethodInSetter = 1; valueInSetter', 'baseMethodV
 shouldBe('(new Derived).baseMethodInGetterSetter', '(new Base).baseMethod');
 shouldBe('(new Derived).baseMethodInGetterSetter = 1; valueInSetter', '(new Base).baseMethod');
 shouldBe('Derived.staticMethod()', '"base3"');
-shouldBe('(new SecondDerived).chainMethod()', '["base", "derived", "secondDerived"]');
+shouldBe('(new SecondDerived).chainMethod().toString()', '["base", "derived", "secondDerived"].toString()');
 shouldThrow('x = class extends Base { constructor() { super(); } super() {} }', '"SyntaxError: Unexpected keyword \'super\'"');
 shouldThrow('x = class extends Base { constructor() { super(); } method() { super() } }',
     '"SyntaxError: Cannot call super() outside of a class constructor."');
index bc63bd6..5de190e 100644 (file)
@@ -11,12 +11,12 @@ shouldBeType("Intl.Collator.call({})", "Intl.Collator");
 shouldBeType("new Intl.Collator()", "Intl.Collator");
 
 // Subclassable
-class DerivedCollator extends Intl.Collator {}
-shouldBeType("new DerivedCollator", "DerivedCollator");
-shouldBeType("new DerivedCollator", "Intl.Collator");
-shouldBe("new DerivedCollator().compare('a', 'b')", "-1");
-shouldBe("Object.getPrototypeOf(new DerivedCollator)", "DerivedCollator.prototype");
-shouldBe("Object.getPrototypeOf(Object.getPrototypeOf(new DerivedCollator))", "Intl.Collator.prototype");
+var classPrefix = "class DerivedCollator extends Intl.Collator {};";
+shouldBeTrue(classPrefix + "(new DerivedCollator) instanceof DerivedCollator");
+shouldBeTrue(classPrefix + "(new DerivedCollator) instanceof Intl.Collator");
+shouldBeTrue(classPrefix + "new DerivedCollator().compare('a', 'b') === -1");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(new DerivedCollator) === DerivedCollator.prototype");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(Object.getPrototypeOf(new DerivedCollator)) === Intl.Collator.prototype");
 
 // 10.2 Properties of the Intl.Collator Constructor
 
index bf8a9cd..bc7c9a7 100644 (file)
@@ -11,12 +11,12 @@ shouldBeType("Intl.DateTimeFormat.call({})", "Intl.DateTimeFormat");
 shouldBeType("new Intl.DateTimeFormat()", "Intl.DateTimeFormat");
 
 // Subclassable
-class DerivedDateTimeFormat extends Intl.DateTimeFormat {}
-shouldBeType("new DerivedDateTimeFormat", "DerivedDateTimeFormat");
-shouldBeType("new DerivedDateTimeFormat", "Intl.DateTimeFormat");
-shouldBeTrue("new DerivedDateTimeFormat().format(0).length > 0");
-shouldBe("Object.getPrototypeOf(new DerivedDateTimeFormat)", "DerivedDateTimeFormat.prototype");
-shouldBe("Object.getPrototypeOf(Object.getPrototypeOf(new DerivedDateTimeFormat))", "Intl.DateTimeFormat.prototype");
+var classPrefix = "class DerivedDateTimeFormat extends Intl.DateTimeFormat {};";
+shouldBeTrue(classPrefix + "(new DerivedDateTimeFormat) instanceof DerivedDateTimeFormat");
+shouldBeTrue(classPrefix + "(new DerivedDateTimeFormat) instanceof Intl.DateTimeFormat");
+shouldBeTrue(classPrefix + "new DerivedDateTimeFormat().format(0).length > 0");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(new DerivedDateTimeFormat) === DerivedDateTimeFormat.prototype");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(Object.getPrototypeOf(new DerivedDateTimeFormat)) === Intl.DateTimeFormat.prototype");
 
 // 12.2 Properties of the Intl.DateTimeFormat Constructor
 
index f573b92..065d921 100644 (file)
@@ -11,12 +11,12 @@ shouldBeType("Intl.NumberFormat.call({})", "Intl.NumberFormat");
 shouldBeType("new Intl.NumberFormat()", "Intl.NumberFormat");
 
 // Subclassable
-class DerivedNumberFormat extends Intl.NumberFormat {}
-shouldBeType("new DerivedNumberFormat", "DerivedNumberFormat");
-shouldBeType("new DerivedNumberFormat", "Intl.NumberFormat");
-shouldBe("new DerivedNumberFormat().format(1)", "'1'");
-shouldBe("Object.getPrototypeOf(new DerivedNumberFormat)", "DerivedNumberFormat.prototype");
-shouldBe("Object.getPrototypeOf(Object.getPrototypeOf(new DerivedNumberFormat))", "Intl.NumberFormat.prototype");
+var classPrefix = "class DerivedNumberFormat extends Intl.NumberFormat {};";
+shouldBeTrue(classPrefix + "(new DerivedNumberFormat) instanceof DerivedNumberFormat");
+shouldBeTrue(classPrefix + "(new DerivedNumberFormat) instanceof Intl.NumberFormat");
+shouldBeTrue(classPrefix + "new DerivedNumberFormat().format(1) === '1'");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(new DerivedNumberFormat) === DerivedNumberFormat.prototype");
+shouldBeTrue(classPrefix + "Object.getPrototypeOf(Object.getPrototypeOf(new DerivedNumberFormat)) === Intl.NumberFormat.prototype");
 
 // 11.2 Properties of the Intl.NumberFormat Constructor
 
index 7fbb75b..c5dca4d 100644 (file)
@@ -1,3 +1,34 @@
+2015-07-31  Saam barati  <saambarati1@gmail.com>
+
+        ES6 class syntax should use block scoping
+        https://bugs.webkit.org/show_bug.cgi?id=142567
+
+        Reviewed by Geoffrey Garen.
+
+        We treat class declarations like we do "let" declarations.
+        The class name is under TDZ until the class declaration
+        statement is evaluated. Class declarations also follow
+        the same rules as "let": No duplicate definitions inside
+        a lexical environment.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createClassDeclStatement):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseClassDeclaration):
+        * tests/stress/class-syntax-block-scoping.js: Added.
+        (assert):
+        (truth):
+        (.):
+        * tests/stress/class-syntax-definition-semantics.js: Added.
+        (shouldBeSyntaxError):
+        (shouldNotBeSyntaxError):
+        (truth):
+        * tests/stress/class-syntax-tdz.js:
+        (assert):
+        (shouldThrowTDZ):
+        (truth):
+        (.):
+
 2015-07-31  Sukolsak Sakshuwong  <sukolsak@gmail.com>
 
         Implement WebAssembly module parser
index 36216d4..d6fa847 100644 (file)
@@ -442,7 +442,6 @@ public:
     StatementNode* createClassDeclStatement(const JSTokenLocation& location, ClassExprNode* classExpression,
         const JSTextPosition& classStart, const JSTextPosition& classEnd, unsigned startLine, unsigned endLine)
     {
-        // FIXME: Use "let" declaration.
         ExpressionNode* assign = createAssignResolve(location, classExpression->name(), classExpression, classStart, classStart + 1, classEnd, AssignmentContext::DeclarationStatement);
         ClassDeclNode* decl = new (m_parserArena) ClassDeclNode(location, assign);
         decl->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
index 289f38e..1ed1746 100644 (file)
@@ -1821,8 +1821,10 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclarat
     ParserClassInfo<TreeBuilder> info;
     TreeClassExpression classExpr = parseClass(context, FunctionNeedsName, info);
     failIfFalse(classExpr, "Failed to parse class");
-    // FIXME: This should be like `let`, not `var`.
-    declareVariable(info.className);
+
+    DeclarationResultMask declarationResult = declareVariable(info.className, DeclarationType::LetDeclaration);
+    if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
+        internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'");
 
     JSTextPosition classEnd = lastTokenEndPosition();
     unsigned classEndLine = tokenLine();
diff --git a/Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js b/Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js
new file mode 100644 (file)
index 0000000..f3526f9
--- /dev/null
@@ -0,0 +1,49 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Assertion failure");
+}
+noInline(assert);
+
+function truth() { return true; }
+noInline(truth);
+
+const NUM_LOOPS = 1000;
+
+;(function() {
+    function foo() {
+        let first;
+        let second;
+        class A {};
+        first = A;
+        if (truth()) {
+            class A {};
+            second = A;
+        }
+        assert(first !== second);
+    }
+    function baz() {
+        class A { static hello() { return 10; } };
+        assert(A.hello() === 10);
+        if (truth()) {
+            class A { static hello() { return 20; } };
+            assert(A.hello() === 20);
+        }
+        assert(A.hello() === 10);
+    }
+    function bar() {
+        class A { static hello() { return 10; } };
+        let capA = function() { return A; }
+        assert(A.hello() === 10);
+        if (truth()) {
+            class A { static hello() { return 20; } };
+            let capA = function() { return A; }
+            assert(A.hello() === 20);
+        }
+        assert(A.hello() === 10);
+    }
+    for (let i = 0; i < NUM_LOOPS; i++) {
+        foo();
+        bar();
+        baz();
+    }
+})();
diff --git a/Source/JavaScriptCore/tests/stress/class-syntax-definition-semantics.js b/Source/JavaScriptCore/tests/stress/class-syntax-definition-semantics.js
new file mode 100644 (file)
index 0000000..c02742c
--- /dev/null
@@ -0,0 +1,37 @@
+
+function shouldBeSyntaxError(s) {
+    let isSyntaxError = false;
+    try {
+        eval(s);
+    } catch(e) {
+        if (e instanceof SyntaxError)
+            isSyntaxError = true;
+        print(e);
+    }
+    if (!isSyntaxError)
+        throw new Error("expected a syntax error");
+}
+noInline(shouldBeSyntaxError);
+
+function shouldNotBeSyntaxError(s) {
+    let isSyntaxError = false;
+    try {
+        eval(s);
+    } catch(e) {
+        if (e instanceof SyntaxError)
+            isSyntaxError = true;
+    }
+    if (isSyntaxError)
+        throw new Error("did not expect a syntax error");
+}
+
+function truth() { return true; }
+noInline(truth);
+
+shouldBeSyntaxError("class A { }; class A { };");
+shouldBeSyntaxError("function foo() { class A { }; class A { }; }");
+shouldBeSyntaxError("function foo() { if (truth()) { class A { }; class A { }; } }");
+shouldBeSyntaxError("switch(10) { case 10: class A { }; break; case 20: class A { } }");
+shouldBeSyntaxError("if (truth()) class A { }");
+shouldNotBeSyntaxError("switch(10) { case 10: { class A { }; break; } case 20: class A { } }");
+shouldNotBeSyntaxError("class A { } if (truth()) { class A { } }");
index 1444910..c14c667 100644 (file)
@@ -12,7 +12,28 @@ class B extends A {
 
 noInline(B);
 
-for (var i = 0; i < 10000; ++i) {
+function assert(b) {
+    if (!b)
+        throw new Error("Assertion failure");
+}
+noInline(assert);
+
+function shouldThrowTDZ(func) {
+    var hasThrown = false;
+    try {
+        func();
+    } catch(e) {
+        if (e.name.indexOf("ReferenceError") !== -1)
+            hasThrown = true;
+    }
+    assert(hasThrown);
+}
+noInline(shouldThrowTDZ);
+
+function truth() { return true; }
+noInline(truth);
+
+for (var i = 0; i < 100; ++i) {
     var exception;
     try {
         new B();
@@ -24,3 +45,36 @@ for (var i = 0; i < 10000; ++i) {
     if (!exception)
         throw "Exception not thrown for an unitialized this at iteration " + i;
 }
+
+
+
+;(function() {
+    function foo() {
+        return A;
+        class A { }
+    }
+    function bar() {
+        shouldThrowTDZ(function() { return A; });
+        class A { }
+    }
+    function baz() {
+        class C { static m() { return "m"; } }
+        if (truth()) {
+            class B extends C { }
+            assert(B.m() === "m");
+        }
+        class B extends A { }
+        class A { }
+    }
+    function taz() {
+        function f(x) { return x; }
+        class C extends f(C) { }
+    }
+
+    for (var i = 0; i < 100; i++) {
+        shouldThrowTDZ(foo);
+        bar();
+        shouldThrowTDZ(baz);
+        shouldThrowTDZ(taz);
+    }
+})();