Index: test/webkit/class-constructor-return.js |
diff --git a/test/webkit/class-constructor-return.js b/test/webkit/class-constructor-return.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6eb72ad4036125e8ef438cd8b3da4062a3e6175d |
--- /dev/null |
+++ b/test/webkit/class-constructor-return.js |
@@ -0,0 +1,217 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
+// |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions |
+// are met: |
+// 1. Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// 2. Redistributions in binary form must reproduce the above copyright |
+// notice, this list of conditions and the following disclaimer in the |
+// documentation and/or other materials provided with the distribution. |
+// |
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY |
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+// Flags: --harmony-sloppy |
+ |
+description('Tests for ES6 class constructor return values'); |
+ |
+// ES6 |
+// - 9.2.2 [[Construct]] (ECMAScript Function Objects) |
+// - 12.3.5.1 Runtime Semantics: Evaluation (The super Keyword) |
+// - 14.5.14 Runtime Semantics: ClassDefinitionEvaluation (Default Constructor) |
+ |
+var globalVariable = {name:"globalVariable"}; |
+var globalSymbol = Symbol(); |
+ |
+debug('Base class'); |
+class BaseNoReturn { constructor() { } }; |
+class BaseReturnImplicit { constructor() { return; } }; |
+class BaseReturnUndefined { constructor() { return undefined; } }; |
+class BaseReturnThis { constructor() { return this; } }; |
+class BaseReturnObject { constructor() { return {a:1}; } }; |
+class BaseReturnObject2 { constructor() { return globalVariable; } }; |
+class BaseReturnString { constructor() { return "test"; } }; |
+class BaseReturnNumber { constructor() { return 1; } }; |
+class BaseReturnNull { constructor() { return null; } }; |
+class BaseReturnSymbol { constructor() { return Symbol(); } }; |
+class BaseThrow { constructor() { throw "Thrown Exception String"; } }; |
+ |
+// Base - Implicit => return this. |
+shouldBeTrue('(new BaseNoReturn) instanceof BaseNoReturn'); |
+ |
+// Base - Early return => return this. |
+shouldBeTrue('(new BaseReturnImplicit) instanceof BaseReturnImplicit'); |
+shouldBeTrue('(new BaseReturnImplicit) !== undefined'); |
+shouldBeTrue('(new BaseReturnUndefined) instanceof BaseReturnUndefined'); |
+shouldBeTrue('(new BaseReturnUndefined) !== undefined'); |
+ |
+// Base - return this => return this. |
+shouldBeTrue('(new BaseReturnThis) instanceof BaseReturnThis'); |
+ |
+// Base - return Object => return object, not instance. |
+shouldBeFalse('(new BaseReturnObject) instanceof BaseReturnObject'); |
+shouldBeTrue('typeof (new BaseReturnObject) === "object"'); |
+shouldBeFalse('(new BaseReturnObject2) instanceof BaseReturnObject'); |
+shouldBeTrue('(new BaseReturnObject2) === globalVariable'); |
+ |
+// Base - return non-Object => return this. |
+shouldBeTrue('(new BaseReturnString) instanceof BaseReturnString'); |
+shouldBeTrue('typeof (new BaseReturnString) !== "string"'); |
+shouldBeTrue('(new BaseReturnNumber) instanceof BaseReturnNumber'); |
+shouldBeTrue('typeof (new BaseReturnNumber) !== "number"'); |
+shouldBeTrue('(new BaseReturnNull) instanceof BaseReturnNull'); |
+shouldBeTrue('(new BaseReturnNull) !== null'); |
+shouldBeTrue('(new BaseReturnSymbol) instanceof BaseReturnSymbol'); |
+shouldBeTrue('(new BaseReturnSymbol) !== globalSymbol'); |
+ |
+// Base - throw => throw |
+shouldThrow('(new BaseThrow)'); |
+ |
+// Same behavior for Functions. |
+debug(''); debug('Function constructor (non-class)'); |
+function FunctionNoReturn() { }; |
+function FunctionReturnImplicit() { return; }; |
+function FunctionReturnUndefined() { return undefined; }; |
+function FunctionReturnThis() { return this; }; |
+function FunctionReturnObject() { return {a:1}; }; |
+function FunctionReturnObject2() { return globalVariable; }; |
+function FunctionReturnString() { return "test"; }; |
+function FunctionReturnNumber() { return 1; }; |
+function FunctionReturnNull() { return null; }; |
+function FunctionReturnSymbol() { return Symbol(); }; |
+function FunctionThrow() { throw "Thrown Exception String"; }; |
+ |
+shouldBeTrue('(new FunctionNoReturn) instanceof FunctionNoReturn'); |
+shouldBeTrue('(new FunctionReturnImplicit) instanceof FunctionReturnImplicit'); |
+shouldBeTrue('(new FunctionReturnImplicit) !== undefined'); |
+shouldBeTrue('(new FunctionReturnUndefined) instanceof FunctionReturnUndefined'); |
+shouldBeTrue('(new FunctionReturnUndefined) !== undefined'); |
+shouldBeTrue('(new FunctionReturnThis) instanceof FunctionReturnThis'); |
+shouldBeFalse('(new FunctionReturnObject) instanceof FunctionReturnObject'); |
+shouldBeTrue('typeof (new FunctionReturnObject) === "object"'); |
+shouldBeFalse('(new FunctionReturnObject2) instanceof FunctionReturnObject'); |
+shouldBeTrue('(new FunctionReturnObject2) === globalVariable'); |
+shouldBeTrue('(new FunctionReturnString) instanceof FunctionReturnString'); |
+shouldBeTrue('typeof (new FunctionReturnString) !== "string"'); |
+shouldBeTrue('(new FunctionReturnNumber) instanceof FunctionReturnNumber'); |
+shouldBeTrue('typeof (new FunctionReturnNumber) !== "number"'); |
+shouldBeTrue('(new FunctionReturnNull) instanceof FunctionReturnNull'); |
+shouldBeTrue('(new FunctionReturnNull) !== null'); |
+shouldBeTrue('(new FunctionReturnSymbol) instanceof FunctionReturnSymbol'); |
+shouldBeTrue('(new FunctionReturnSymbol) !== globalSymbol'); |
+shouldThrow('(new FunctionThrow)'); |
+ |
+ |
+debug(''); debug('Derived class calling super()'); |
+class DerivedNoReturn extends BaseNoReturn { constructor() { super(); } }; |
+class DerivedReturnImplicit extends BaseNoReturn { constructor() { super(); return; } }; |
+class DerivedReturnUndefined extends BaseNoReturn { constructor() { super(); return undefined; } }; |
+class DerivedReturnThis extends BaseNoReturn { constructor() { super(); return this; } }; |
+class DerivedReturnObject extends BaseNoReturn { constructor() { super(); return {a:1}; } }; |
+class DerivedReturnObject2 extends BaseNoReturn { constructor() { super(); return globalVariable; } }; |
+class DerivedReturnString extends BaseNoReturn { constructor() { super(); return "test"; } }; |
+class DerivedReturnNumber extends BaseNoReturn { constructor() { super(); return 1; } }; |
+class DerivedReturnNull extends BaseNoReturn { constructor() { super(); return null; } }; |
+class DerivedReturnSymbol extends BaseNoReturn { constructor() { super(); return globalSymbol; } }; |
+class DerivedThrow extends BaseNoReturn { constructor() { super(); throw "Thrown Exception String"; } }; |
+ |
+// Derived - Implicit => return this. |
+shouldBeTrue('(new DerivedNoReturn) instanceof DerivedNoReturn'); |
+ |
+// Derived - Early return => return this. |
+shouldBeTrue('(new DerivedReturnImplicit) instanceof DerivedReturnImplicit'); |
+shouldBeTrue('(new DerivedReturnImplicit) !== undefined'); |
+shouldBeTrue('(new DerivedReturnUndefined) instanceof DerivedReturnUndefined'); |
+shouldBeTrue('(new DerivedReturnUndefined) !== undefined'); |
+ |
+// Derived - return this => return this. |
+shouldBeTrue('(new DerivedReturnThis) instanceof DerivedReturnThis'); |
+ |
+// Derived - return Object => return object, not instance. |
+shouldBeFalse('(new DerivedReturnObject) instanceof DerivedReturnObject'); |
+shouldBeTrue('typeof (new DerivedReturnObject) === "object"'); |
+shouldBeFalse('(new DerivedReturnObject2) instanceof DerivedReturnObject2'); |
+shouldBeTrue('(new DerivedReturnObject2) === globalVariable'); |
+ |
+// Derived - return non-Object => exception. |
+shouldThrow('(new DerivedReturnString)'); |
+shouldThrow('(new DerivedReturnNumber)'); |
+shouldThrow('(new DerivedReturnNull)'); |
+shouldThrow('(new DerivedReturnSymbol)'); |
+shouldThrow('(new DerivedThrow)'); |
+ |
+ |
+debug(''); debug('Derived class not calling super()'); |
+class DerivedNoSuperNoReturn extends BaseNoReturn { constructor() { } }; |
+class DerivedNoSuperReturn extends BaseNoReturn { constructor() { return; } }; |
+class DerivedNoSuperReturnUndefined extends BaseNoReturn { constructor() { return undefined; } }; |
+class DerivedNoSuperReturnObject extends BaseNoReturn { constructor() { return {a:1}; } }; |
+class DerivedNoSuperReturnObject2 extends BaseNoReturn { constructor() { return globalVariable; } }; |
+class DerivedNoSuperReturnThis extends BaseNoReturn { constructor() { return this; } }; |
+class DerivedNoSuperReturnString extends BaseNoReturn { constructor() { return "test"; } }; |
+class DerivedNoSuperReturnNumber extends BaseNoReturn { constructor() { return 1; } }; |
+class DerivedNoSuperReturnNull extends BaseNoReturn { constructor() { return null; } }; |
+class DerivedNoSuperReturnSymbol extends BaseNoReturn { constructor() { return globalSymbol; } }; |
+class DerivedNoSuperThrow extends BaseNoReturn { constructor() { throw "Thrown Exception String"; } }; |
+ |
+// Derived without super() - Implicit => return this => TDZ. |
+shouldThrow('(new DerivedNoSuperNoReturn)'); |
+ |
+// Derived without super() - Early return => return this => TDZ. |
+shouldThrow('(new DerivedNoSuperReturnImplicit)'); |
+shouldThrow('(new DerivedNoSuperReturnUndefined)'); |
+ |
+// Derived without super() - return this => return this => TDZ |
+shouldThrow('(new DerivedNoSuperReturnThis)'); |
+ |
+// Derived without super() - return Object => no this access => return object, not instance |
+shouldNotThrow('(new DerivedNoSuperReturnObject)'); |
+shouldNotThrow('(new DerivedNoSuperReturnObject2)'); |
+ |
+// Derived without super() - return non-Object => exception |
+shouldThrow('(new DerivedNoSuperReturnString)'); // TypeError |
+shouldThrow('(new DerivedNoSuperReturnNumber)'); // TypeError |
+shouldThrow('(new DerivedNoSuperReturnNull)'); // TypeError |
+shouldThrow('(new DerivedNoSuperReturnSymbol)'); // TypeError |
+shouldThrow('(new DerivedNoSuperThrow)'); // Thrown exception |
+ |
+ |
+debug(''); debug('Derived class with default constructor and base class returning different values'); |
+class DerivedDefaultConstructorWithBaseNoReturn extends BaseNoReturn { }; |
+class DerivedDefaultConstructorWithBaseReturnImplicit extends BaseReturnImplicit { }; |
+class DerivedDefaultConstructorWithBaseReturnUndefined extends BaseReturnUndefined { }; |
+class DerivedDefaultConstructorWithBaseReturnThis extends BaseReturnThis { }; |
+class DerivedDefaultConstructorWithBaseReturnObject extends BaseReturnObject { }; |
+class DerivedDefaultConstructorWithBaseReturnObject2 extends BaseReturnObject2 { }; |
+class DerivedDefaultConstructorWithBaseReturnString extends BaseReturnString { }; |
+class DerivedDefaultConstructorWithBaseReturnNumber extends BaseReturnNumber { }; |
+class DerivedDefaultConstructorWithBaseReturnNull extends BaseReturnNull { }; |
+class DerivedDefaultConstructorWithBaseReturnSymbol extends BaseReturnSymbol { }; |
+class DerivedDefaultConstructorWithBaseThrow extends BaseThrow { }; |
+ |
+// Derived default constructor - implicit "super(...arguments)" return the result of the base (Object or this). |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined'); |
+shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject'); |
+shouldBeTrue('typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object"'); |
+shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull'); |
+shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol'); |
+shouldThrow('(new DerivedDefaultConstructorWithBaseThrow)'); |
+ |
+var successfullyParsed = true; |