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 24// Flags: --harmony-sloppy 25 26description('Tests for ES6 class constructor return values'); 27 28// ES6 29// - 9.2.2 [[Construct]] (ECMAScript Function Objects) 30// - 12.3.5.1 Runtime Semantics: Evaluation (The super Keyword) 31// - 14.5.14 Runtime Semantics: ClassDefinitionEvaluation (Default Constructor) 32 33var globalVariable = {name:"globalVariable"}; 34var globalSymbol = Symbol(); 35 36debug('Base class'); 37class BaseNoReturn { constructor() { } }; 38class BaseReturnImplicit { constructor() { return; } }; 39class BaseReturnUndefined { constructor() { return undefined; } }; 40class BaseReturnThis { constructor() { return this; } }; 41class BaseReturnObject { constructor() { return {a:1}; } }; 42class BaseReturnObject2 { constructor() { return globalVariable; } }; 43class BaseReturnString { constructor() { return "test"; } }; 44class BaseReturnNumber { constructor() { return 1; } }; 45class BaseReturnNull { constructor() { return null; } }; 46class BaseReturnSymbol { constructor() { return Symbol(); } }; 47class BaseThrow { constructor() { throw "Thrown Exception String"; } }; 48 49// Base - Implicit => return this. 50shouldBeTrue('(new BaseNoReturn) instanceof BaseNoReturn'); 51 52// Base - Early return => return this. 53shouldBeTrue('(new BaseReturnImplicit) instanceof BaseReturnImplicit'); 54shouldBeTrue('(new BaseReturnImplicit) !== undefined'); 55shouldBeTrue('(new BaseReturnUndefined) instanceof BaseReturnUndefined'); 56shouldBeTrue('(new BaseReturnUndefined) !== undefined'); 57 58// Base - return this => return this. 59shouldBeTrue('(new BaseReturnThis) instanceof BaseReturnThis'); 60 61// Base - return Object => return object, not instance. 62shouldBeFalse('(new BaseReturnObject) instanceof BaseReturnObject'); 63shouldBeTrue('typeof (new BaseReturnObject) === "object"'); 64shouldBeFalse('(new BaseReturnObject2) instanceof BaseReturnObject'); 65shouldBeTrue('(new BaseReturnObject2) === globalVariable'); 66 67// Base - return non-Object => return this. 68shouldBeTrue('(new BaseReturnString) instanceof BaseReturnString'); 69shouldBeTrue('typeof (new BaseReturnString) !== "string"'); 70shouldBeTrue('(new BaseReturnNumber) instanceof BaseReturnNumber'); 71shouldBeTrue('typeof (new BaseReturnNumber) !== "number"'); 72shouldBeTrue('(new BaseReturnNull) instanceof BaseReturnNull'); 73shouldBeTrue('(new BaseReturnNull) !== null'); 74shouldBeTrue('(new BaseReturnSymbol) instanceof BaseReturnSymbol'); 75shouldBeTrue('(new BaseReturnSymbol) !== globalSymbol'); 76 77// Base - throw => throw 78shouldThrow('(new BaseThrow)'); 79 80// Same behavior for Functions. 81debug(''); debug('Function constructor (non-class)'); 82function FunctionNoReturn() { }; 83function FunctionReturnImplicit() { return; }; 84function FunctionReturnUndefined() { return undefined; }; 85function FunctionReturnThis() { return this; }; 86function FunctionReturnObject() { return {a:1}; }; 87function FunctionReturnObject2() { return globalVariable; }; 88function FunctionReturnString() { return "test"; }; 89function FunctionReturnNumber() { return 1; }; 90function FunctionReturnNull() { return null; }; 91function FunctionReturnSymbol() { return Symbol(); }; 92function FunctionThrow() { throw "Thrown Exception String"; }; 93 94shouldBeTrue('(new FunctionNoReturn) instanceof FunctionNoReturn'); 95shouldBeTrue('(new FunctionReturnImplicit) instanceof FunctionReturnImplicit'); 96shouldBeTrue('(new FunctionReturnImplicit) !== undefined'); 97shouldBeTrue('(new FunctionReturnUndefined) instanceof FunctionReturnUndefined'); 98shouldBeTrue('(new FunctionReturnUndefined) !== undefined'); 99shouldBeTrue('(new FunctionReturnThis) instanceof FunctionReturnThis'); 100shouldBeFalse('(new FunctionReturnObject) instanceof FunctionReturnObject'); 101shouldBeTrue('typeof (new FunctionReturnObject) === "object"'); 102shouldBeFalse('(new FunctionReturnObject2) instanceof FunctionReturnObject'); 103shouldBeTrue('(new FunctionReturnObject2) === globalVariable'); 104shouldBeTrue('(new FunctionReturnString) instanceof FunctionReturnString'); 105shouldBeTrue('typeof (new FunctionReturnString) !== "string"'); 106shouldBeTrue('(new FunctionReturnNumber) instanceof FunctionReturnNumber'); 107shouldBeTrue('typeof (new FunctionReturnNumber) !== "number"'); 108shouldBeTrue('(new FunctionReturnNull) instanceof FunctionReturnNull'); 109shouldBeTrue('(new FunctionReturnNull) !== null'); 110shouldBeTrue('(new FunctionReturnSymbol) instanceof FunctionReturnSymbol'); 111shouldBeTrue('(new FunctionReturnSymbol) !== globalSymbol'); 112shouldThrow('(new FunctionThrow)'); 113 114 115debug(''); debug('Derived class calling super()'); 116class DerivedNoReturn extends BaseNoReturn { constructor() { super(); } }; 117class DerivedReturnImplicit extends BaseNoReturn { constructor() { super(); return; } }; 118class DerivedReturnUndefined extends BaseNoReturn { constructor() { super(); return undefined; } }; 119class DerivedReturnThis extends BaseNoReturn { constructor() { super(); return this; } }; 120class DerivedReturnObject extends BaseNoReturn { constructor() { super(); return {a:1}; } }; 121class DerivedReturnObject2 extends BaseNoReturn { constructor() { super(); return globalVariable; } }; 122class DerivedReturnString extends BaseNoReturn { constructor() { super(); return "test"; } }; 123class DerivedReturnNumber extends BaseNoReturn { constructor() { super(); return 1; } }; 124class DerivedReturnNull extends BaseNoReturn { constructor() { super(); return null; } }; 125class DerivedReturnSymbol extends BaseNoReturn { constructor() { super(); return globalSymbol; } }; 126class DerivedThrow extends BaseNoReturn { constructor() { super(); throw "Thrown Exception String"; } }; 127 128// Derived - Implicit => return this. 129shouldBeTrue('(new DerivedNoReturn) instanceof DerivedNoReturn'); 130 131// Derived - Early return => return this. 132shouldBeTrue('(new DerivedReturnImplicit) instanceof DerivedReturnImplicit'); 133shouldBeTrue('(new DerivedReturnImplicit) !== undefined'); 134shouldBeTrue('(new DerivedReturnUndefined) instanceof DerivedReturnUndefined'); 135shouldBeTrue('(new DerivedReturnUndefined) !== undefined'); 136 137// Derived - return this => return this. 138shouldBeTrue('(new DerivedReturnThis) instanceof DerivedReturnThis'); 139 140// Derived - return Object => return object, not instance. 141shouldBeFalse('(new DerivedReturnObject) instanceof DerivedReturnObject'); 142shouldBeTrue('typeof (new DerivedReturnObject) === "object"'); 143shouldBeFalse('(new DerivedReturnObject2) instanceof DerivedReturnObject2'); 144shouldBeTrue('(new DerivedReturnObject2) === globalVariable'); 145 146// Derived - return non-Object => exception. 147shouldThrow('(new DerivedReturnString)'); 148shouldThrow('(new DerivedReturnNumber)'); 149shouldThrow('(new DerivedReturnNull)'); 150shouldThrow('(new DerivedReturnSymbol)'); 151shouldThrow('(new DerivedThrow)'); 152 153 154debug(''); debug('Derived class not calling super()'); 155class DerivedNoSuperNoReturn extends BaseNoReturn { constructor() { } }; 156class DerivedNoSuperReturn extends BaseNoReturn { constructor() { return; } }; 157class DerivedNoSuperReturnUndefined extends BaseNoReturn { constructor() { return undefined; } }; 158class DerivedNoSuperReturnObject extends BaseNoReturn { constructor() { return {a:1}; } }; 159class DerivedNoSuperReturnObject2 extends BaseNoReturn { constructor() { return globalVariable; } }; 160class DerivedNoSuperReturnThis extends BaseNoReturn { constructor() { return this; } }; 161class DerivedNoSuperReturnString extends BaseNoReturn { constructor() { return "test"; } }; 162class DerivedNoSuperReturnNumber extends BaseNoReturn { constructor() { return 1; } }; 163class DerivedNoSuperReturnNull extends BaseNoReturn { constructor() { return null; } }; 164class DerivedNoSuperReturnSymbol extends BaseNoReturn { constructor() { return globalSymbol; } }; 165class DerivedNoSuperThrow extends BaseNoReturn { constructor() { throw "Thrown Exception String"; } }; 166 167// Derived without super() - Implicit => return this => TDZ. 168shouldThrow('(new DerivedNoSuperNoReturn)'); 169 170// Derived without super() - Early return => return this => TDZ. 171shouldThrow('(new DerivedNoSuperReturnImplicit)'); 172shouldThrow('(new DerivedNoSuperReturnUndefined)'); 173 174// Derived without super() - return this => return this => TDZ 175shouldThrow('(new DerivedNoSuperReturnThis)'); 176 177// Derived without super() - return Object => no this access => return object, not instance 178shouldNotThrow('(new DerivedNoSuperReturnObject)'); 179shouldNotThrow('(new DerivedNoSuperReturnObject2)'); 180 181// Derived without super() - return non-Object => exception 182shouldThrow('(new DerivedNoSuperReturnString)'); // TypeError 183shouldThrow('(new DerivedNoSuperReturnNumber)'); // TypeError 184shouldThrow('(new DerivedNoSuperReturnNull)'); // TypeError 185shouldThrow('(new DerivedNoSuperReturnSymbol)'); // TypeError 186shouldThrow('(new DerivedNoSuperThrow)'); // Thrown exception 187 188 189debug(''); debug('Derived class with default constructor and base class returning different values'); 190class DerivedDefaultConstructorWithBaseNoReturn extends BaseNoReturn { }; 191class DerivedDefaultConstructorWithBaseReturnImplicit extends BaseReturnImplicit { }; 192class DerivedDefaultConstructorWithBaseReturnUndefined extends BaseReturnUndefined { }; 193class DerivedDefaultConstructorWithBaseReturnThis extends BaseReturnThis { }; 194class DerivedDefaultConstructorWithBaseReturnObject extends BaseReturnObject { }; 195class DerivedDefaultConstructorWithBaseReturnObject2 extends BaseReturnObject2 { }; 196class DerivedDefaultConstructorWithBaseReturnString extends BaseReturnString { }; 197class DerivedDefaultConstructorWithBaseReturnNumber extends BaseReturnNumber { }; 198class DerivedDefaultConstructorWithBaseReturnNull extends BaseReturnNull { }; 199class DerivedDefaultConstructorWithBaseReturnSymbol extends BaseReturnSymbol { }; 200class DerivedDefaultConstructorWithBaseThrow extends BaseThrow { }; 201 202// Derived default constructor - implicit "super(...arguments)" return the result of the base (Object or this). 203shouldBeTrue('(new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn'); 204shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit'); 205shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined'); 206shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject'); 207shouldBeTrue('typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object"'); 208shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2'); 209shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable'); 210shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis'); 211shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString'); 212shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber'); 213shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull'); 214shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol'); 215shouldThrow('(new DerivedDefaultConstructorWithBaseThrow)'); 216 217var successfullyParsed = true; 218