1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Flags: --harmony-reflect --harmony-destructuring-bind 6 7 8 (function TestClass() { 9 'use strict'; 10 11 var calls = 0; 12 class Base { 13 constructor(_) { 14 assertEquals(Base, new.target); 15 calls++; 16 } 17 } 18 assertInstanceof(new Base(1), Base); 19 assertInstanceof(new Base(1, 2), Base); 20 assertInstanceof(new Base(), Base); 21 assertEquals(3, calls); 22 })(); 23 24 25 (function TestDerivedClass() { 26 'use strict'; 27 28 var calls = 0; 29 class Base { 30 constructor(expected) { 31 assertEquals(expected, new.target); 32 } 33 } 34 class Derived extends Base { 35 constructor(expected) { 36 super(expected); 37 assertEquals(expected, new.target); 38 calls++; 39 } 40 } 41 new Derived(Derived, 'extra'); 42 new Derived(Derived); 43 assertEquals(2, calls); 44 45 class Derived2 extends Derived {} 46 calls = 0; 47 new Derived2(Derived2); 48 new Derived2(Derived2, 'extra'); 49 assertEquals(2, calls); 50 })(); 51 52 53 (function TestFunctionCall() { 54 var calls; 55 function f(expected) { 56 calls++; 57 assertEquals(expected, new.target); 58 } 59 60 calls = 0; 61 f(undefined); 62 f(undefined, 'extra'); 63 f(); 64 assertEquals(3, calls); 65 66 calls = 0; 67 f.call({}, undefined); 68 f.call({}, undefined, 'extra'); 69 f.call({}); 70 assertEquals(3, calls); 71 72 calls = 0; 73 f.apply({}, [undefined]); 74 f.apply({}, [undefined, 'extra']); 75 f.apply({}, []); 76 assertEquals(3, calls); 77 })(); 78 79 80 (function TestFunctionConstruct() { 81 var calls; 82 function f(expected) { 83 calls++; 84 assertEquals(expected, new.target); 85 } 86 87 calls = 0; 88 new f(f); 89 new f(f, 'extra'); 90 assertEquals(2, calls); 91 })(); 92 93 94 (function TestClassExtendsFunction() { 95 'use strict'; 96 97 var calls = 0; 98 function f(expected) { 99 assertEquals(expected, new.target); 100 } 101 class Derived extends f { 102 constructor(expected) { 103 super(expected); 104 assertEquals(expected, new.target); 105 calls++; 106 } 107 } 108 109 new Derived(Derived); 110 new Derived(Derived, 'extra'); 111 assertEquals(2, calls); 112 })(); 113 114 115 (function TestFunctionReturnObject() { 116 function f(expected) { 117 assertEquals(expected, new.target); 118 return /abc/; 119 } 120 121 assertInstanceof(new f(f), RegExp); 122 assertInstanceof(new f(f, 'extra'), RegExp); 123 124 assertInstanceof(f(undefined), RegExp); 125 assertInstanceof(f(), RegExp); 126 assertInstanceof(f(undefined, 'extra'), RegExp); 127 })(); 128 129 130 (function TestClassReturnObject() { 131 'use strict'; 132 133 class Base { 134 constructor(expected) { 135 assertEquals(expected, new.target); 136 return /abc/; 137 } 138 } 139 140 assertInstanceof(new Base(Base), RegExp); 141 assertInstanceof(new Base(Base, 'extra'), RegExp); 142 143 class Derived extends Base {} 144 assertInstanceof(new Derived(Derived), RegExp); 145 assertInstanceof(new Derived(Derived, 'extra'), RegExp); 146 147 class Derived2 extends Base { 148 constructor(expected) { 149 super(expected); 150 assertInstanceof(this, RegExp); 151 } 152 } 153 assertInstanceof(new Derived2(Derived2), RegExp); 154 assertInstanceof(new Derived2(Derived2, 'extra'), RegExp); 155 })(); 156 157 158 (function TestReflectConstruct() { 159 var calls = 0; 160 function f(expected) { 161 calls++; 162 assertEquals(expected, new.target); 163 } 164 165 var o = Reflect.construct(f, [f]); 166 assertEquals(Object.getPrototypeOf(o), f.prototype); 167 o = Reflect.construct(f, [f, 'extra']); 168 assertEquals(Object.getPrototypeOf(o), f.prototype); 169 assertEquals(2, calls); 170 171 calls = 0; 172 o = Reflect.construct(f, [f], f); 173 assertEquals(Object.getPrototypeOf(o), f.prototype); 174 o = Reflect.construct(f, [f, 'extra'], f); 175 assertEquals(Object.getPrototypeOf(o), f.prototype); 176 assertEquals(2, calls); 177 178 179 function g() {} 180 calls = 0; 181 o = Reflect.construct(f, [g], g); 182 assertEquals(Object.getPrototypeOf(o), g.prototype); 183 o = Reflect.construct(f, [g, 'extra'], g); 184 assertEquals(Object.getPrototypeOf(o), g.prototype); 185 assertEquals(2, calls); 186 })(); 187 188 189 (function TestRestParametersFunction() { 190 function f(...rest) { 191 assertEquals(rest[0], new.target); 192 } 193 194 assertInstanceof(new f(f), f); 195 assertInstanceof(new f(f, 'extra'), f); 196 })(); 197 198 199 (function TestRestParametersClass() { 200 'use strict'; 201 202 class Base { 203 constructor(...rest) { 204 assertEquals(rest[0], new.target); 205 } 206 } 207 208 assertInstanceof(new Base(Base), Base); 209 assertInstanceof(new Base(Base, 'extra'), Base); 210 211 class Derived extends Base {} 212 213 assertInstanceof(new Derived(Derived), Derived); 214 assertInstanceof(new Derived(Derived, 'extra'), Derived); 215 })(); 216 217 218 (function TestArrowFunction() { 219 function f(expected) { 220 (() => { 221 assertEquals(expected, new.target); 222 })(); 223 } 224 225 assertInstanceof(new f(f), f); 226 assertInstanceof(new f(f, 'extra'), f); 227 })(); 228 229 230 (function TestRestParametersClass() { 231 'use strict'; 232 233 class Base { 234 constructor(expected) { 235 (() => { 236 assertEquals(expected, new.target); 237 })(); 238 } 239 } 240 241 assertInstanceof(new Base(Base), Base); 242 assertInstanceof(new Base(Base, 'extra'), Base); 243 244 class Derived extends Base {} 245 246 assertInstanceof(new Derived(Derived), Derived); 247 assertInstanceof(new Derived(Derived, 'extra'), Derived); 248 })(); 249 250 251 (function TestSloppyArguments() { 252 var length, a0, a1, a2, nt; 253 function f(x) { 254 assertEquals(length, arguments.length); 255 assertEquals(a0, arguments[0]); 256 assertEquals(a1, arguments[1]); 257 assertEquals(a2, arguments[2]); 258 assertEquals(nt, new.target); 259 260 if (length > 0) { 261 x = 42; 262 assertEquals(42, x); 263 assertEquals(42, arguments[0]); 264 265 arguments[0] = 33; 266 assertEquals(33, x); 267 assertEquals(33, arguments[0]); 268 } 269 } 270 271 nt = f; 272 length = 0; 273 new f(); 274 275 length = 1; 276 a0 = 1; 277 new f(1); 278 279 length = 2; 280 a0 = 1; 281 a1 = 2; 282 new f(1, 2); 283 284 length = 3; 285 a0 = 1; 286 a1 = 2; 287 a2 = 3; 288 new f(1, 2, 3); 289 290 nt = undefined; 291 a0 = a1 = a2 = undefined; 292 length = 0; 293 f(); 294 295 length = 1; 296 a0 = 1; 297 f(1); 298 299 length = 2; 300 a0 = 1; 301 a1 = 2; 302 f(1, 2); 303 304 length = 3; 305 a0 = 1; 306 a1 = 2; 307 a2 = 3; 308 f(1, 2, 3); 309 })(); 310 311 312 (function TestStrictArguments() { 313 var length, a0, a1, a2, nt; 314 function f(x) { 315 'use strict'; 316 assertEquals(length, arguments.length); 317 assertEquals(a0, arguments[0]); 318 assertEquals(a1, arguments[1]); 319 assertEquals(a2, arguments[2]); 320 assertEquals(nt, new.target); 321 322 if (length > 0) { 323 x = 42; 324 assertEquals(a0, arguments[0]); 325 326 arguments[0] = 33; 327 assertEquals(33, arguments[0]); 328 } 329 } 330 331 nt = f; 332 length = 0; 333 new f(); 334 335 length = 1; 336 a0 = 1; 337 new f(1); 338 339 length = 2; 340 a0 = 1; 341 a1 = 2; 342 new f(1, 2); 343 344 length = 3; 345 a0 = 1; 346 a1 = 2; 347 a2 = 3; 348 new f(1, 2, 3); 349 350 nt = undefined; 351 a0 = a1 = a2 = undefined; 352 length = 0; 353 f(); 354 355 length = 1; 356 a0 = 1; 357 f(1); 358 359 length = 2; 360 a0 = 1; 361 a1 = 2; 362 f(1, 2); 363 364 length = 3; 365 a0 = 1; 366 a1 = 2; 367 a2 = 3; 368 f(1, 2, 3); 369 })(); 370 371 372 (function TestOtherScopes() { 373 function f1() { return eval("'use strict'; new.target") } 374 assertSame(f1, new f1); 375 function f2() { with ({}) return new.target } 376 assertSame(f2, new f2); 377 function f3({a}) { return new.target } 378 assertSame(f3, new f3({})); 379 function f4(...a) { return new.target } 380 assertSame(f4, new f4); 381 function f5() { 'use strict'; { let x; return new.target } } 382 assertSame(f5, new f5); 383 function f6() { with ({'new.target': 42}) return new.target } 384 assertSame(f6, new f6); 385 })(); 386 387 388 // Has to be top-level to be inlined. 389 function get_new_target() { return new.target; } 390 (function TestInlining() { 391 "use strict"; 392 new function() { assertEquals(undefined, get_new_target()); } 393 new function() { assertEquals(get_new_target, new get_new_target()); } 394 395 class A extends get_new_target { 396 constructor() { 397 var new_target = super(); 398 this.new_target = new_target; 399 } 400 } 401 assertEquals(A, new A().new_target); 402 })(); 403 404 405 (function TestEarlyErrors() { 406 assertThrows(function() { Function("new.target = 42"); }, ReferenceError); 407 assertThrows(function() { Function("var foo = 1; new.target = foo = 42"); }, ReferenceError); 408 assertThrows(function() { Function("var foo = 1; foo = new.target = 42"); }, ReferenceError); 409 assertThrows(function() { Function("new.target--"); }, ReferenceError); 410 assertThrows(function() { Function("--new.target"); }, ReferenceError); 411 assertThrows(function() { Function("(new.target)++"); }, ReferenceError); 412 assertThrows(function() { Function("++(new.target)"); }, ReferenceError); 413 assertThrows(function() { Function("for (new.target of {});"); }, SyntaxError); 414 })(); 415