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