Home | History | Annotate | Download | only in webkit
      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