blob: fb77dbb8e4b01bb273512b215763dadbb1077661 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2014 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
Ben Murdochc5610432016-08-08 18:44:38 +01005// Flags: --allow-natives-syntax --harmony-do-expressions
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
7(function TestBasics() {
8 var C = class C {}
9 assertEquals(typeof C, 'function');
10 assertEquals(C.__proto__, Function.prototype);
11 assertEquals(Object.prototype, Object.getPrototypeOf(C.prototype));
12 assertEquals(Function.prototype, Object.getPrototypeOf(C));
13 assertEquals('C', C.name);
14
15 class D {}
16 assertEquals(typeof D, 'function');
17 assertEquals(D.__proto__, Function.prototype);
18 assertEquals(Object.prototype, Object.getPrototypeOf(D.prototype));
19 assertEquals(Function.prototype, Object.getPrototypeOf(D));
20 assertEquals('D', D.name);
21
22 class D2 { constructor() {} }
23 assertEquals('D2', D2.name);
24
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025 var E = class {}
Ben Murdochda12d292016-06-02 14:46:10 +010026 assertEquals('E', E.name); // Should be 'E'.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027
28 var F = class { constructor() {} };
Ben Murdochda12d292016-06-02 14:46:10 +010029 assertEquals('F', F.name); // Should be 'F'.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030})();
31
32
33(function TestBasicsExtends() {
34 class C extends null {}
35 assertEquals(typeof C, 'function');
36 assertEquals(C.__proto__, Function.prototype);
37 assertEquals(null, Object.getPrototypeOf(C.prototype));
38
39 class D extends C {}
40 assertEquals(typeof D, 'function');
41 assertEquals(D.__proto__, C);
42 assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
43})();
44
45
46(function TestSideEffectInExtends() {
47 var calls = 0;
48 class C {}
49 class D extends (calls++, C) {}
50 assertEquals(1, calls);
51 assertEquals(typeof D, 'function');
52 assertEquals(D.__proto__, C);
53 assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
54})();
55
56
57(function TestInvalidExtends() {
58 assertThrows(function() {
59 class C extends 42 {}
60 }, TypeError);
61
62 assertThrows(function() {
63 // Function but its .prototype is not null or a function.
64 class C extends Math.abs {}
65 }, TypeError);
66
67 assertThrows(function() {
68 Math.abs.prototype = 42;
69 class C extends Math.abs {}
70 }, TypeError);
71 delete Math.abs.prototype;
72
73 assertThrows(function() {
74 function* g() {}
75 class C extends g {}
76 }, TypeError);
77})();
78
79
80(function TestConstructorProperty() {
81 class C {}
82 assertEquals(C, C.prototype.constructor);
83 var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
84 assertTrue(descr.configurable);
85 assertFalse(descr.enumerable);
86 assertTrue(descr.writable);
87})();
88
89
90(function TestPrototypeProperty() {
91 class C {}
92 var descr = Object.getOwnPropertyDescriptor(C, 'prototype');
93 assertFalse(descr.configurable);
94 assertFalse(descr.enumerable);
95 assertFalse(descr.writable);
96})();
97
98
99(function TestConstructor() {
100 var count = 0;
101 class C {
102 constructor() {
103 assertEquals(Object.getPrototypeOf(this), C.prototype);
104 count++;
105 }
106 }
107 assertEquals(C, C.prototype.constructor);
108 var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
109 assertTrue(descr.configurable);
110 assertFalse(descr.enumerable);
111 assertTrue(descr.writable);
112
113 var c = new C();
114 assertEquals(1, count);
115 assertEquals(Object.getPrototypeOf(c), C.prototype);
116})();
117
118
119(function TestImplicitConstructor() {
120 class C {}
121 var c = new C();
122 assertEquals(Object.getPrototypeOf(c), C.prototype);
123})();
124
125
126(function TestConstructorStrict() {
127 class C {
128 constructor() {
129 assertThrows(function() {
130 nonExistingBinding = 42;
131 }, ReferenceError);
132 }
133 }
134 new C();
135})();
136
137
138(function TestSuperInConstructor() {
139 var calls = 0;
140 class B {}
141 B.prototype.x = 42;
142
143 class C extends B {
144 constructor() {
145 super();
146 calls++;
147 assertEquals(42, super.x);
148 }
149 }
150
151 new C;
152 assertEquals(1, calls);
153})();
154
155
156(function TestStrictMode() {
157 class C {}
158
159 with ({a: 1}) {
160 assertEquals(1, a);
161 }
162
163 assertThrows('class C extends function B() { with ({}); return B; }() {}',
164 SyntaxError);
165
166 var D = class extends function() {
167 arguments.caller;
168 } {};
169 assertThrows(function() {
170 Object.getPrototypeOf(D).arguments;
171 }, TypeError);
172 assertThrows(function() {
173 new D;
174 }, TypeError);
175})();
176
177
178(function TestToString() {
179 class C {}
180 assertEquals('class C {}', C.toString());
181
182 class D { constructor() { 42; } }
183 assertEquals('class D { constructor() { 42; } }', D.toString());
184
185 class E { x() { 42; } }
186 assertEquals('class E { x() { 42; } }', E.toString());
187})();
188
189
190function assertMethodDescriptor(object, name) {
191 var descr = Object.getOwnPropertyDescriptor(object, name);
192 assertTrue(descr.configurable);
193 assertFalse(descr.enumerable);
194 assertTrue(descr.writable);
195 assertEquals('function', typeof descr.value);
196 assertFalse('prototype' in descr.value);
197}
198
199
200function assertGetterDescriptor(object, name) {
201 var descr = Object.getOwnPropertyDescriptor(object, name);
202 assertTrue(descr.configurable);
203 assertFalse(descr.enumerable);
204 assertEquals('function', typeof descr.get);
205 assertFalse('prototype' in descr.get);
206 assertEquals(undefined, descr.set);
207}
208
209
210function assertSetterDescriptor(object, name) {
211 var descr = Object.getOwnPropertyDescriptor(object, name);
212 assertTrue(descr.configurable);
213 assertFalse(descr.enumerable);
214 assertEquals(undefined, descr.get);
215 assertEquals('function', typeof descr.set);
216 assertFalse('prototype' in descr.set);
217}
218
219
220function assertAccessorDescriptor(object, name) {
221 var descr = Object.getOwnPropertyDescriptor(object, name);
222 assertTrue(descr.configurable);
223 assertFalse(descr.enumerable);
224 assertEquals('function', typeof descr.get);
225 assertEquals('function', typeof descr.set);
226 assertFalse('prototype' in descr.get);
227 assertFalse('prototype' in descr.set);
228}
229
230
231(function TestMethods() {
232 class C {
233 method() { return 1; }
234 static staticMethod() { return 2; }
235 method2() { return 3; }
236 static staticMethod2() { return 4; }
237 }
238
239 assertMethodDescriptor(C.prototype, 'method');
240 assertMethodDescriptor(C.prototype, 'method2');
241 assertMethodDescriptor(C, 'staticMethod');
242 assertMethodDescriptor(C, 'staticMethod2');
243
244 assertEquals(1, new C().method());
245 assertEquals(2, C.staticMethod());
246 assertEquals(3, new C().method2());
247 assertEquals(4, C.staticMethod2());
248})();
249
250
251(function TestGetters() {
252 class C {
253 get x() { return 1; }
254 static get staticX() { return 2; }
255 get y() { return 3; }
256 static get staticY() { return 4; }
257 }
258
259 assertGetterDescriptor(C.prototype, 'x');
260 assertGetterDescriptor(C.prototype, 'y');
261 assertGetterDescriptor(C, 'staticX');
262 assertGetterDescriptor(C, 'staticY');
263
264 assertEquals(1, new C().x);
265 assertEquals(2, C.staticX);
266 assertEquals(3, new C().y);
267 assertEquals(4, C.staticY);
268})();
269
270
271
272(function TestSetters() {
273 var x, staticX, y, staticY;
274 class C {
275 set x(v) { x = v; }
276 static set staticX(v) { staticX = v; }
277 set y(v) { y = v; }
278 static set staticY(v) { staticY = v; }
279 }
280
281 assertSetterDescriptor(C.prototype, 'x');
282 assertSetterDescriptor(C.prototype, 'y');
283 assertSetterDescriptor(C, 'staticX');
284 assertSetterDescriptor(C, 'staticY');
285
286 assertEquals(1, new C().x = 1);
287 assertEquals(1, x);
288 assertEquals(2, C.staticX = 2);
289 assertEquals(2, staticX);
290 assertEquals(3, new C().y = 3);
291 assertEquals(3, y);
292 assertEquals(4, C.staticY = 4);
293 assertEquals(4, staticY);
294})();
295
296
297(function TestSideEffectsInPropertyDefine() {
298 function B() {}
299 B.prototype = {
300 constructor: B,
301 set m(v) {
302 throw Error();
303 }
304 };
305
306 class C extends B {
307 m() { return 1; }
308 }
309
310 assertEquals(1, new C().m());
311})();
312
313
314(function TestAccessors() {
315 class C {
316 constructor(x) {
317 this._x = x;
318 }
319
320 get x() { return this._x; }
321 set x(v) { this._x = v; }
322
323 static get staticX() { return this._x; }
324 static set staticX(v) { this._x = v; }
325 }
326
327 assertAccessorDescriptor(C.prototype, 'x');
328 assertAccessorDescriptor(C, 'staticX');
329
330 var c = new C(1);
331 c._x = 1;
332 assertEquals(1, c.x);
333 c.x = 2;
334 assertEquals(2, c._x);
335
336 C._x = 3;
337 assertEquals(3, C.staticX);
338 C._x = 4;
339 assertEquals(4, C.staticX );
340})();
341
342
343(function TestProto() {
344 class C {
345 __proto__() { return 1; }
346 }
347 assertMethodDescriptor(C.prototype, '__proto__');
348 assertEquals(1, new C().__proto__());
349})();
350
351
352(function TestProtoStatic() {
353 class C {
354 static __proto__() { return 1; }
355 }
356 assertMethodDescriptor(C, '__proto__');
357 assertEquals(1, C.__proto__());
358})();
359
360
361(function TestProtoAccessor() {
362 class C {
363 get __proto__() { return this._p; }
364 set __proto__(v) { this._p = v; }
365 }
366 assertAccessorDescriptor(C.prototype, '__proto__');
367 var c = new C();
368 c._p = 1;
369 assertEquals(1, c.__proto__);
370 c.__proto__ = 2;
371 assertEquals(2, c.__proto__);
372})();
373
374
375(function TestStaticProtoAccessor() {
376 class C {
377 static get __proto__() { return this._p; }
378 static set __proto__(v) { this._p = v; }
379 }
380 assertAccessorDescriptor(C, '__proto__');
381 C._p = 1;
382 assertEquals(1, C.__proto__);
383 C.__proto__ = 2;
384 assertEquals(2, C.__proto__);
385})();
386
387
388(function TestSettersOnProto() {
389 function Base() {}
390 Base.prototype = {
391 set constructor(_) {
392 assertUnreachable();
393 },
394 set m(_) {
395 assertUnreachable();
396 }
397 };
398 Object.defineProperty(Base, 'staticM', {
399 set: function() {
400 assertUnreachable();
401 }
402 });
403
404 class C extends Base {
405 m() {
406 return 1;
407 }
408 static staticM() {
409 return 2;
410 }
411 }
412
413 assertEquals(1, new C().m());
414 assertEquals(2, C.staticM());
415})();
416
417
418(function TestConstructableButNoPrototype() {
419 var Base = function() {}.bind();
420 assertThrows(function() {
421 class C extends Base {}
422 }, TypeError);
423})();
424
425
426(function TestPrototypeGetter() {
427 var calls = 0;
428 var Base = function() {}.bind();
429 Object.defineProperty(Base, 'prototype', {
430 get: function() {
431 calls++;
432 return null;
433 },
434 configurable: true
435 });
436 class C extends Base {}
437 assertEquals(1, calls);
438
439 calls = 0;
440 Object.defineProperty(Base, 'prototype', {
441 get: function() {
442 calls++;
443 return 42;
444 },
445 configurable: true
446 });
447 assertThrows(function() {
448 class C extends Base {}
449 }, TypeError);
450 assertEquals(1, calls);
451})();
452
453
454(function TestPrototypeSetter() {
455 var Base = function() {}.bind();
456 Object.defineProperty(Base, 'prototype', {
457 set: function() {
458 assertUnreachable();
459 }
460 });
461 assertThrows(function() {
462 class C extends Base {}
463 }, TypeError);
464})();
465
466
467(function TestSuperInMethods() {
468 class B {
469 method() {
470 return 1;
471 }
472 get x() {
473 return 2;
474 }
475 }
476 class C extends B {
477 method() {
478 assertEquals(2, super.x);
479 return super.method();
480 }
481 }
482 assertEquals(1, new C().method());
483})();
484
485
486(function TestSuperInGetter() {
487 class B {
488 method() {
489 return 1;
490 }
491 get x() {
492 return 2;
493 }
494 }
495 class C extends B {
496 get y() {
497 assertEquals(2, super.x);
498 return super.method();
499 }
500 }
501 assertEquals(1, new C().y);
502})();
503
504
505(function TestSuperInSetter() {
506 class B {
507 method() {
508 return 1;
509 }
510 get x() {
511 return 2;
512 }
513 }
514 class C extends B {
515 set y(v) {
516 assertEquals(3, v);
517 assertEquals(2, super.x);
518 assertEquals(1, super.method());
519 }
520 }
521 assertEquals(3, new C().y = 3);
522})();
523
524
525(function TestSuperInStaticMethods() {
526 class B {
527 static method() {
528 return 1;
529 }
530 static get x() {
531 return 2;
532 }
533 }
534 class C extends B {
535 static method() {
536 assertEquals(2, super.x);
537 return super.method();
538 }
539 }
540 assertEquals(1, C.method());
541})();
542
543
544(function TestSuperInStaticGetter() {
545 class B {
546 static method() {
547 return 1;
548 }
549 static get x() {
550 return 2;
551 }
552 }
553 class C extends B {
554 static get x() {
555 assertEquals(2, super.x);
556 return super.method();
557 }
558 }
559 assertEquals(1, C.x);
560})();
561
562
563(function TestSuperInStaticSetter() {
564 class B {
565 static method() {
566 return 1;
567 }
568 static get x() {
569 return 2;
570 }
571 }
572 class C extends B {
573 static set x(v) {
574 assertEquals(3, v);
575 assertEquals(2, super.x);
576 assertEquals(1, super.method());
577 }
578 }
579 assertEquals(3, C.x = 3);
580})();
581
582
583(function TestNumericPropertyNames() {
584 class B {
585 1() { return 1; }
586 get 2() { return 2; }
587 set 3(_) {}
588
589 static 4() { return 4; }
590 static get 5() { return 5; }
591 static set 6(_) {}
592 }
593
594 assertMethodDescriptor(B.prototype, '1');
595 assertGetterDescriptor(B.prototype, '2');
596 assertSetterDescriptor(B.prototype, '3');
597
598 assertMethodDescriptor(B, '4');
599 assertGetterDescriptor(B, '5');
600 assertSetterDescriptor(B, '6');
601
602 class C extends B {
603 1() { return super[1](); }
604 get 2() { return super[2]; }
605
606 static 4() { return super[4](); }
607 static get 5() { return super[5]; }
608 }
609
610 assertEquals(1, new C()[1]());
611 assertEquals(2, new C()[2]);
612 assertEquals(4, C[4]());
613 assertEquals(5, C[5]);
614})();
615
616
617(function TestDefaultConstructorNoCrash() {
618 // Regression test for https://code.google.com/p/v8/issues/detail?id=3661
619 class C {}
620 assertThrows(function () {C();}, TypeError);
621 assertThrows(function () {C(1);}, TypeError);
622 assertTrue(new C() instanceof C);
623 assertTrue(new C(1) instanceof C);
624})();
625
626
627(function TestConstructorCall(){
628 var realmIndex = Realm.create();
629 var otherTypeError = Realm.eval(realmIndex, "TypeError");
630 var A = Realm.eval(realmIndex, '"use strict"; class A {}');
631 var instance = new A();
632 var constructor = instance.constructor;
633 var otherTypeError = Realm.eval(realmIndex, 'TypeError');
634 if (otherTypeError === TypeError) {
635 throw Error('Should not happen!');
636 }
637
638 // ES6 9.2.1[[Call]] throws a TypeError in the caller context/Realm when the
639 // called function is a classConstructor
640 assertThrows(function() { Realm.eval(realmIndex, "A()") }, otherTypeError);
641 assertThrows(function() { instance.constructor() }, TypeError);
642 assertThrows(function() { A() }, TypeError);
643
644 // ES6 9.3.1 call() first activates the callee context before invoking the
645 // method. The TypeError from the constructor is thus thrown in the other
646 // Realm.
647 assertThrows(function() { Realm.eval(realmIndex, "A.call()") },
648 otherTypeError);
649 assertThrows(function() { constructor.call() }, otherTypeError);
650 assertThrows(function() { A.call() }, otherTypeError);
651})();
652
653
654(function TestConstructorCallOptimized() {
655 class A { };
656
657 function invoke_constructor() { A() }
658 function call_constructor() { A.call() }
659 function apply_constructor() { A.apply() }
660
661 for (var i=0; i<3; i++) {
662 assertThrows(invoke_constructor);
663 assertThrows(call_constructor);
664 assertThrows(apply_constructor);
665 }
666 // Make sure we still check for class constructors when calling optimized
667 // code.
668 %OptimizeFunctionOnNextCall(invoke_constructor);
669 assertThrows(invoke_constructor);
670 %OptimizeFunctionOnNextCall(call_constructor);
671 assertThrows(call_constructor);
672 %OptimizeFunctionOnNextCall(apply_constructor);
673 assertThrows(apply_constructor);
674})();
675
676
677(function TestDefaultConstructor() {
678 var calls = 0;
679 class Base {
680 constructor() {
681 calls++;
682 }
683 }
684 class Derived extends Base {}
685 var object = new Derived;
686 assertEquals(1, calls);
687
688 calls = 0;
689 assertThrows(function() { Derived(); }, TypeError);
690 assertEquals(0, calls);
691})();
692
693
694(function TestDefaultConstructorArguments() {
695 var args, self;
696 class Base {
697 constructor() {
698 self = this;
699 args = arguments;
700 }
701 }
702 class Derived extends Base {}
703
704 new Derived;
705 assertEquals(0, args.length);
706
707 new Derived(0, 1, 2);
708 assertEquals(3, args.length);
709 assertTrue(self instanceof Derived);
710
711 var arr = new Array(100);
712 var obj = {};
713 assertThrows(function() {Derived.apply(obj, arr);}, TypeError);
714})();
715
716
717(function TestDefaultConstructorArguments2() {
718 var args;
719 class Base {
720 constructor(x, y) {
721 args = arguments;
722 }
723 }
724 class Derived extends Base {}
725
726 new Derived;
727 assertEquals(0, args.length);
728
729 new Derived(1);
730 assertEquals(1, args.length);
731 assertEquals(1, args[0]);
732
733 new Derived(1, 2, 3);
734 assertEquals(3, args.length);
735 assertEquals(1, args[0]);
736 assertEquals(2, args[1]);
737 assertEquals(3, args[2]);
738})();
739
740
741(function TestNameBindingConst() {
742 assertThrows('class C { constructor() { C = 42; } }; new C();', TypeError);
743 assertThrows('new (class C { constructor() { C = 42; } })', TypeError);
744 assertThrows('class C { m() { C = 42; } }; new C().m()', TypeError);
745 assertThrows('new (class C { m() { C = 42; } }).m()', TypeError);
746 assertThrows('class C { get x() { C = 42; } }; new C().x', TypeError);
747 assertThrows('(new (class C { get x() { C = 42; } })).x', TypeError);
748 assertThrows('class C { set x(_) { C = 42; } }; new C().x = 15;', TypeError);
749 assertThrows('(new (class C { set x(_) { C = 42; } })).x = 15;', TypeError);
750})();
751
752
753(function TestNameBinding() {
754 var C2;
755 class C {
756 constructor() {
757 C2 = C;
758 }
759 m() {
760 C2 = C;
761 }
762 get x() {
763 C2 = C;
764 }
765 set x(_) {
766 C2 = C;
767 }
768 }
769 new C();
770 assertEquals(C, C2);
771
772 C2 = undefined;
773 new C().m();
774 assertEquals(C, C2);
775
776 C2 = undefined;
777 new C().x;
778 assertEquals(C, C2);
779
780 C2 = undefined;
781 new C().x = 1;
782 assertEquals(C, C2);
783})();
784
785
786(function TestNameBindingExpression() {
787 var C3;
788 var C = class C2 {
789 constructor() {
790 assertEquals(C2, C);
791 C3 = C2;
792 }
793 m() {
794 assertEquals(C2, C);
795 C3 = C2;
796 }
797 get x() {
798 assertEquals(C2, C);
799 C3 = C2;
800 }
801 set x(_) {
802 assertEquals(C2, C);
803 C3 = C2;
804 }
805 }
806 new C();
807 assertEquals(C, C3);
808
809 C3 = undefined;
810 new C().m();
811 assertEquals(C, C3);
812
813 C3 = undefined;
814 new C().x;
815 assertEquals(C, C3);
816
817 C3 = undefined;
818 new C().x = 1;
819 assertEquals(C, C3);
820})();
821
822
823(function TestNameBindingInExtendsExpression() {
824 assertThrows(function() {
825 class x extends x {}
826 }, ReferenceError);
827
828 assertThrows(function() {
829 (class x extends x {});
830 }, ReferenceError);
831
832 assertThrows(function() {
833 var x = (class x extends x {});
834 }, ReferenceError);
835})();
836
837
838(function TestThisAccessRestriction() {
839 class Base {}
840 (function() {
841 class C extends Base {
842 constructor() {
843 var y;
844 super();
845 }
846 }; new C();
847 }());
848 assertThrows(function() {
849 class C extends Base {
850 constructor() {
851 super(this.x);
852 }
853 }; new C();
854 }, ReferenceError);
855 assertThrows(function() {
856 class C extends Base {
857 constructor() {
858 super(this);
859 }
860 }; new C();
861 }, ReferenceError);
862 assertThrows(function() {
863 class C extends Base {
864 constructor() {
865 super.method();
866 super(this);
867 }
868 }; new C();
869 }, ReferenceError);
870 assertThrows(function() {
871 class C extends Base {
872 constructor() {
873 super(super.method());
874 }
875 }; new C();
876 }, ReferenceError);
877 assertThrows(function() {
878 class C extends Base {
879 constructor() {
880 super(super());
881 }
882 }; new C();
883 }, ReferenceError);
884 assertThrows(function() {
885 class C extends Base {
886 constructor() {
887 super(1, 2, Object.getPrototypeOf(this));
888 }
889 }; new C();
890 }, ReferenceError);
891 (function() {
892 class C extends Base {
893 constructor() {
894 { super(1, 2); }
895 }
896 }; new C();
897 }());
898 (function() {
899 class C extends Base {
900 constructor() {
901 if (1) super();
902 }
903 }; new C();
904 }());
905
906 class C1 extends Object {
907 constructor() {
908 'use strict';
909 super();
910 }
911 };
912 new C1();
913
914 class C2 extends Object {
915 constructor() {
916 ; 'use strict';;;;;
917 super();
918 }
919 };
920 new C2();
921
922 class C3 extends Object {
923 constructor() {
924 ; 'use strict';;;;;
925 // This is a comment.
926 super();
927 }
928 };
929 new C3();
930}());
931
932
933function testClassRestrictedProperties(C) {
934 assertEquals(false, C.hasOwnProperty("arguments"));
935 assertThrows(function() { return C.arguments; }, TypeError);
936 assertThrows(function() { C.arguments = {}; }, TypeError);
937
938 assertEquals(false, C.hasOwnProperty("caller"));
939 assertThrows(function() { return C.caller; }, TypeError);
940 assertThrows(function() { C.caller = {}; }, TypeError);
941
942 assertEquals(false, (new C).method.hasOwnProperty("arguments"));
943 assertThrows(function() { return new C().method.arguments; }, TypeError);
944 assertThrows(function() { new C().method.arguments = {}; }, TypeError);
945
946 assertEquals(false, (new C).method.hasOwnProperty("caller"));
947 assertThrows(function() { return new C().method.caller; }, TypeError);
948 assertThrows(function() { new C().method.caller = {}; }, TypeError);
949}
950
951
952(function testRestrictedPropertiesStrict() {
953 "use strict";
954 class ClassWithDefaultConstructor {
955 method() {}
956 }
957 class Class {
958 constructor() {}
959 method() {}
960 }
961 class DerivedClassWithDefaultConstructor extends Class {}
962 class DerivedClass extends Class { constructor() { super(); } }
963
964 testClassRestrictedProperties(ClassWithDefaultConstructor);
965 testClassRestrictedProperties(Class);
966 testClassRestrictedProperties(DerivedClassWithDefaultConstructor);
967 testClassRestrictedProperties(DerivedClass);
968 testClassRestrictedProperties(class { method() {} });
969 testClassRestrictedProperties(class { constructor() {} method() {} });
970 testClassRestrictedProperties(class extends Class { });
971 testClassRestrictedProperties(
972 class extends Class { constructor() { super(); } });
973})();
974
975
976(function testRestrictedPropertiesSloppy() {
977 class ClassWithDefaultConstructor {
978 method() {}
979 }
980 class Class {
981 constructor() {}
982 method() {}
983 }
984 class DerivedClassWithDefaultConstructor extends Class {}
985 class DerivedClass extends Class { constructor() { super(); } }
986
987 testClassRestrictedProperties(ClassWithDefaultConstructor);
988 testClassRestrictedProperties(Class);
989 testClassRestrictedProperties(DerivedClassWithDefaultConstructor);
990 testClassRestrictedProperties(DerivedClass);
991 testClassRestrictedProperties(class { method() {} });
992 testClassRestrictedProperties(class { constructor() {} method() {} });
993 testClassRestrictedProperties(class extends Class { });
994 testClassRestrictedProperties(
995 class extends Class { constructor() { super(); } });
996})();
Ben Murdochda12d292016-06-02 14:46:10 +0100997
998
999(function testReturnFromClassLiteral() {
1000
1001 function usingDoExpressionInBody() {
1002 let x = 42;
1003 let dummy = function() {x};
1004 try {
1005 class C {
1006 dummy() {C}
1007 [do {return}]() {}
1008 };
1009 } finally {
1010 return x;
1011 }
1012 }
1013 assertEquals(42, usingDoExpressionInBody());
1014
1015 function usingDoExpressionInExtends() {
1016 let x = 42;
1017 let dummy = function() {x};
1018 try {
1019 class C extends (do {return}) { dummy() {C} };
1020 } finally {
1021 return x;
1022 }
1023 }
1024 assertEquals(42, usingDoExpressionInExtends());
1025
1026 function usingYieldInBody() {
1027 function* foo() {
1028 class C {
1029 [yield]() {}
1030 }
1031 }
1032 var g = foo();
1033 g.next();
1034 return g.return(42).value;
1035 }
1036 assertEquals(42, usingYieldInBody());
1037
1038 function usingYieldInExtends() {
1039 function* foo() {
1040 class C extends (yield) {};
1041 }
1042 var g = foo();
1043 g.next();
1044 return g.return(42).value;
1045 }
1046 assertEquals(42, usingYieldInExtends());
1047
1048})();