|
| 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; |
0 commit comments