blob: dbd4c3bcbec2f4e76fde7fce0b0b4a9775958f92 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
7 var lines =<< trim END
8 class NotWorking
9 endclass
10 END
11 v9.CheckScriptFailure(lines, 'E1316:')
12
13 lines =<< trim END
14 vim9script
15 class notWorking
16 endclass
17 END
18 v9.CheckScriptFailure(lines, 'E1314:')
19
20 lines =<< trim END
21 vim9script
22 class Not@working
23 endclass
24 END
25 v9.CheckScriptFailure(lines, 'E1315:')
26
27 lines =<< trim END
28 vim9script
29 abstract noclass Something
30 endclass
31 END
32 v9.CheckScriptFailure(lines, 'E475:')
33
34 lines =<< trim END
35 vim9script
36 abstract classy Something
37 endclass
38 END
39 v9.CheckScriptFailure(lines, 'E475:')
40
41 lines =<< trim END
42 vim9script
43 class Something
44 endcl
45 END
46 v9.CheckScriptFailure(lines, 'E1065:')
47
48 lines =<< trim END
49 vim9script
50 class Something
Bram Moolenaar94722c52023-01-28 19:19:03 +000051 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000052 END
53 v9.CheckScriptFailure(lines, 'E488:')
54
55 lines =<< trim END
56 vim9script
57 class Something
58 endclass | echo 'done'
59 END
60 v9.CheckScriptFailure(lines, 'E488:')
61
62 lines =<< trim END
63 vim9script
64 class Something
65 this
66 endclass
67 END
68 v9.CheckScriptFailure(lines, 'E1317:')
69
70 lines =<< trim END
71 vim9script
72 class Something
73 this.
74 endclass
75 END
76 v9.CheckScriptFailure(lines, 'E1317:')
77
78 lines =<< trim END
79 vim9script
80 class Something
81 this .count
82 endclass
83 END
84 v9.CheckScriptFailure(lines, 'E1317:')
85
86 lines =<< trim END
87 vim9script
88 class Something
89 this. count
90 endclass
91 END
92 v9.CheckScriptFailure(lines, 'E1317:')
93
94 lines =<< trim END
95 vim9script
96 class Something
97 this.count: number
98 that.count
99 endclass
100 END
101 v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
102
103 lines =<< trim END
104 vim9script
105 class Something
106 this.count
107 endclass
108 END
109 v9.CheckScriptFailure(lines, 'E1022:')
110
111 lines =<< trim END
112 vim9script
113 class Something
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000114 def new()
115 this.state = 0
116 enddef
117 endclass
118 var obj = Something.new()
119 END
120 v9.CheckScriptFailure(lines, 'E1089:')
121
122 lines =<< trim END
123 vim9script
124 class Something
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000125 this.count : number
126 endclass
127 END
128 v9.CheckScriptFailure(lines, 'E1059:')
129
130 lines =<< trim END
131 vim9script
132 class Something
133 this.count:number
134 endclass
135 END
136 v9.CheckScriptFailure(lines, 'E1069:')
137
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200138 # Test for unsupported comment specifier
139 lines =<< trim END
140 vim9script
141 class Something
142 # comment
143 #{
144 endclass
145 END
146 v9.CheckScriptFailure(lines, 'E1170:')
147
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000148 lines =<< trim END
149 vim9script
150
151 class TextPosition
152 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000153 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000154
Bram Moolenaar418b5472022-12-20 13:38:22 +0000155 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000156 def ToString(): string
157 return $'({this.lnum}, {this.col})'
158 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000159 endclass
160
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000161 # use the automatically generated new() method
162 var pos = TextPosition.new(2, 12)
163 assert_equal(2, pos.lnum)
164 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000165
166 # call an object method
167 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000168
169 assert_equal(v:t_class, type(TextPosition))
170 assert_equal(v:t_object, type(pos))
171 assert_equal('class<TextPosition>', typename(TextPosition))
172 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000173 END
174 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200175
176 # When referencing object methods, space cannot be used after a "."
177 lines =<< trim END
178 vim9script
179 class A
180 def Foo(): number
181 return 10
182 enddef
183 endclass
184 var a = A.new()
185 var v = a. Foo()
186 END
187 v9.CheckScriptFailure(lines, 'E1202:')
188
189 # Using an object without specifying a method or a member variable
190 lines =<< trim END
191 vim9script
192 class A
193 def Foo(): number
194 return 10
195 enddef
196 endclass
197 var a = A.new()
198 var v = a.
199 END
200 v9.CheckScriptFailure(lines, 'E15:')
201
202 # Error when parsing the arguments of an object method.
203 lines =<< trim END
204 vim9script
205 class A
206 def Foo()
207 enddef
208 endclass
209 var a = A.new()
210 var v = a.Foo(,)
211 END
212 v9.CheckScriptFailure(lines, 'E15:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213enddef
214
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000215def Test_class_defined_twice()
216 # class defined twice should fail
217 var lines =<< trim END
218 vim9script
219 class There
220 endclass
221 class There
222 endclass
223 END
224 v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
225
226 # one class, reload same script twice is OK
227 lines =<< trim END
228 vim9script
229 class There
230 endclass
231 END
232 writefile(lines, 'XclassTwice.vim', 'D')
233 source XclassTwice.vim
234 source XclassTwice.vim
235enddef
236
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000237def Test_returning_null_object()
238 # this was causing an internal error
239 var lines =<< trim END
240 vim9script
241
242 class BufferList
243 def Current(): any
244 return null_object
245 enddef
246 endclass
247
248 var buffers = BufferList.new()
249 echo buffers.Current()
250 END
251 v9.CheckScriptSuccess(lines)
252enddef
253
Bram Moolenaard13dd302023-03-11 20:56:35 +0000254def Test_using_null_class()
255 var lines =<< trim END
256 @_ = null_class.member
257 END
258 v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
259enddef
260
Bram Moolenaar657aea72023-01-27 13:16:19 +0000261def Test_class_interface_wrong_end()
262 var lines =<< trim END
263 vim9script
264 abstract class SomeName
265 this.member = 'text'
266 endinterface
267 END
268 v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
269
270 lines =<< trim END
271 vim9script
272 export interface AnotherName
273 this.member: string
274 endclass
275 END
276 v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
277enddef
278
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000279def Test_object_not_set()
280 var lines =<< trim END
281 vim9script
282
283 class State
284 this.value = 'xyz'
285 endclass
286
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000287 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000288 var db = {'xyz': 789}
289 echo db[state.value]
290 END
291 v9.CheckScriptFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000292
293 lines =<< trim END
294 vim9script
295
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000296 class Class
297 this.id: string
298 def Method1()
299 echo 'Method1' .. this.id
300 enddef
301 endclass
302
303 var obj: Class
304 def Func()
305 obj.Method1()
306 enddef
307 Func()
308 END
309 v9.CheckScriptFailure(lines, 'E1360:')
310
311 lines =<< trim END
312 vim9script
313
Bram Moolenaar0917e862023-02-18 14:42:44 +0000314 class Background
315 this.background = 'dark'
316 endclass
317
318 class Colorscheme
319 this._bg: Background
320
321 def GetBackground(): string
322 return this._bg.background
323 enddef
324 endclass
325
326 var bg: Background # UNINITIALIZED
327 echo Colorscheme.new(bg).GetBackground()
328 END
329 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Background> but got object<Unknown>')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000330
331 # TODO: this should not give an error but be handled at runtime
332 lines =<< trim END
333 vim9script
334
335 class Class
336 this.id: string
337 def Method1()
338 echo 'Method1' .. this.id
339 enddef
340 endclass
341
342 var obj = null_object
343 def Func()
344 obj.Method1()
345 enddef
346 Func()
347 END
348 v9.CheckScriptFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000349enddef
350
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000351def Test_class_member_initializer()
352 var lines =<< trim END
353 vim9script
354
355 class TextPosition
356 this.lnum: number = 1
357 this.col: number = 1
358
Bram Moolenaar418b5472022-12-20 13:38:22 +0000359 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000360 def new(lnum: number)
361 this.lnum = lnum
362 enddef
363 endclass
364
365 var pos = TextPosition.new(3)
366 assert_equal(3, pos.lnum)
367 assert_equal(1, pos.col)
368
369 var instr = execute('disassemble TextPosition.new')
370 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000371 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000372 '\d PUSHNR 1\_s*' ..
373 '\d STORE_THIS 0\_s*' ..
374 '\d PUSHNR 1\_s*' ..
375 '\d STORE_THIS 1\_s*' ..
376 'this.lnum = lnum\_s*' ..
377 '\d LOAD arg\[-1]\_s*' ..
378 '\d PUSHNR 0\_s*' ..
379 '\d LOAD $0\_s*' ..
380 '\d\+ STOREINDEX object\_s*' ..
381 '\d\+ RETURN object.*',
382 instr)
383 END
384 v9.CheckScriptSuccess(lines)
385enddef
386
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000387def Test_member_any_used_as_object()
388 var lines =<< trim END
389 vim9script
390
391 class Inner
392 this.value: number = 0
393 endclass
394
395 class Outer
396 this.inner: any
397 endclass
398
399 def F(outer: Outer)
400 outer.inner.value = 1
401 enddef
402
403 var inner_obj = Inner.new(0)
404 var outer_obj = Outer.new(inner_obj)
405 F(outer_obj)
406 assert_equal(1, inner_obj.value)
407 END
408 v9.CheckScriptSuccess(lines)
409
410 lines =<< trim END
411 vim9script
412
413 class Inner
414 this.value: number = 0
415 endclass
416
417 class Outer
418 this.inner: Inner
419 endclass
420
421 def F(outer: Outer)
422 outer.inner.value = 1
423 enddef
424
425 def Test_assign_to_nested_typed_member()
426 var inner = Inner.new(0)
427 var outer = Outer.new(inner)
428 F(outer)
429 assert_equal(1, inner.value)
430 enddef
431
432 Test_assign_to_nested_typed_member()
433 END
434 v9.CheckScriptSuccess(lines)
435enddef
436
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000437def Test_assignment_with_operator()
438 var lines =<< trim END
439 vim9script
440
441 class Foo
442 this.x: number
443
444 def Add(n: number)
445 this.x += n
446 enddef
447 endclass
448
449 var f = Foo.new(3)
450 f.Add(17)
451 assert_equal(20, f.x)
Bram Moolenaar22363c62023-04-24 17:15:25 +0100452
453 def AddToFoo(obj: Foo)
454 obj.x += 3
455 enddef
456
457 AddToFoo(f)
458 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000459 END
460 v9.CheckScriptSuccess(lines)
461enddef
462
Bram Moolenaarf4508042023-01-15 16:54:57 +0000463def Test_list_of_objects()
464 var lines =<< trim END
465 vim9script
466
467 class Foo
468 def Add()
469 enddef
470 endclass
471
472 def ProcessList(fooList: list<Foo>)
473 for foo in fooList
474 foo.Add()
475 endfor
476 enddef
477
478 var l: list<Foo> = [Foo.new()]
479 ProcessList(l)
480 END
481 v9.CheckScriptSuccess(lines)
482enddef
483
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000484def Test_expr_after_using_object()
485 var lines =<< trim END
486 vim9script
487
488 class Something
489 this.label: string = ''
490 endclass
491
492 def Foo(): Something
493 var v = Something.new()
494 echo 'in Foo(): ' .. typename(v)
495 return v
496 enddef
497
498 Foo()
499 END
500 v9.CheckScriptSuccess(lines)
501enddef
502
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000503def Test_class_default_new()
504 var lines =<< trim END
505 vim9script
506
507 class TextPosition
508 this.lnum: number = 1
509 this.col: number = 1
510 endclass
511
512 var pos = TextPosition.new()
513 assert_equal(1, pos.lnum)
514 assert_equal(1, pos.col)
515
516 pos = TextPosition.new(v:none, v:none)
517 assert_equal(1, pos.lnum)
518 assert_equal(1, pos.col)
519
520 pos = TextPosition.new(3, 22)
521 assert_equal(3, pos.lnum)
522 assert_equal(22, pos.col)
523
524 pos = TextPosition.new(v:none, 33)
525 assert_equal(1, pos.lnum)
526 assert_equal(33, pos.col)
527 END
528 v9.CheckScriptSuccess(lines)
529
530 lines =<< trim END
531 vim9script
532 class Person
533 this.name: string
534 this.age: number = 42
535 this.education: string = "unknown"
536
537 def new(this.name, this.age = v:none, this.education = v:none)
538 enddef
539 endclass
540
541 var piet = Person.new("Piet")
542 assert_equal("Piet", piet.name)
543 assert_equal(42, piet.age)
544 assert_equal("unknown", piet.education)
545
546 var chris = Person.new("Chris", 4, "none")
547 assert_equal("Chris", chris.name)
548 assert_equal(4, chris.age)
549 assert_equal("none", chris.education)
550 END
551 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000552
553 lines =<< trim END
554 vim9script
555 class Person
556 this.name: string
557 this.age: number = 42
558 this.education: string = "unknown"
559
560 def new(this.name, this.age = v:none, this.education = v:none)
561 enddef
562 endclass
563
564 var missing = Person.new()
565 END
566 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000567enddef
568
h-east2261c892023-08-16 21:49:54 +0900569
570def Test_class_new_with_object_member()
571 var lines =<< trim END
572 vim9script
573
574 class C
575 this.str: string
576 this.num: number
577 def new(this.str, this.num)
578 enddef
579 def newVals(this.str, this.num)
580 enddef
581 endclass
582
583 def Check()
584 try
585 var c = C.new('cats', 2)
586 assert_equal('cats', c.str)
587 assert_equal(2, c.num)
588
589 c = C.newVals('dogs', 4)
590 assert_equal('dogs', c.str)
591 assert_equal(4, c.num)
592 catch
593 assert_report($'Unexpected exception was caught: {v:exception}')
594 endtry
595 enddef
596
597 Check()
598 END
599 v9.CheckScriptSuccess(lines)
600
601 lines =<< trim END
602 vim9script
603
604 class C
605 this.str: string
606 this.num: number
607 def new(this.str, this.num)
608 enddef
609 endclass
610
611 def Check()
612 try
613 var c = C.new(1, 2)
614 catch
615 assert_report($'Unexpected exception was caught: {v:exception}')
616 endtry
617 enddef
618
619 Check()
620 END
621 v9.CheckScriptFailure(lines, 'E1013:')
622
623 lines =<< trim END
624 vim9script
625
626 class C
627 this.str: string
628 this.num: number
629 def newVals(this.str, this.num)
630 enddef
631 endclass
632
633 def Check()
634 try
635 var c = C.newVals('dogs', 'apes')
636 catch
637 assert_report($'Unexpected exception was caught: {v:exception}')
638 endtry
639 enddef
640
641 Check()
642 END
643 v9.CheckScriptFailure(lines, 'E1013:')
644enddef
645
Bram Moolenaar74e12742022-12-13 21:14:28 +0000646def Test_class_object_member_inits()
647 var lines =<< trim END
648 vim9script
649 class TextPosition
650 this.lnum: number
651 this.col = 1
652 this.addcol: number = 2
653 endclass
654
655 var pos = TextPosition.new()
656 assert_equal(0, pos.lnum)
657 assert_equal(1, pos.col)
658 assert_equal(2, pos.addcol)
659 END
660 v9.CheckScriptSuccess(lines)
661
662 lines =<< trim END
663 vim9script
664 class TextPosition
665 this.lnum
666 this.col = 1
667 endclass
668 END
669 v9.CheckScriptFailure(lines, 'E1022:')
670
671 lines =<< trim END
672 vim9script
673 class TextPosition
674 this.lnum = v:none
675 this.col = 1
676 endclass
677 END
678 v9.CheckScriptFailure(lines, 'E1330:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200679
680 # Test for initializing an object member with an unknown variable/type
681 lines =<< trim END
682 vim9script
683 class A
684 this.value = init_val
685 endclass
686 END
687 v9.CheckScriptFailureList(lines, ['E121:', 'E1329:'])
Bram Moolenaar74e12742022-12-13 21:14:28 +0000688enddef
689
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000690def Test_class_object_member_access()
691 var lines =<< trim END
692 vim9script
693 class Triple
694 this._one = 1
695 this.two = 2
696 public this.three = 3
697
698 def GetOne(): number
699 return this._one
700 enddef
701 endclass
702
703 var trip = Triple.new()
704 assert_equal(1, trip.GetOne())
705 assert_equal(2, trip.two)
706 assert_equal(3, trip.three)
707 assert_fails('echo trip._one', 'E1333')
708
709 assert_fails('trip._one = 11', 'E1333')
710 assert_fails('trip.two = 22', 'E1335')
711 trip.three = 33
712 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000713
714 assert_fails('trip.four = 4', 'E1334')
715 END
716 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000717
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200718 # Test for a public member variable name beginning with an underscore
719 lines =<< trim END
720 vim9script
721 class A
722 public this._val = 10
723 endclass
724 END
725 v9.CheckScriptFailure(lines, 'E1332:')
726
Bram Moolenaar590162c2022-12-24 21:24:06 +0000727 lines =<< trim END
728 vim9script
729
730 class MyCar
731 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000732 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000733
734 def new(make_arg: string)
735 this.make = make_arg
736 enddef
737
738 def GetMake(): string
739 return $"make = {this.make}"
740 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000741 def GetAge(): number
742 return this.age
743 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000744 endclass
745
746 var c = MyCar.new("abc")
747 assert_equal('make = abc', c.GetMake())
748
749 c = MyCar.new("def")
750 assert_equal('make = def', c.GetMake())
751
752 var c2 = MyCar.new("123")
753 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000754
755 def CheckCar()
756 assert_equal("make = def", c.GetMake())
757 assert_equal(5, c.GetAge())
758 enddef
759 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000760 END
761 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000762
763 lines =<< trim END
764 vim9script
765
766 class MyCar
767 this.make: string
768
769 def new(make_arg: string)
770 this.make = make_arg
771 enddef
772 endclass
773
774 var c = MyCar.new("abc")
775 var c = MyCar.new("def")
776 END
777 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000778
779 lines =<< trim END
780 vim9script
781
782 class Foo
783 this.x: list<number> = []
784
785 def Add(n: number): any
786 this.x->add(n)
787 return this
788 enddef
789 endclass
790
791 echo Foo.new().Add(1).Add(2).x
792 echo Foo.new().Add(1).Add(2)
793 .x
794 echo Foo.new().Add(1)
795 .Add(2).x
796 echo Foo.new()
797 .Add(1).Add(2).x
798 echo Foo.new()
799 .Add(1)
800 .Add(2)
801 .x
802 END
803 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200804
805 # Test for "public" cannot be abbreviated
806 lines =<< trim END
807 vim9script
808 class Something
809 pub this.val = 1
810 endclass
811 END
812 v9.CheckScriptFailure(lines, 'E1065:')
813
814 # Test for "public" keyword must be followed by "this" or "static".
815 lines =<< trim END
816 vim9script
817 class Something
818 public val = 1
819 endclass
820 END
821 v9.CheckScriptFailure(lines, 'E1331:')
822
823 # Test for "static" cannot be abbreviated
824 lines =<< trim END
825 vim9script
826 class Something
827 stat this.val = 1
828 endclass
829 END
830 v9.CheckScriptFailure(lines, 'E1065:')
Bram Moolenaard505d172022-12-18 21:42:55 +0000831enddef
832
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000833def Test_class_object_compare()
834 var class_lines =<< trim END
835 vim9script
836 class Item
837 this.nr = 0
838 this.name = 'xx'
839 endclass
840 END
841
842 # used at the script level and in a compiled function
843 var test_lines =<< trim END
844 var i1 = Item.new()
845 assert_equal(i1, i1)
846 assert_true(i1 is i1)
847 var i2 = Item.new()
848 assert_equal(i1, i2)
849 assert_false(i1 is i2)
850 var i3 = Item.new(0, 'xx')
851 assert_equal(i1, i3)
852
853 var io1 = Item.new(1, 'xx')
854 assert_notequal(i1, io1)
855 var io2 = Item.new(0, 'yy')
856 assert_notequal(i1, io2)
857 END
858
859 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000860 v9.CheckScriptSuccess(
861 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000862
863 for op in ['>', '>=', '<', '<=', '=~', '!~']
864 var op_lines = [
865 'var i1 = Item.new()',
866 'var i2 = Item.new()',
867 'echo i1 ' .. op .. ' i2',
868 ]
869 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000870 v9.CheckScriptFailure(class_lines
871 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000872 endfor
873enddef
874
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000875def Test_object_type()
876 var lines =<< trim END
877 vim9script
878
879 class One
880 this.one = 1
881 endclass
882 class Two
883 this.two = 2
884 endclass
885 class TwoMore extends Two
886 this.more = 9
887 endclass
888
889 var o: One = One.new()
890 var t: Two = Two.new()
891 var m: TwoMore = TwoMore.new()
892 var tm: Two = TwoMore.new()
893
894 t = m
895 END
896 v9.CheckScriptSuccess(lines)
897
898 lines =<< trim END
899 vim9script
900
901 class One
902 this.one = 1
903 endclass
904 class Two
905 this.two = 2
906 endclass
907
908 var o: One = Two.new()
909 END
910 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000911
912 lines =<< trim END
913 vim9script
914
915 interface One
916 def GetMember(): number
917 endinterface
918 class Two implements One
919 this.one = 1
920 def GetMember(): number
921 return this.one
922 enddef
923 endclass
924
925 var o: One = Two.new(5)
926 assert_equal(5, o.GetMember())
927 END
928 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000929
930 lines =<< trim END
931 vim9script
932
933 class Num
934 this.n: number = 0
935 endclass
936
937 def Ref(name: string): func(Num): Num
938 return (arg: Num): Num => {
939 return eval(name)(arg)
940 }
941 enddef
942
943 const Fn = Ref('Double')
944 var Double = (m: Num): Num => Num.new(m.n * 2)
945
946 echo Fn(Num.new(4))
947 END
948 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000949enddef
950
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000951def Test_class_member()
952 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000953 var lines =<< trim END
954 vim9script
955 class TextPos
956 this.lnum = 1
957 this.col = 1
958 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000959 static _secret = 7
960 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000961
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000962 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000963 counter += nr
964 enddef
965 endclass
966
967 assert_equal(0, TextPos.counter)
968 TextPos.AddToCounter(3)
969 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000970 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000971
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000972 def GetCounter(): number
973 return TextPos.counter
974 enddef
975 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000976
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000977 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000978 assert_fails('TextPos.counter = 5', 'E1335:')
979 assert_fails('TextPos.counter += 5', 'E1335:')
980
981 assert_fails('echo TextPos._secret', 'E1333:')
982 assert_fails('TextPos._secret = 8', 'E1333:')
983
984 assert_equal(42, TextPos.anybody)
985 TextPos.anybody = 12
986 assert_equal(12, TextPos.anybody)
987 TextPos.anybody += 5
988 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000989 END
990 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000991
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000992 # example in the help
993 lines =<< trim END
994 vim9script
995 class OtherThing
996 this.size: number
997 static totalSize: number
998
999 def new(this.size)
1000 totalSize += this.size
1001 enddef
1002 endclass
1003 assert_equal(0, OtherThing.totalSize)
1004 var to3 = OtherThing.new(3)
1005 assert_equal(3, OtherThing.totalSize)
1006 var to7 = OtherThing.new(7)
1007 assert_equal(10, OtherThing.totalSize)
1008 END
1009 v9.CheckScriptSuccess(lines)
1010
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001011 # using static class member twice
1012 lines =<< trim END
1013 vim9script
1014
1015 class HTML
1016 static author: string = 'John Doe'
1017
1018 static def MacroSubstitute(s: string): string
1019 return substitute(s, '{{author}}', author, 'gi')
1020 enddef
1021 endclass
1022
1023 assert_equal('some text', HTML.MacroSubstitute('some text'))
1024 assert_equal('some text', HTML.MacroSubstitute('some text'))
1025 END
1026 v9.CheckScriptSuccess(lines)
1027
Bram Moolenaar62a69232023-01-24 15:07:04 +00001028 # access private member in lambda
1029 lines =<< trim END
1030 vim9script
1031
1032 class Foo
1033 this._x: number = 0
1034
1035 def Add(n: number): number
1036 const F = (): number => this._x + n
1037 return F()
1038 enddef
1039 endclass
1040
1041 var foo = Foo.new()
1042 assert_equal(5, foo.Add(5))
1043 END
1044 v9.CheckScriptSuccess(lines)
1045
h-east2bd6a092023-05-19 19:01:17 +01001046 # access private member in lambda body
1047 lines =<< trim END
1048 vim9script
1049
1050 class Foo
1051 this._x: number = 6
1052
1053 def Add(n: number): number
1054 var Lam = () => {
1055 this._x = this._x + n
1056 }
1057 Lam()
1058 return this._x
1059 enddef
1060 endclass
1061
1062 var foo = Foo.new()
1063 assert_equal(13, foo.Add(7))
1064 END
1065 v9.CheckScriptSuccess(lines)
1066
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001067 # check shadowing
1068 lines =<< trim END
1069 vim9script
1070
1071 class Some
1072 static count = 0
1073 def Method(count: number)
1074 echo count
1075 enddef
1076 endclass
1077
1078 var s = Some.new()
1079 s.Method(7)
1080 END
1081 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
1082
1083 lines =<< trim END
1084 vim9script
1085
1086 class Some
1087 static count = 0
1088 def Method(arg: number)
1089 var count = 3
1090 echo arg count
1091 enddef
1092 endclass
1093
1094 var s = Some.new()
1095 s.Method(7)
1096 END
1097 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001098
1099 # Test for using an invalid type for a member variable
1100 lines =<< trim END
1101 vim9script
1102 class A
1103 this.val: xxx
1104 endclass
1105 END
1106 v9.CheckScriptFailure(lines, 'E1010:')
1107
1108 # Test for no space before or after the '=' when initializing a member
1109 # variable
1110 lines =<< trim END
1111 vim9script
1112 class A
1113 this.val: number= 10
1114 endclass
1115 END
1116 v9.CheckScriptFailure(lines, 'E1004:')
1117 lines =<< trim END
1118 vim9script
1119 class A
1120 this.val: number =10
1121 endclass
1122 END
1123 v9.CheckScriptFailure(lines, 'E1004:')
1124
1125 # Access a non-existing member
1126 lines =<< trim END
1127 vim9script
1128 class A
1129 endclass
1130 var a = A.new()
1131 var v = a.bar
1132 END
1133 v9.CheckScriptFailure(lines, 'E1326:')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001134enddef
1135
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001136func Test_class_garbagecollect()
1137 let lines =<< trim END
1138 vim9script
1139
1140 class Point
1141 this.p = [2, 3]
1142 static pl = ['a', 'b']
1143 static pd = {a: 'a', b: 'b'}
1144 endclass
1145
1146 echo Point.pl Point.pd
1147 call test_garbagecollect_now()
1148 echo Point.pl Point.pd
1149 END
1150 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001151
1152 let lines =<< trim END
1153 vim9script
1154
1155 interface View
1156 endinterface
1157
1158 class Widget
1159 this.view: View
1160 endclass
1161
1162 class MyView implements View
1163 this.widget: Widget
1164
1165 def new()
1166 # this will result in a circular reference to this object
1167 this.widget = Widget.new(this)
1168 enddef
1169 endclass
1170
1171 var view = MyView.new()
1172
1173 # overwrite "view", will be garbage-collected next
1174 view = MyView.new()
1175 test_garbagecollect_now()
1176 END
1177 call v9.CheckScriptSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001178endfunc
1179
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001180def Test_class_function()
1181 var lines =<< trim END
1182 vim9script
1183 class Value
1184 this.value = 0
1185 static objects = 0
1186
1187 def new(v: number)
1188 this.value = v
1189 ++objects
1190 enddef
1191
1192 static def GetCount(): number
1193 return objects
1194 enddef
1195 endclass
1196
1197 assert_equal(0, Value.GetCount())
1198 var v1 = Value.new(2)
1199 assert_equal(1, Value.GetCount())
1200 var v2 = Value.new(7)
1201 assert_equal(2, Value.GetCount())
1202 END
1203 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001204
1205 # Test for cleaning up after a class definition failure when using class
1206 # functions.
1207 lines =<< trim END
1208 vim9script
1209 class A
1210 static def Foo()
1211 enddef
1212 aaa
1213 endclass
1214 END
1215 v9.CheckScriptFailure(lines, 'E1318:')
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001216enddef
1217
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001218def Test_class_defcompile()
1219 var lines =<< trim END
1220 vim9script
1221
1222 class C
1223 def Fo(i: number): string
1224 return i
1225 enddef
1226 endclass
1227
1228 defcompile C.Fo
1229 END
1230 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
1231
1232 lines =<< trim END
1233 vim9script
1234
1235 class C
1236 static def Fc(): number
1237 return 'x'
1238 enddef
1239 endclass
1240
1241 defcompile C.Fc
1242 END
1243 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001244
1245 # Trying to compile a function using a non-existing class variable
1246 lines =<< trim END
1247 vim9script
1248 defcompile x.Foo()
1249 END
1250 v9.CheckScriptFailure(lines, 'E475:')
1251
1252 # Trying to compile a function using a variable which is not a class
1253 lines =<< trim END
1254 vim9script
1255 var x: number
1256 defcompile x.Foo()
1257 END
1258 v9.CheckScriptFailure(lines, 'E475:')
1259
1260 # Trying to compile a function without specifying the name
1261 lines =<< trim END
1262 vim9script
1263 class A
1264 endclass
1265 defcompile A.
1266 END
1267 v9.CheckScriptFailure(lines, 'E475:')
1268
1269 # Trying to compile a non-existing class object member function
1270 lines =<< trim END
1271 vim9script
1272 class A
1273 endclass
1274 var a = A.new()
1275 defcompile a.Foo()
1276 END
1277 v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001278enddef
1279
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001280def Test_class_object_to_string()
1281 var lines =<< trim END
1282 vim9script
1283 class TextPosition
1284 this.lnum = 1
1285 this.col = 22
1286 endclass
1287
1288 assert_equal("class TextPosition", string(TextPosition))
1289
1290 var pos = TextPosition.new()
1291 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
1292 END
1293 v9.CheckScriptSuccess(lines)
1294enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001295
Bram Moolenaar554d0312023-01-05 19:59:18 +00001296def Test_interface_basics()
1297 var lines =<< trim END
1298 vim9script
1299 interface Something
1300 this.value: string
1301 static count: number
1302 def GetCount(): number
1303 endinterface
1304 END
1305 v9.CheckScriptSuccess(lines)
1306
1307 lines =<< trim END
1308 interface SomethingWrong
1309 static count = 7
1310 endinterface
1311 END
1312 v9.CheckScriptFailure(lines, 'E1342:')
1313
1314 lines =<< trim END
1315 vim9script
1316
1317 interface Some
1318 static count: number
1319 def Method(count: number)
1320 endinterface
1321 END
h-east61378a12023-04-18 19:07:29 +01001322 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001323
1324 lines =<< trim END
1325 vim9script
1326
1327 interface Some
1328 this.value: number
1329 def Method(value: number)
1330 endinterface
1331 END
h-east61378a12023-04-18 19:07:29 +01001332 # The argument name and the object member name are the same, but this is not a
1333 # problem because object members are always accessed with the "this." prefix.
1334 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001335
1336 lines =<< trim END
1337 vim9script
1338 interface somethingWrong
1339 static count = 7
1340 endinterface
1341 END
1342 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1343
1344 lines =<< trim END
1345 vim9script
1346 interface SomethingWrong
1347 this.value: string
1348 static count = 7
1349 def GetCount(): number
1350 endinterface
1351 END
1352 v9.CheckScriptFailure(lines, 'E1344:')
1353
1354 lines =<< trim END
1355 vim9script
1356 interface SomethingWrong
1357 this.value: string
1358 static count: number
1359 def GetCount(): number
1360 return 5
1361 enddef
1362 endinterface
1363 END
1364 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001365
1366 lines =<< trim END
1367 vim9script
1368 export interface EnterExit
1369 def Enter(): void
1370 def Exit(): void
1371 endinterface
1372 END
1373 writefile(lines, 'XdefIntf.vim', 'D')
1374
1375 lines =<< trim END
1376 vim9script
1377 import './XdefIntf.vim' as defIntf
1378 export def With(ee: defIntf.EnterExit, F: func)
1379 ee.Enter()
1380 try
1381 F()
1382 finally
1383 ee.Exit()
1384 endtry
1385 enddef
1386 END
1387 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001388
1389 var imported =<< trim END
1390 vim9script
1391 export abstract class EnterExit
1392 def Enter(): void
1393 enddef
1394 def Exit(): void
1395 enddef
1396 endclass
1397 END
1398 writefile(imported, 'XdefIntf2.vim', 'D')
1399
1400 lines[1] = " import './XdefIntf2.vim' as defIntf"
1401 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001402enddef
1403
Bram Moolenaar94674f22023-01-06 18:42:20 +00001404def Test_class_implements_interface()
1405 var lines =<< trim END
1406 vim9script
1407
1408 interface Some
1409 static count: number
1410 def Method(nr: number)
1411 endinterface
1412
1413 class SomeImpl implements Some
1414 static count: number
1415 def Method(nr: number)
1416 echo nr
1417 enddef
1418 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001419
1420 interface Another
1421 this.member: string
1422 endinterface
1423
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001424 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001425 this.member = 'abc'
1426 static count: number
1427 def Method(nr: number)
1428 echo nr
1429 enddef
1430 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001431 END
1432 v9.CheckScriptSuccess(lines)
1433
1434 lines =<< trim END
1435 vim9script
1436
1437 interface Some
1438 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001439 endinterface
1440
1441 class SomeImpl implements Some implements Some
1442 static count: number
1443 endclass
1444 END
1445 v9.CheckScriptFailure(lines, 'E1350:')
1446
1447 lines =<< trim END
1448 vim9script
1449
1450 interface Some
1451 static counter: number
1452 endinterface
1453
1454 class SomeImpl implements Some, Some
1455 static count: number
1456 endclass
1457 END
1458 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1459
1460 lines =<< trim END
1461 vim9script
1462
1463 interface Some
1464 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001465 def Method(nr: number)
1466 endinterface
1467
1468 class SomeImpl implements Some
1469 static count: number
1470 def Method(nr: number)
1471 echo nr
1472 enddef
1473 endclass
1474 END
1475 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1476
1477 lines =<< trim END
1478 vim9script
1479
1480 interface Some
1481 static count: number
1482 def Methods(nr: number)
1483 endinterface
1484
1485 class SomeImpl implements Some
1486 static count: number
1487 def Method(nr: number)
1488 echo nr
1489 enddef
1490 endclass
1491 END
1492 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001493
1494 # Check different order of members in class and interface works.
1495 lines =<< trim END
1496 vim9script
1497
1498 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001499 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001500 this.errpos: number
1501 endinterface
1502
1503 # order of members is opposite of interface
1504 class Failure implements Result
1505 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001506 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001507 endclass
1508
1509 def Test()
1510 var result: Result = Failure.new()
1511
1512 assert_equal('label', result.label)
1513 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001514
1515 result.label = 'different'
1516 assert_equal('different', result.label)
1517 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001518 enddef
1519
1520 Test()
1521 END
1522 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001523
1524 # Interface name after "extends" doesn't end in a space or NUL character
1525 lines =<< trim END
1526 vim9script
1527 interface A
1528 endinterface
1529 class B extends A"
1530 endclass
1531 END
1532 v9.CheckScriptFailure(lines, 'E1315:')
1533
1534 # Trailing characters after a class name
1535 lines =<< trim END
1536 vim9script
1537 class A bbb
1538 endclass
1539 END
1540 v9.CheckScriptFailure(lines, 'E488:')
1541
1542 # using "implements" with a non-existing class
1543 lines =<< trim END
1544 vim9script
1545 class A implements B
1546 endclass
1547 END
1548 v9.CheckScriptFailure(lines, 'E1346:')
1549
1550 # using "implements" with a regular class
1551 lines =<< trim END
1552 vim9script
1553 class A
1554 endclass
1555 class B implements A
1556 endclass
1557 END
1558 v9.CheckScriptFailure(lines, 'E1347:')
1559
1560 # using "implements" with a variable
1561 lines =<< trim END
1562 vim9script
1563 var T: number = 10
1564 class A implements T
1565 endclass
1566 END
1567 v9.CheckScriptFailure(lines, 'E1347:')
1568
1569 # all the class methods in an "interface" should be implemented
1570 lines =<< trim END
1571 vim9script
1572 interface A
1573 static def Foo()
1574 endinterface
1575 class B implements A
1576 endclass
1577 END
1578 v9.CheckScriptFailure(lines, 'E1349:')
LemonBoyc5d27442023-08-19 13:02:35 +02001579
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02001580 # implements should be followed by a white space
1581 lines =<< trim END
1582 vim9script
1583 interface A
1584 endinterface
1585 class B implements A;
1586 endclass
1587 END
1588 v9.CheckScriptFailure(lines, 'E1315:')
1589
LemonBoyc5d27442023-08-19 13:02:35 +02001590 lines =<< trim END
1591 vim9script
1592
1593 interface One
1594 static matching: bool
1595 static as_any: any
1596 static not_matching: number
1597 endinterface
1598 class Two implements One
1599 static not_matching: string
1600 static as_any: string
1601 static matching: bool
1602 endclass
1603 END
1604 v9.CheckScriptFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
1605
1606 lines =<< trim END
1607 vim9script
1608
1609 interface One
1610 def IsEven(nr: number): bool
1611 endinterface
1612 class Two implements One
1613 def IsEven(nr: number): string
1614 enddef
1615 endclass
1616 END
1617 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number): string')
1618
1619 lines =<< trim END
1620 vim9script
1621
1622 interface One
1623 def IsEven(nr: number): bool
1624 endinterface
1625 class Two implements One
1626 def IsEven(nr: bool): bool
1627 enddef
1628 endclass
1629 END
1630 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
1631
1632 lines =<< trim END
1633 vim9script
1634
1635 interface One
1636 def IsEven(nr: number): bool
1637 endinterface
1638 class Two implements One
1639 def IsEven(nr: number, ...extra: list<number>): bool
1640 enddef
1641 endclass
1642 END
1643 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
Bram Moolenaar94674f22023-01-06 18:42:20 +00001644enddef
1645
Bram Moolenaard0200c82023-01-28 15:19:40 +00001646def Test_call_interface_method()
1647 var lines =<< trim END
1648 vim9script
1649 interface Base
1650 def Enter(): void
1651 endinterface
1652
1653 class Child implements Base
1654 def Enter(): void
1655 g:result ..= 'child'
1656 enddef
1657 endclass
1658
1659 def F(obj: Base)
1660 obj.Enter()
1661 enddef
1662
1663 g:result = ''
1664 F(Child.new())
1665 assert_equal('child', g:result)
1666 unlet g:result
1667 END
1668 v9.CheckScriptSuccess(lines)
1669
1670 lines =<< trim END
1671 vim9script
1672 class Base
1673 def Enter(): void
1674 g:result ..= 'base'
1675 enddef
1676 endclass
1677
1678 class Child extends Base
1679 def Enter(): void
1680 g:result ..= 'child'
1681 enddef
1682 endclass
1683
1684 def F(obj: Base)
1685 obj.Enter()
1686 enddef
1687
1688 g:result = ''
1689 F(Child.new())
1690 assert_equal('child', g:result)
1691 unlet g:result
1692 END
1693 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001694
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001695 # method of interface returns a value
1696 lines =<< trim END
1697 vim9script
1698 interface Base
1699 def Enter(): string
1700 endinterface
1701
1702 class Child implements Base
1703 def Enter(): string
1704 g:result ..= 'child'
1705 return "/resource"
1706 enddef
1707 endclass
1708
1709 def F(obj: Base)
1710 var r = obj.Enter()
1711 g:result ..= r
1712 enddef
1713
1714 g:result = ''
1715 F(Child.new())
1716 assert_equal('child/resource', g:result)
1717 unlet g:result
1718 END
1719 v9.CheckScriptSuccess(lines)
1720
1721 lines =<< trim END
1722 vim9script
1723 class Base
1724 def Enter(): string
1725 return null_string
1726 enddef
1727 endclass
1728
1729 class Child extends Base
1730 def Enter(): string
1731 g:result ..= 'child'
1732 return "/resource"
1733 enddef
1734 endclass
1735
1736 def F(obj: Base)
1737 var r = obj.Enter()
1738 g:result ..= r
1739 enddef
1740
1741 g:result = ''
1742 F(Child.new())
1743 assert_equal('child/resource', g:result)
1744 unlet g:result
1745 END
1746 v9.CheckScriptSuccess(lines)
1747
1748
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001749 # No class that implements the interface.
1750 lines =<< trim END
1751 vim9script
1752
1753 interface IWithEE
1754 def Enter(): any
1755 def Exit(): void
1756 endinterface
1757
1758 def With1(ee: IWithEE, F: func)
1759 var r = ee.Enter()
1760 enddef
1761
1762 defcompile
1763 END
1764 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001765enddef
1766
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001767def Test_class_used_as_type()
1768 var lines =<< trim END
1769 vim9script
1770
1771 class Point
1772 this.x = 0
1773 this.y = 0
1774 endclass
1775
1776 var p: Point
1777 p = Point.new(2, 33)
1778 assert_equal(2, p.x)
1779 assert_equal(33, p.y)
1780 END
1781 v9.CheckScriptSuccess(lines)
1782
1783 lines =<< trim END
1784 vim9script
1785
1786 interface HasX
1787 this.x: number
1788 endinterface
1789
1790 class Point implements HasX
1791 this.x = 0
1792 this.y = 0
1793 endclass
1794
1795 var p: Point
1796 p = Point.new(2, 33)
1797 var hx = p
1798 assert_equal(2, hx.x)
1799 END
1800 v9.CheckScriptSuccess(lines)
1801
1802 lines =<< trim END
1803 vim9script
1804
1805 class Point
1806 this.x = 0
1807 this.y = 0
1808 endclass
1809
1810 var p: Point
1811 p = 'text'
1812 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001813 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001814enddef
1815
Bram Moolenaar83677162023-01-08 19:54:10 +00001816def Test_class_extends()
1817 var lines =<< trim END
1818 vim9script
1819 class Base
1820 this.one = 1
1821 def GetOne(): number
1822 return this.one
1823 enddef
1824 endclass
1825 class Child extends Base
1826 this.two = 2
1827 def GetTotal(): number
1828 return this.one + this.two
1829 enddef
1830 endclass
1831 var o = Child.new()
1832 assert_equal(1, o.one)
1833 assert_equal(2, o.two)
1834 assert_equal(1, o.GetOne())
1835 assert_equal(3, o.GetTotal())
1836 END
1837 v9.CheckScriptSuccess(lines)
1838
1839 lines =<< trim END
1840 vim9script
1841 class Base
1842 this.one = 1
1843 endclass
1844 class Child extends Base
1845 this.two = 2
1846 endclass
1847 var o = Child.new(3, 44)
1848 assert_equal(3, o.one)
1849 assert_equal(44, o.two)
1850 END
1851 v9.CheckScriptSuccess(lines)
1852
1853 lines =<< trim END
1854 vim9script
1855 class Base
1856 this.one = 1
1857 endclass
1858 class Child extends Base extends Base
1859 this.two = 2
1860 endclass
1861 END
1862 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1863
1864 lines =<< trim END
1865 vim9script
1866 class Child extends BaseClass
1867 this.two = 2
1868 endclass
1869 END
1870 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1871
1872 lines =<< trim END
1873 vim9script
1874 var SomeVar = 99
1875 class Child extends SomeVar
1876 this.two = 2
1877 endclass
1878 END
1879 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001880
1881 lines =<< trim END
1882 vim9script
1883 class Base
1884 this.name: string
1885 def ToString(): string
1886 return this.name
1887 enddef
1888 endclass
1889
1890 class Child extends Base
1891 this.age: number
1892 def ToString(): string
1893 return super.ToString() .. ': ' .. this.age
1894 enddef
1895 endclass
1896
1897 var o = Child.new('John', 42)
1898 assert_equal('John: 42', o.ToString())
1899 END
1900 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001901
1902 lines =<< trim END
1903 vim9script
1904 class Child
1905 this.age: number
1906 def ToString(): number
1907 return this.age
1908 enddef
1909 def ToString(): string
1910 return this.age
1911 enddef
1912 endclass
1913 END
1914 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1915
1916 lines =<< trim END
1917 vim9script
1918 class Child
1919 this.age: number
1920 def ToString(): string
1921 return super .ToString() .. ': ' .. this.age
1922 enddef
1923 endclass
1924 var o = Child.new(42)
1925 echo o.ToString()
1926 END
1927 v9.CheckScriptFailure(lines, 'E1356:')
1928
1929 lines =<< trim END
1930 vim9script
1931 class Base
1932 this.name: string
1933 def ToString(): string
1934 return this.name
1935 enddef
1936 endclass
1937
1938 var age = 42
1939 def ToString(): string
1940 return super.ToString() .. ': ' .. age
1941 enddef
1942 echo ToString()
1943 END
1944 v9.CheckScriptFailure(lines, 'E1357:')
1945
1946 lines =<< trim END
1947 vim9script
1948 class Child
1949 this.age: number
1950 def ToString(): string
1951 return super.ToString() .. ': ' .. this.age
1952 enddef
1953 endclass
1954 var o = Child.new(42)
1955 echo o.ToString()
1956 END
1957 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001958
1959 lines =<< trim END
1960 vim9script
1961 class Base
1962 this.name: string
1963 static def ToString(): string
1964 return 'Base class'
1965 enddef
1966 endclass
1967
1968 class Child extends Base
1969 this.age: number
1970 def ToString(): string
1971 return Base.ToString() .. ': ' .. this.age
1972 enddef
1973 endclass
1974
1975 var o = Child.new('John', 42)
1976 assert_equal('Base class: 42', o.ToString())
1977 END
1978 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001979
1980 lines =<< trim END
1981 vim9script
1982 class Base
1983 this.value = 1
1984 def new(init: number)
1985 this.value = number + 1
1986 enddef
1987 endclass
1988 class Child extends Base
1989 def new()
1990 this.new(3)
1991 enddef
1992 endclass
1993 var c = Child.new()
1994 END
1995 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001996
1997 # base class with more than one object member
1998 lines =<< trim END
1999 vim9script
2000
2001 class Result
2002 this.success: bool
2003 this.value: any = null
2004 endclass
2005
2006 class Success extends Result
2007 def new(this.value = v:none)
2008 this.success = true
2009 enddef
2010 endclass
2011
2012 var v = Success.new('asdf')
2013 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
2014 END
2015 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002016
2017 # class name after "extends" doesn't end in a space or NUL character
2018 lines =<< trim END
2019 vim9script
2020 class A
2021 endclass
2022 class B extends A"
2023 endclass
2024 END
2025 v9.CheckScriptFailure(lines, 'E1315:')
Bram Moolenaar83677162023-01-08 19:54:10 +00002026enddef
2027
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002028def Test_using_base_class()
2029 var lines =<< trim END
2030 vim9script
2031
2032 class BaseEE
2033 def Enter(): any
2034 return null
2035 enddef
2036 def Exit(resource: any): void
2037 enddef
2038 endclass
2039
2040 class ChildEE extends BaseEE
2041 def Enter(): any
2042 return 42
2043 enddef
2044
2045 def Exit(resource: number): void
2046 g:result ..= '/exit'
2047 enddef
2048 endclass
2049
2050 def With(ee: BaseEE)
2051 var r = ee.Enter()
2052 try
2053 g:result ..= r
2054 finally
2055 g:result ..= '/finally'
2056 ee.Exit(r)
2057 endtry
2058 enddef
2059
2060 g:result = ''
2061 With(ChildEE.new())
2062 assert_equal('42/finally/exit', g:result)
2063 END
2064 v9.CheckScriptSuccess(lines)
2065 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002066
2067 # Using super, Child invokes Base method which has optional arg. #12471
2068 lines =<< trim END
2069 vim9script
2070
2071 class Base
2072 this.success: bool = false
2073 def Method(arg = 0)
2074 this.success = true
2075 enddef
2076 endclass
2077
2078 class Child extends Base
2079 def new()
2080 super.Method()
2081 enddef
2082 endclass
2083
2084 var obj = Child.new()
2085 assert_equal(true, obj.success)
2086 END
2087 v9.CheckScriptSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002088enddef
2089
2090
Bram Moolenaara86655a2023-01-12 17:06:27 +00002091def Test_class_import()
2092 var lines =<< trim END
2093 vim9script
2094 export class Animal
2095 this.kind: string
2096 this.name: string
2097 endclass
2098 END
2099 writefile(lines, 'Xanimal.vim', 'D')
2100
2101 lines =<< trim END
2102 vim9script
2103 import './Xanimal.vim' as animal
2104
2105 var a: animal.Animal
2106 a = animal.Animal.new('fish', 'Eric')
2107 assert_equal('fish', a.kind)
2108 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002109
2110 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2111 assert_equal('cat', b.kind)
2112 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002113 END
2114 v9.CheckScriptSuccess(lines)
2115enddef
2116
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002117def Test_abstract_class()
2118 var lines =<< trim END
2119 vim9script
2120 abstract class Base
2121 this.name: string
2122 endclass
2123 class Person extends Base
2124 this.age: number
2125 endclass
2126 var p: Base = Person.new('Peter', 42)
2127 assert_equal('Peter', p.name)
2128 assert_equal(42, p.age)
2129 END
2130 v9.CheckScriptSuccess(lines)
2131
2132 lines =<< trim END
2133 vim9script
2134 abstract class Base
2135 this.name: string
2136 endclass
2137 class Person extends Base
2138 this.age: number
2139 endclass
2140 var p = Base.new('Peter')
2141 END
2142 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
2143
2144 lines =<< trim END
2145 abstract class Base
2146 this.name: string
2147 endclass
2148 END
2149 v9.CheckScriptFailure(lines, 'E1316:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002150
2151 # Abstract class cannot have a "new" function
2152 lines =<< trim END
2153 vim9script
2154 abstract class Base
2155 def new()
2156 enddef
2157 endclass
2158 END
2159 v9.CheckScriptFailure(lines, 'E1359:')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002160enddef
2161
Bram Moolenaar486fc252023-01-18 14:51:07 +00002162def Test_closure_in_class()
2163 var lines =<< trim END
2164 vim9script
2165
2166 class Foo
2167 this.y: list<string> = ['B']
2168
2169 def new()
2170 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2171 enddef
2172 endclass
2173
2174 Foo.new()
2175 assert_equal(['A'], g:result)
2176 END
2177 v9.CheckScriptSuccess(lines)
2178enddef
2179
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002180def Test_call_constructor_from_legacy()
2181 var lines =<< trim END
2182 vim9script
2183
2184 var newCalled = 'false'
2185
2186 class A
2187 def new()
2188 newCalled = 'true'
2189 enddef
2190 endclass
2191
2192 export def F(options = {}): any
2193 return A
2194 enddef
2195
2196 g:p = F()
2197 legacy call p.new()
2198 assert_equal('true', newCalled)
2199 END
2200 v9.CheckScriptSuccess(lines)
2201enddef
2202
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002203def Test_defer_with_object()
2204 var lines =<< trim END
2205 vim9script
2206
2207 class CWithEE
2208 def Enter()
2209 g:result ..= "entered/"
2210 enddef
2211 def Exit()
2212 g:result ..= "exited"
2213 enddef
2214 endclass
2215
2216 def With(ee: CWithEE, F: func)
2217 ee.Enter()
2218 defer ee.Exit()
2219 F()
2220 enddef
2221
2222 g:result = ''
2223 var obj = CWithEE.new()
2224 obj->With(() => {
2225 g:result ..= "called/"
2226 })
2227 assert_equal('entered/called/exited', g:result)
2228 END
2229 v9.CheckScriptSuccess(lines)
2230 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00002231
2232 lines =<< trim END
2233 vim9script
2234
2235 class BaseWithEE
2236 def Enter()
2237 g:result ..= "entered-base/"
2238 enddef
2239 def Exit()
2240 g:result ..= "exited-base"
2241 enddef
2242 endclass
2243
2244 class CWithEE extends BaseWithEE
2245 def Enter()
2246 g:result ..= "entered-child/"
2247 enddef
2248 def Exit()
2249 g:result ..= "exited-child"
2250 enddef
2251 endclass
2252
2253 def With(ee: BaseWithEE, F: func)
2254 ee.Enter()
2255 defer ee.Exit()
2256 F()
2257 enddef
2258
2259 g:result = ''
2260 var obj = CWithEE.new()
2261 obj->With(() => {
2262 g:result ..= "called/"
2263 })
2264 assert_equal('entered-child/called/exited-child', g:result)
2265 END
2266 v9.CheckScriptSuccess(lines)
2267 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002268enddef
2269
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002270" The following test used to crash Vim (Github issue #12676)
2271def Test_extends_method_crashes_vim()
2272 var lines =<< trim END
2273 vim9script
2274
2275 class Observer
2276 endclass
2277
2278 class Property
2279 this.value: any
2280
2281 def Set(v: any)
2282 if v != this.value
2283 this.value = v
2284 endif
2285 enddef
2286
2287 def Register(observer: Observer)
2288 enddef
2289 endclass
2290
2291 class Bool extends Property
2292 this.value: bool
2293 endclass
2294
2295 def Observe(obj: Property, who: Observer)
2296 obj.Register(who)
2297 enddef
2298
2299 var p = Bool.new(false)
2300 var myObserver = Observer.new()
2301
2302 Observe(p, myObserver)
2303
2304 p.Set(true)
2305 END
2306 v9.CheckScriptSuccess(lines)
2307enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00002308
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02002309" Test for calling a method in a class that is extended
2310def Test_call_method_in_extended_class()
2311 var lines =<< trim END
2312 vim9script
2313
2314 var prop_init_called = false
2315 var prop_register_called = false
2316
2317 class Property
2318 def Init()
2319 prop_init_called = true
2320 enddef
2321
2322 def Register()
2323 prop_register_called = true
2324 enddef
2325 endclass
2326
2327 class Bool extends Property
2328 endclass
2329
2330 def Observe(obj: Property)
2331 obj.Register()
2332 enddef
2333
2334 var p = Property.new()
2335 Observe(p)
2336
2337 p.Init()
2338 assert_true(prop_init_called)
2339 assert_true(prop_register_called)
2340 END
2341 v9.CheckScriptSuccess(lines)
2342enddef
2343
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02002344" Test for calling a method in the parent class that is extended partially.
2345" This used to fail with the 'E118: Too many arguments for function: Text' error
2346" message (Github issue #12524).
2347def Test_call_method_in_parent_class()
2348 var lines =<< trim END
2349 vim9script
2350
2351 class Widget
2352 this._lnum: number = 1
2353
2354 def SetY(lnum: number)
2355 this._lnum = lnum
2356 enddef
2357
2358 def Text(): string
2359 return ''
2360 enddef
2361 endclass
2362
2363 class Foo extends Widget
2364 def Text(): string
2365 return '<Foo>'
2366 enddef
2367 endclass
2368
2369 def Stack(w1: Widget, w2: Widget): list<Widget>
2370 w1.SetY(1)
2371 w2.SetY(2)
2372 return [w1, w2]
2373 enddef
2374
2375 var foo1 = Foo.new()
2376 var foo2 = Foo.new()
2377 var l = Stack(foo1, foo2)
2378 END
2379 v9.CheckScriptSuccess(lines)
2380enddef
2381
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002382" Test for calling methods from three levels of classes
2383def Test_multi_level_method_call()
2384 var lines =<< trim END
2385 vim9script
2386
2387 var A_func1: number = 0
2388 var A_func2: number = 0
2389 var A_func3: number = 0
2390 var B_func2: number = 0
2391 var B_func3: number = 0
2392 var C_func3: number = 0
2393
2394 class A
2395 def Func1()
2396 A_func1 += 1
2397 enddef
2398
2399 def Func2()
2400 A_func2 += 1
2401 enddef
2402
2403 def Func3()
2404 A_func3 += 1
2405 enddef
2406 endclass
2407
2408 class B extends A
2409 def Func2()
2410 B_func2 += 1
2411 enddef
2412
2413 def Func3()
2414 B_func3 += 1
2415 enddef
2416 endclass
2417
2418 class C extends B
2419 def Func3()
2420 C_func3 += 1
2421 enddef
2422 endclass
2423
2424 def A_CallFuncs(a: A)
2425 a.Func1()
2426 a.Func2()
2427 a.Func3()
2428 enddef
2429
2430 def B_CallFuncs(b: B)
2431 b.Func1()
2432 b.Func2()
2433 b.Func3()
2434 enddef
2435
2436 def C_CallFuncs(c: C)
2437 c.Func1()
2438 c.Func2()
2439 c.Func3()
2440 enddef
2441
2442 var cobj = C.new()
2443 A_CallFuncs(cobj)
2444 B_CallFuncs(cobj)
2445 C_CallFuncs(cobj)
2446 assert_equal(3, A_func1)
2447 assert_equal(0, A_func2)
2448 assert_equal(0, A_func3)
2449 assert_equal(3, B_func2)
2450 assert_equal(0, B_func3)
2451 assert_equal(3, C_func3)
2452 END
2453 v9.CheckScriptSuccess(lines)
2454enddef
2455
2456" Test for using members from three levels of classes
2457def Test_multi_level_member_access()
2458 var lines =<< trim END
2459 vim9script
2460
2461 class A
2462 this.val1: number = 0
2463 this.val2: number = 0
2464 this.val3: number = 0
2465 endclass
2466
2467 class B extends A
2468 this.val2: number = 0
2469 this.val3: number = 0
2470 endclass
2471
2472 class C extends B
2473 this.val3: number = 0
2474 endclass
2475
2476 def A_members(a: A)
2477 a.val1 += 1
2478 a.val2 += 1
2479 a.val3 += 1
2480 enddef
2481
2482 def B_members(b: B)
2483 b.val1 += 1
2484 b.val2 += 1
2485 b.val3 += 1
2486 enddef
2487
2488 def C_members(c: C)
2489 c.val1 += 1
2490 c.val2 += 1
2491 c.val3 += 1
2492 enddef
2493
2494 var cobj = C.new()
2495 A_members(cobj)
2496 B_members(cobj)
2497 C_members(cobj)
2498 assert_equal(3, cobj.val1)
2499 assert_equal(3, cobj.val2)
2500 assert_equal(3, cobj.val3)
2501 END
2502 v9.CheckScriptSuccess(lines)
2503enddef
2504
LemonBoy0ffc17a2023-08-20 18:09:11 +02002505" Test expansion of <stack> with class methods.
2506def Test_stack_expansion_with_methods()
2507 var lines =<< trim END
2508 vim9script
2509
2510 class C
2511 def M1()
2512 F0()
2513 enddef
2514 endclass
2515
2516 def F0()
2517 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
2518 enddef
2519
2520 def F()
2521 C.new().M1()
2522 enddef
2523
2524 F()
2525 END
2526 v9.CheckScriptSuccess(lines)
2527enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002528
2529" Test the return type of the new() constructor
2530def Test_new_return_type()
2531 # new() uses the default return type and there is no return statement
2532 var lines =<< trim END
2533 vim9script
2534
2535 class C
2536 this._bufnr: number
2537
2538 def new(this._bufnr)
2539 if !bufexists(this._bufnr)
2540 this._bufnr = -1
2541 endif
2542 enddef
2543 endclass
2544
2545 var c = C.new(12345)
2546 assert_equal('object<C>', typename(c))
2547
2548 var v1: C
2549 v1 = C.new(12345)
2550 assert_equal('object<C>', typename(v1))
2551
2552 def F()
2553 var v2: C
2554 v2 = C.new(12345)
2555 assert_equal('object<C>', typename(v2))
2556 enddef
2557 F()
2558 END
2559 v9.CheckScriptSuccess(lines)
2560
2561 # new() uses the default return type and an empty 'return' statement
2562 lines =<< trim END
2563 vim9script
2564
2565 class C
2566 this._bufnr: number
2567
2568 def new(this._bufnr)
2569 if !bufexists(this._bufnr)
2570 this._bufnr = -1
2571 return
2572 endif
2573 enddef
2574 endclass
2575
2576 var c = C.new(12345)
2577 assert_equal('object<C>', typename(c))
2578
2579 var v1: C
2580 v1 = C.new(12345)
2581 assert_equal('object<C>', typename(v1))
2582
2583 def F()
2584 var v2: C
2585 v2 = C.new(12345)
2586 assert_equal('object<C>', typename(v2))
2587 enddef
2588 F()
2589 END
2590 v9.CheckScriptSuccess(lines)
2591
2592 # new() uses "any" return type and returns "this"
2593 lines =<< trim END
2594 vim9script
2595
2596 class C
2597 this._bufnr: number
2598
2599 def new(this._bufnr): any
2600 if !bufexists(this._bufnr)
2601 this._bufnr = -1
2602 return this
2603 endif
2604 enddef
2605 endclass
2606 END
2607 v9.CheckScriptFailure(lines, 'E1365:')
2608
2609 # new() uses 'Dict' return type and returns a Dict
2610 lines =<< trim END
2611 vim9script
2612
2613 class C
2614 this._state: dict<any>
2615
2616 def new(): dict<any>
2617 this._state = {}
2618 return this._state
2619 enddef
2620 endclass
2621
2622 var c = C.new()
2623 assert_equal('object<C>', typename(c))
2624 END
2625 v9.CheckScriptFailure(lines, 'E1365:')
2626enddef
2627
Bram Moolenaar00b28d62022-12-08 15:32:33 +00002628" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker