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