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