1// Copyright 2015 the V8 project authors. All rights reserved. 2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions 6// are met: 7// 1. Redistributions of source code must retain the above copyright 8// notice, this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright 10// notice, this list of conditions and the following disclaimer in the 11// documentation and/or other materials provided with the distribution. 12// 13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 24description('Tests for ES6 class constructor return values'); 25 26// ES6 27// - 9.2.2 [[Construct]] (ECMAScript Function Objects) 28// - 12.3.5.1 Runtime Semantics: Evaluation (The super Keyword) 29// - 14.5.14 Runtime Semantics: ClassDefinitionEvaluation (Default Constructor) 30 31var globalVariable = {name:"globalVariable"}; 32var globalSymbol = Symbol(); 33 34debug('Base class'); 35class BaseNoReturn { constructor() { } }; 36class BaseReturnImplicit { constructor() { return; } }; 37class BaseReturnUndefined { constructor() { return undefined; } }; 38class BaseReturnThis { constructor() { return this; } }; 39class BaseReturnObject { constructor() { return {a:1}; } }; 40class BaseReturnObject2 { constructor() { return globalVariable; } }; 41class BaseReturnString { constructor() { return "test"; } }; 42class BaseReturnNumber { constructor() { return 1; } }; 43class BaseReturnNull { constructor() { return null; } }; 44class BaseReturnSymbol { constructor() { return Symbol(); } }; 45class BaseThrow { constructor() { throw "Thrown Exception String"; } }; 46 47// Base - Implicit => return this. 48shouldBeTrue('(new BaseNoReturn) instanceof BaseNoReturn'); 49 50// Base - Early return => return this. 51shouldBeTrue('(new BaseReturnImplicit) instanceof BaseReturnImplicit'); 52shouldBeTrue('(new BaseReturnImplicit) !== undefined'); 53shouldBeTrue('(new BaseReturnUndefined) instanceof BaseReturnUndefined'); 54shouldBeTrue('(new BaseReturnUndefined) !== undefined'); 55 56// Base - return this => return this. 57shouldBeTrue('(new BaseReturnThis) instanceof BaseReturnThis'); 58 59// Base - return Object => return object, not instance. 60shouldBeFalse('(new BaseReturnObject) instanceof BaseReturnObject'); 61shouldBeTrue('typeof (new BaseReturnObject) === "object"'); 62shouldBeFalse('(new BaseReturnObject2) instanceof BaseReturnObject'); 63shouldBeTrue('(new BaseReturnObject2) === globalVariable'); 64 65// Base - return non-Object => return this. 66shouldBeTrue('(new BaseReturnString) instanceof BaseReturnString'); 67shouldBeTrue('typeof (new BaseReturnString) !== "string"'); 68shouldBeTrue('(new BaseReturnNumber) instanceof BaseReturnNumber'); 69shouldBeTrue('typeof (new BaseReturnNumber) !== "number"'); 70shouldBeTrue('(new BaseReturnNull) instanceof BaseReturnNull'); 71shouldBeTrue('(new BaseReturnNull) !== null'); 72shouldBeTrue('(new BaseReturnSymbol) instanceof BaseReturnSymbol'); 73shouldBeTrue('(new BaseReturnSymbol) !== globalSymbol'); 74 75// Base - throw => throw 76shouldThrow('(new BaseThrow)'); 77 78// Same behavior for Functions. 79debug(''); debug('Function constructor (non-class)'); 80function FunctionNoReturn() { }; 81function FunctionReturnImplicit() { return; }; 82function FunctionReturnUndefined() { return undefined; }; 83function FunctionReturnThis() { return this; }; 84function FunctionReturnObject() { return {a:1}; }; 85function FunctionReturnObject2() { return globalVariable; }; 86function FunctionReturnString() { return "test"; }; 87function FunctionReturnNumber() { return 1; }; 88function FunctionReturnNull() { return null; }; 89function FunctionReturnSymbol() { return Symbol(); }; 90function FunctionThrow() { throw "Thrown Exception String"; }; 91 92shouldBeTrue('(new FunctionNoReturn) instanceof FunctionNoReturn'); 93shouldBeTrue('(new FunctionReturnImplicit) instanceof FunctionReturnImplicit'); 94shouldBeTrue('(new FunctionReturnImplicit) !== undefined'); 95shouldBeTrue('(new FunctionReturnUndefined) instanceof FunctionReturnUndefined'); 96shouldBeTrue('(new FunctionReturnUndefined) !== undefined'); 97shouldBeTrue('(new FunctionReturnThis) instanceof FunctionReturnThis'); 98shouldBeFalse('(new FunctionReturnObject) instanceof FunctionReturnObject'); 99shouldBeTrue('typeof (new FunctionReturnObject) === "object"'); 100shouldBeFalse('(new FunctionReturnObject2) instanceof FunctionReturnObject'); 101shouldBeTrue('(new FunctionReturnObject2) === globalVariable'); 102shouldBeTrue('(new FunctionReturnString) instanceof FunctionReturnString'); 103shouldBeTrue('typeof (new FunctionReturnString) !== "string"'); 104shouldBeTrue('(new FunctionReturnNumber) instanceof FunctionReturnNumber'); 105shouldBeTrue('typeof (new FunctionReturnNumber) !== "number"'); 106shouldBeTrue('(new FunctionReturnNull) instanceof FunctionReturnNull'); 107shouldBeTrue('(new FunctionReturnNull) !== null'); 108shouldBeTrue('(new FunctionReturnSymbol) instanceof FunctionReturnSymbol'); 109shouldBeTrue('(new FunctionReturnSymbol) !== globalSymbol'); 110shouldThrow('(new FunctionThrow)'); 111 112 113debug(''); debug('Derived class calling super()'); 114class DerivedNoReturn extends BaseNoReturn { constructor() { super(); } }; 115class DerivedReturnImplicit extends BaseNoReturn { constructor() { super(); return; } }; 116class DerivedReturnUndefined extends BaseNoReturn { constructor() { super(); return undefined; } }; 117class DerivedReturnThis extends BaseNoReturn { constructor() { super(); return this; } }; 118class DerivedReturnObject extends BaseNoReturn { constructor() { super(); return {a:1}; } }; 119class DerivedReturnObject2 extends BaseNoReturn { constructor() { super(); return globalVariable; } }; 120class DerivedReturnString extends BaseNoReturn { constructor() { super(); return "test"; } }; 121class DerivedReturnNumber extends BaseNoReturn { constructor() { super(); return 1; } }; 122class DerivedReturnNull extends BaseNoReturn { constructor() { super(); return null; } }; 123class DerivedReturnSymbol extends BaseNoReturn { constructor() { super(); return globalSymbol; } }; 124class DerivedThrow extends BaseNoReturn { constructor() { super(); throw "Thrown Exception String"; } }; 125 126// Derived - Implicit => return this. 127shouldBeTrue('(new DerivedNoReturn) instanceof DerivedNoReturn'); 128 129// Derived - Early return => return this. 130shouldBeTrue('(new DerivedReturnImplicit) instanceof DerivedReturnImplicit'); 131shouldBeTrue('(new DerivedReturnImplicit) !== undefined'); 132shouldBeTrue('(new DerivedReturnUndefined) instanceof DerivedReturnUndefined'); 133shouldBeTrue('(new DerivedReturnUndefined) !== undefined'); 134 135// Derived - return this => return this. 136shouldBeTrue('(new DerivedReturnThis) instanceof DerivedReturnThis'); 137 138// Derived - return Object => return object, not instance. 139shouldBeFalse('(new DerivedReturnObject) instanceof DerivedReturnObject'); 140shouldBeTrue('typeof (new DerivedReturnObject) === "object"'); 141shouldBeFalse('(new DerivedReturnObject2) instanceof DerivedReturnObject2'); 142shouldBeTrue('(new DerivedReturnObject2) === globalVariable'); 143 144// Derived - return non-Object => exception. 145shouldThrow('(new DerivedReturnString)'); 146shouldThrow('(new DerivedReturnNumber)'); 147shouldThrow('(new DerivedReturnNull)'); 148shouldThrow('(new DerivedReturnSymbol)'); 149shouldThrow('(new DerivedThrow)'); 150 151 152debug(''); debug('Derived class not calling super()'); 153class DerivedNoSuperNoReturn extends BaseNoReturn { constructor() { } }; 154class DerivedNoSuperReturn extends BaseNoReturn { constructor() { return; } }; 155class DerivedNoSuperReturnUndefined extends BaseNoReturn { constructor() { return undefined; } }; 156class DerivedNoSuperReturnObject extends BaseNoReturn { constructor() { return {a:1}; } }; 157class DerivedNoSuperReturnObject2 extends BaseNoReturn { constructor() { return globalVariable; } }; 158class DerivedNoSuperReturnThis extends BaseNoReturn { constructor() { return this; } }; 159class DerivedNoSuperReturnString extends BaseNoReturn { constructor() { return "test"; } }; 160class DerivedNoSuperReturnNumber extends BaseNoReturn { constructor() { return 1; } }; 161class DerivedNoSuperReturnNull extends BaseNoReturn { constructor() { return null; } }; 162class DerivedNoSuperReturnSymbol extends BaseNoReturn { constructor() { return globalSymbol; } }; 163class DerivedNoSuperThrow extends BaseNoReturn { constructor() { throw "Thrown Exception String"; } }; 164 165// Derived without super() - Implicit => return this => TDZ. 166shouldThrow('(new DerivedNoSuperNoReturn)'); 167 168// Derived without super() - Early return => return this => TDZ. 169shouldThrow('(new DerivedNoSuperReturnImplicit)'); 170shouldThrow('(new DerivedNoSuperReturnUndefined)'); 171 172// Derived without super() - return this => return this => TDZ 173shouldThrow('(new DerivedNoSuperReturnThis)'); 174 175// Derived without super() - return Object => no this access => return object, not instance 176shouldNotThrow('(new DerivedNoSuperReturnObject)'); 177shouldNotThrow('(new DerivedNoSuperReturnObject2)'); 178 179// Derived without super() - return non-Object => exception 180shouldThrow('(new DerivedNoSuperReturnString)'); // TypeError 181shouldThrow('(new DerivedNoSuperReturnNumber)'); // TypeError 182shouldThrow('(new DerivedNoSuperReturnNull)'); // TypeError 183shouldThrow('(new DerivedNoSuperReturnSymbol)'); // TypeError 184shouldThrow('(new DerivedNoSuperThrow)'); // Thrown exception 185 186 187debug(''); debug('Derived class with default constructor and base class returning different values'); 188class DerivedDefaultConstructorWithBaseNoReturn extends BaseNoReturn { }; 189class DerivedDefaultConstructorWithBaseReturnImplicit extends BaseReturnImplicit { }; 190class DerivedDefaultConstructorWithBaseReturnUndefined extends BaseReturnUndefined { }; 191class DerivedDefaultConstructorWithBaseReturnThis extends BaseReturnThis { }; 192class DerivedDefaultConstructorWithBaseReturnObject extends BaseReturnObject { }; 193class DerivedDefaultConstructorWithBaseReturnObject2 extends BaseReturnObject2 { }; 194class DerivedDefaultConstructorWithBaseReturnString extends BaseReturnString { }; 195class DerivedDefaultConstructorWithBaseReturnNumber extends BaseReturnNumber { }; 196class DerivedDefaultConstructorWithBaseReturnNull extends BaseReturnNull { }; 197class DerivedDefaultConstructorWithBaseReturnSymbol extends BaseReturnSymbol { }; 198class DerivedDefaultConstructorWithBaseThrow extends BaseThrow { }; 199 200// Derived default constructor - implicit "super(...arguments)" return the result of the base (Object or this). 201shouldBeTrue('(new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn'); 202shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit'); 203shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined'); 204shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject'); 205shouldBeTrue('typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object"'); 206shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2'); 207shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable'); 208shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis'); 209shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString'); 210shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber'); 211shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull'); 212shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol'); 213shouldThrow('(new DerivedDefaultConstructorWithBaseThrow)'); 214 215var successfullyParsed = true; 216