blob: 00b843206e2810cff43bd4254d39fb9abfaffb72 [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
138 lines =<< trim END
139 vim9script
140
141 class TextPosition
142 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000143 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000144
Bram Moolenaar418b5472022-12-20 13:38:22 +0000145 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000146 def ToString(): string
147 return $'({this.lnum}, {this.col})'
148 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000149 endclass
150
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000151 # use the automatically generated new() method
152 var pos = TextPosition.new(2, 12)
153 assert_equal(2, pos.lnum)
154 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000155
156 # call an object method
157 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000158
159 assert_equal(v:t_class, type(TextPosition))
160 assert_equal(v:t_object, type(pos))
161 assert_equal('class<TextPosition>', typename(TextPosition))
162 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000163 END
164 v9.CheckScriptSuccess(lines)
165enddef
166
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000167def Test_class_defined_twice()
168 # class defined twice should fail
169 var lines =<< trim END
170 vim9script
171 class There
172 endclass
173 class There
174 endclass
175 END
176 v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
177
178 # one class, reload same script twice is OK
179 lines =<< trim END
180 vim9script
181 class There
182 endclass
183 END
184 writefile(lines, 'XclassTwice.vim', 'D')
185 source XclassTwice.vim
186 source XclassTwice.vim
187enddef
188
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000189def Test_returning_null_object()
190 # this was causing an internal error
191 var lines =<< trim END
192 vim9script
193
194 class BufferList
195 def Current(): any
196 return null_object
197 enddef
198 endclass
199
200 var buffers = BufferList.new()
201 echo buffers.Current()
202 END
203 v9.CheckScriptSuccess(lines)
204enddef
205
Bram Moolenaard13dd302023-03-11 20:56:35 +0000206def Test_using_null_class()
207 var lines =<< trim END
208 @_ = null_class.member
209 END
210 v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
211enddef
212
Bram Moolenaar657aea72023-01-27 13:16:19 +0000213def Test_class_interface_wrong_end()
214 var lines =<< trim END
215 vim9script
216 abstract class SomeName
217 this.member = 'text'
218 endinterface
219 END
220 v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
221
222 lines =<< trim END
223 vim9script
224 export interface AnotherName
225 this.member: string
226 endclass
227 END
228 v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
229enddef
230
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000231def Test_object_not_set()
232 var lines =<< trim END
233 vim9script
234
235 class State
236 this.value = 'xyz'
237 endclass
238
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000239 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000240 var db = {'xyz': 789}
241 echo db[state.value]
242 END
243 v9.CheckScriptFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000244
245 lines =<< trim END
246 vim9script
247
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000248 class Class
249 this.id: string
250 def Method1()
251 echo 'Method1' .. this.id
252 enddef
253 endclass
254
255 var obj: Class
256 def Func()
257 obj.Method1()
258 enddef
259 Func()
260 END
261 v9.CheckScriptFailure(lines, 'E1360:')
262
263 lines =<< trim END
264 vim9script
265
Bram Moolenaar0917e862023-02-18 14:42:44 +0000266 class Background
267 this.background = 'dark'
268 endclass
269
270 class Colorscheme
271 this._bg: Background
272
273 def GetBackground(): string
274 return this._bg.background
275 enddef
276 endclass
277
278 var bg: Background # UNINITIALIZED
279 echo Colorscheme.new(bg).GetBackground()
280 END
281 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Background> but got object<Unknown>')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000282
283 # TODO: this should not give an error but be handled at runtime
284 lines =<< trim END
285 vim9script
286
287 class Class
288 this.id: string
289 def Method1()
290 echo 'Method1' .. this.id
291 enddef
292 endclass
293
294 var obj = null_object
295 def Func()
296 obj.Method1()
297 enddef
298 Func()
299 END
300 v9.CheckScriptFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000301enddef
302
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000303def Test_class_member_initializer()
304 var lines =<< trim END
305 vim9script
306
307 class TextPosition
308 this.lnum: number = 1
309 this.col: number = 1
310
Bram Moolenaar418b5472022-12-20 13:38:22 +0000311 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000312 def new(lnum: number)
313 this.lnum = lnum
314 enddef
315 endclass
316
317 var pos = TextPosition.new(3)
318 assert_equal(3, pos.lnum)
319 assert_equal(1, pos.col)
320
321 var instr = execute('disassemble TextPosition.new')
322 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000323 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000324 '\d PUSHNR 1\_s*' ..
325 '\d STORE_THIS 0\_s*' ..
326 '\d PUSHNR 1\_s*' ..
327 '\d STORE_THIS 1\_s*' ..
328 'this.lnum = lnum\_s*' ..
329 '\d LOAD arg\[-1]\_s*' ..
330 '\d PUSHNR 0\_s*' ..
331 '\d LOAD $0\_s*' ..
332 '\d\+ STOREINDEX object\_s*' ..
333 '\d\+ RETURN object.*',
334 instr)
335 END
336 v9.CheckScriptSuccess(lines)
337enddef
338
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000339def Test_member_any_used_as_object()
340 var lines =<< trim END
341 vim9script
342
343 class Inner
344 this.value: number = 0
345 endclass
346
347 class Outer
348 this.inner: any
349 endclass
350
351 def F(outer: Outer)
352 outer.inner.value = 1
353 enddef
354
355 var inner_obj = Inner.new(0)
356 var outer_obj = Outer.new(inner_obj)
357 F(outer_obj)
358 assert_equal(1, inner_obj.value)
359 END
360 v9.CheckScriptSuccess(lines)
361
362 lines =<< trim END
363 vim9script
364
365 class Inner
366 this.value: number = 0
367 endclass
368
369 class Outer
370 this.inner: Inner
371 endclass
372
373 def F(outer: Outer)
374 outer.inner.value = 1
375 enddef
376
377 def Test_assign_to_nested_typed_member()
378 var inner = Inner.new(0)
379 var outer = Outer.new(inner)
380 F(outer)
381 assert_equal(1, inner.value)
382 enddef
383
384 Test_assign_to_nested_typed_member()
385 END
386 v9.CheckScriptSuccess(lines)
387enddef
388
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000389def Test_assignment_with_operator()
390 var lines =<< trim END
391 vim9script
392
393 class Foo
394 this.x: number
395
396 def Add(n: number)
397 this.x += n
398 enddef
399 endclass
400
401 var f = Foo.new(3)
402 f.Add(17)
403 assert_equal(20, f.x)
Bram Moolenaar22363c62023-04-24 17:15:25 +0100404
405 def AddToFoo(obj: Foo)
406 obj.x += 3
407 enddef
408
409 AddToFoo(f)
410 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000411 END
412 v9.CheckScriptSuccess(lines)
413enddef
414
Bram Moolenaarf4508042023-01-15 16:54:57 +0000415def Test_list_of_objects()
416 var lines =<< trim END
417 vim9script
418
419 class Foo
420 def Add()
421 enddef
422 endclass
423
424 def ProcessList(fooList: list<Foo>)
425 for foo in fooList
426 foo.Add()
427 endfor
428 enddef
429
430 var l: list<Foo> = [Foo.new()]
431 ProcessList(l)
432 END
433 v9.CheckScriptSuccess(lines)
434enddef
435
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000436def Test_expr_after_using_object()
437 var lines =<< trim END
438 vim9script
439
440 class Something
441 this.label: string = ''
442 endclass
443
444 def Foo(): Something
445 var v = Something.new()
446 echo 'in Foo(): ' .. typename(v)
447 return v
448 enddef
449
450 Foo()
451 END
452 v9.CheckScriptSuccess(lines)
453enddef
454
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000455def Test_class_default_new()
456 var lines =<< trim END
457 vim9script
458
459 class TextPosition
460 this.lnum: number = 1
461 this.col: number = 1
462 endclass
463
464 var pos = TextPosition.new()
465 assert_equal(1, pos.lnum)
466 assert_equal(1, pos.col)
467
468 pos = TextPosition.new(v:none, v:none)
469 assert_equal(1, pos.lnum)
470 assert_equal(1, pos.col)
471
472 pos = TextPosition.new(3, 22)
473 assert_equal(3, pos.lnum)
474 assert_equal(22, pos.col)
475
476 pos = TextPosition.new(v:none, 33)
477 assert_equal(1, pos.lnum)
478 assert_equal(33, pos.col)
479 END
480 v9.CheckScriptSuccess(lines)
481
482 lines =<< trim END
483 vim9script
484 class Person
485 this.name: string
486 this.age: number = 42
487 this.education: string = "unknown"
488
489 def new(this.name, this.age = v:none, this.education = v:none)
490 enddef
491 endclass
492
493 var piet = Person.new("Piet")
494 assert_equal("Piet", piet.name)
495 assert_equal(42, piet.age)
496 assert_equal("unknown", piet.education)
497
498 var chris = Person.new("Chris", 4, "none")
499 assert_equal("Chris", chris.name)
500 assert_equal(4, chris.age)
501 assert_equal("none", chris.education)
502 END
503 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000504
505 lines =<< trim END
506 vim9script
507 class Person
508 this.name: string
509 this.age: number = 42
510 this.education: string = "unknown"
511
512 def new(this.name, this.age = v:none, this.education = v:none)
513 enddef
514 endclass
515
516 var missing = Person.new()
517 END
518 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000519enddef
520
Bram Moolenaar74e12742022-12-13 21:14:28 +0000521def Test_class_object_member_inits()
522 var lines =<< trim END
523 vim9script
524 class TextPosition
525 this.lnum: number
526 this.col = 1
527 this.addcol: number = 2
528 endclass
529
530 var pos = TextPosition.new()
531 assert_equal(0, pos.lnum)
532 assert_equal(1, pos.col)
533 assert_equal(2, pos.addcol)
534 END
535 v9.CheckScriptSuccess(lines)
536
537 lines =<< trim END
538 vim9script
539 class TextPosition
540 this.lnum
541 this.col = 1
542 endclass
543 END
544 v9.CheckScriptFailure(lines, 'E1022:')
545
546 lines =<< trim END
547 vim9script
548 class TextPosition
549 this.lnum = v:none
550 this.col = 1
551 endclass
552 END
553 v9.CheckScriptFailure(lines, 'E1330:')
554enddef
555
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000556def Test_class_object_member_access()
557 var lines =<< trim END
558 vim9script
559 class Triple
560 this._one = 1
561 this.two = 2
562 public this.three = 3
563
564 def GetOne(): number
565 return this._one
566 enddef
567 endclass
568
569 var trip = Triple.new()
570 assert_equal(1, trip.GetOne())
571 assert_equal(2, trip.two)
572 assert_equal(3, trip.three)
573 assert_fails('echo trip._one', 'E1333')
574
575 assert_fails('trip._one = 11', 'E1333')
576 assert_fails('trip.two = 22', 'E1335')
577 trip.three = 33
578 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000579
580 assert_fails('trip.four = 4', 'E1334')
581 END
582 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000583
584 lines =<< trim END
585 vim9script
586
587 class MyCar
588 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000589 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000590
591 def new(make_arg: string)
592 this.make = make_arg
593 enddef
594
595 def GetMake(): string
596 return $"make = {this.make}"
597 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000598 def GetAge(): number
599 return this.age
600 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000601 endclass
602
603 var c = MyCar.new("abc")
604 assert_equal('make = abc', c.GetMake())
605
606 c = MyCar.new("def")
607 assert_equal('make = def', c.GetMake())
608
609 var c2 = MyCar.new("123")
610 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000611
612 def CheckCar()
613 assert_equal("make = def", c.GetMake())
614 assert_equal(5, c.GetAge())
615 enddef
616 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000617 END
618 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000619
620 lines =<< trim END
621 vim9script
622
623 class MyCar
624 this.make: string
625
626 def new(make_arg: string)
627 this.make = make_arg
628 enddef
629 endclass
630
631 var c = MyCar.new("abc")
632 var c = MyCar.new("def")
633 END
634 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000635
636 lines =<< trim END
637 vim9script
638
639 class Foo
640 this.x: list<number> = []
641
642 def Add(n: number): any
643 this.x->add(n)
644 return this
645 enddef
646 endclass
647
648 echo Foo.new().Add(1).Add(2).x
649 echo Foo.new().Add(1).Add(2)
650 .x
651 echo Foo.new().Add(1)
652 .Add(2).x
653 echo Foo.new()
654 .Add(1).Add(2).x
655 echo Foo.new()
656 .Add(1)
657 .Add(2)
658 .x
659 END
660 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000661enddef
662
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000663def Test_class_object_compare()
664 var class_lines =<< trim END
665 vim9script
666 class Item
667 this.nr = 0
668 this.name = 'xx'
669 endclass
670 END
671
672 # used at the script level and in a compiled function
673 var test_lines =<< trim END
674 var i1 = Item.new()
675 assert_equal(i1, i1)
676 assert_true(i1 is i1)
677 var i2 = Item.new()
678 assert_equal(i1, i2)
679 assert_false(i1 is i2)
680 var i3 = Item.new(0, 'xx')
681 assert_equal(i1, i3)
682
683 var io1 = Item.new(1, 'xx')
684 assert_notequal(i1, io1)
685 var io2 = Item.new(0, 'yy')
686 assert_notequal(i1, io2)
687 END
688
689 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000690 v9.CheckScriptSuccess(
691 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000692
693 for op in ['>', '>=', '<', '<=', '=~', '!~']
694 var op_lines = [
695 'var i1 = Item.new()',
696 'var i2 = Item.new()',
697 'echo i1 ' .. op .. ' i2',
698 ]
699 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000700 v9.CheckScriptFailure(class_lines
701 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000702 endfor
703enddef
704
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000705def Test_object_type()
706 var lines =<< trim END
707 vim9script
708
709 class One
710 this.one = 1
711 endclass
712 class Two
713 this.two = 2
714 endclass
715 class TwoMore extends Two
716 this.more = 9
717 endclass
718
719 var o: One = One.new()
720 var t: Two = Two.new()
721 var m: TwoMore = TwoMore.new()
722 var tm: Two = TwoMore.new()
723
724 t = m
725 END
726 v9.CheckScriptSuccess(lines)
727
728 lines =<< trim END
729 vim9script
730
731 class One
732 this.one = 1
733 endclass
734 class Two
735 this.two = 2
736 endclass
737
738 var o: One = Two.new()
739 END
740 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000741
742 lines =<< trim END
743 vim9script
744
745 interface One
746 def GetMember(): number
747 endinterface
748 class Two implements One
749 this.one = 1
750 def GetMember(): number
751 return this.one
752 enddef
753 endclass
754
755 var o: One = Two.new(5)
756 assert_equal(5, o.GetMember())
757 END
758 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000759
760 lines =<< trim END
761 vim9script
762
763 class Num
764 this.n: number = 0
765 endclass
766
767 def Ref(name: string): func(Num): Num
768 return (arg: Num): Num => {
769 return eval(name)(arg)
770 }
771 enddef
772
773 const Fn = Ref('Double')
774 var Double = (m: Num): Num => Num.new(m.n * 2)
775
776 echo Fn(Num.new(4))
777 END
778 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000779enddef
780
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000781def Test_class_member()
782 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000783 var lines =<< trim END
784 vim9script
785 class TextPos
786 this.lnum = 1
787 this.col = 1
788 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000789 static _secret = 7
790 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000791
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000792 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000793 counter += nr
794 enddef
795 endclass
796
797 assert_equal(0, TextPos.counter)
798 TextPos.AddToCounter(3)
799 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000800 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000801
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000802 def GetCounter(): number
803 return TextPos.counter
804 enddef
805 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000806
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000807 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000808 assert_fails('TextPos.counter = 5', 'E1335:')
809 assert_fails('TextPos.counter += 5', 'E1335:')
810
811 assert_fails('echo TextPos._secret', 'E1333:')
812 assert_fails('TextPos._secret = 8', 'E1333:')
813
814 assert_equal(42, TextPos.anybody)
815 TextPos.anybody = 12
816 assert_equal(12, TextPos.anybody)
817 TextPos.anybody += 5
818 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000819 END
820 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000821
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000822 # example in the help
823 lines =<< trim END
824 vim9script
825 class OtherThing
826 this.size: number
827 static totalSize: number
828
829 def new(this.size)
830 totalSize += this.size
831 enddef
832 endclass
833 assert_equal(0, OtherThing.totalSize)
834 var to3 = OtherThing.new(3)
835 assert_equal(3, OtherThing.totalSize)
836 var to7 = OtherThing.new(7)
837 assert_equal(10, OtherThing.totalSize)
838 END
839 v9.CheckScriptSuccess(lines)
840
Bram Moolenaar62a69232023-01-24 15:07:04 +0000841 # access private member in lambda
842 lines =<< trim END
843 vim9script
844
845 class Foo
846 this._x: number = 0
847
848 def Add(n: number): number
849 const F = (): number => this._x + n
850 return F()
851 enddef
852 endclass
853
854 var foo = Foo.new()
855 assert_equal(5, foo.Add(5))
856 END
857 v9.CheckScriptSuccess(lines)
858
h-east2bd6a092023-05-19 19:01:17 +0100859 # access private member in lambda body
860 lines =<< trim END
861 vim9script
862
863 class Foo
864 this._x: number = 6
865
866 def Add(n: number): number
867 var Lam = () => {
868 this._x = this._x + n
869 }
870 Lam()
871 return this._x
872 enddef
873 endclass
874
875 var foo = Foo.new()
876 assert_equal(13, foo.Add(7))
877 END
878 v9.CheckScriptSuccess(lines)
879
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000880 # check shadowing
881 lines =<< trim END
882 vim9script
883
884 class Some
885 static count = 0
886 def Method(count: number)
887 echo count
888 enddef
889 endclass
890
891 var s = Some.new()
892 s.Method(7)
893 END
894 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
895
896 lines =<< trim END
897 vim9script
898
899 class Some
900 static count = 0
901 def Method(arg: number)
902 var count = 3
903 echo arg count
904 enddef
905 endclass
906
907 var s = Some.new()
908 s.Method(7)
909 END
910 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000911enddef
912
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000913func Test_class_garbagecollect()
914 let lines =<< trim END
915 vim9script
916
917 class Point
918 this.p = [2, 3]
919 static pl = ['a', 'b']
920 static pd = {a: 'a', b: 'b'}
921 endclass
922
923 echo Point.pl Point.pd
924 call test_garbagecollect_now()
925 echo Point.pl Point.pd
926 END
927 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +0100928
929 let lines =<< trim END
930 vim9script
931
932 interface View
933 endinterface
934
935 class Widget
936 this.view: View
937 endclass
938
939 class MyView implements View
940 this.widget: Widget
941
942 def new()
943 # this will result in a circular reference to this object
944 this.widget = Widget.new(this)
945 enddef
946 endclass
947
948 var view = MyView.new()
949
950 # overwrite "view", will be garbage-collected next
951 view = MyView.new()
952 test_garbagecollect_now()
953 END
954 call v9.CheckScriptSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000955endfunc
956
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000957def Test_class_function()
958 var lines =<< trim END
959 vim9script
960 class Value
961 this.value = 0
962 static objects = 0
963
964 def new(v: number)
965 this.value = v
966 ++objects
967 enddef
968
969 static def GetCount(): number
970 return objects
971 enddef
972 endclass
973
974 assert_equal(0, Value.GetCount())
975 var v1 = Value.new(2)
976 assert_equal(1, Value.GetCount())
977 var v2 = Value.new(7)
978 assert_equal(2, Value.GetCount())
979 END
980 v9.CheckScriptSuccess(lines)
981enddef
982
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +0000983def Test_class_defcompile()
984 var lines =<< trim END
985 vim9script
986
987 class C
988 def Fo(i: number): string
989 return i
990 enddef
991 endclass
992
993 defcompile C.Fo
994 END
995 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
996
997 lines =<< trim END
998 vim9script
999
1000 class C
1001 static def Fc(): number
1002 return 'x'
1003 enddef
1004 endclass
1005
1006 defcompile C.Fc
1007 END
1008 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
1009enddef
1010
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001011def Test_class_object_to_string()
1012 var lines =<< trim END
1013 vim9script
1014 class TextPosition
1015 this.lnum = 1
1016 this.col = 22
1017 endclass
1018
1019 assert_equal("class TextPosition", string(TextPosition))
1020
1021 var pos = TextPosition.new()
1022 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
1023 END
1024 v9.CheckScriptSuccess(lines)
1025enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001026
Bram Moolenaar554d0312023-01-05 19:59:18 +00001027def Test_interface_basics()
1028 var lines =<< trim END
1029 vim9script
1030 interface Something
1031 this.value: string
1032 static count: number
1033 def GetCount(): number
1034 endinterface
1035 END
1036 v9.CheckScriptSuccess(lines)
1037
1038 lines =<< trim END
1039 interface SomethingWrong
1040 static count = 7
1041 endinterface
1042 END
1043 v9.CheckScriptFailure(lines, 'E1342:')
1044
1045 lines =<< trim END
1046 vim9script
1047
1048 interface Some
1049 static count: number
1050 def Method(count: number)
1051 endinterface
1052 END
h-east61378a12023-04-18 19:07:29 +01001053 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001054
1055 lines =<< trim END
1056 vim9script
1057
1058 interface Some
1059 this.value: number
1060 def Method(value: number)
1061 endinterface
1062 END
h-east61378a12023-04-18 19:07:29 +01001063 # The argument name and the object member name are the same, but this is not a
1064 # problem because object members are always accessed with the "this." prefix.
1065 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001066
1067 lines =<< trim END
1068 vim9script
1069 interface somethingWrong
1070 static count = 7
1071 endinterface
1072 END
1073 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1074
1075 lines =<< trim END
1076 vim9script
1077 interface SomethingWrong
1078 this.value: string
1079 static count = 7
1080 def GetCount(): number
1081 endinterface
1082 END
1083 v9.CheckScriptFailure(lines, 'E1344:')
1084
1085 lines =<< trim END
1086 vim9script
1087 interface SomethingWrong
1088 this.value: string
1089 static count: number
1090 def GetCount(): number
1091 return 5
1092 enddef
1093 endinterface
1094 END
1095 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001096
1097 lines =<< trim END
1098 vim9script
1099 export interface EnterExit
1100 def Enter(): void
1101 def Exit(): void
1102 endinterface
1103 END
1104 writefile(lines, 'XdefIntf.vim', 'D')
1105
1106 lines =<< trim END
1107 vim9script
1108 import './XdefIntf.vim' as defIntf
1109 export def With(ee: defIntf.EnterExit, F: func)
1110 ee.Enter()
1111 try
1112 F()
1113 finally
1114 ee.Exit()
1115 endtry
1116 enddef
1117 END
1118 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001119
1120 var imported =<< trim END
1121 vim9script
1122 export abstract class EnterExit
1123 def Enter(): void
1124 enddef
1125 def Exit(): void
1126 enddef
1127 endclass
1128 END
1129 writefile(imported, 'XdefIntf2.vim', 'D')
1130
1131 lines[1] = " import './XdefIntf2.vim' as defIntf"
1132 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001133enddef
1134
Bram Moolenaar94674f22023-01-06 18:42:20 +00001135def Test_class_implements_interface()
1136 var lines =<< trim END
1137 vim9script
1138
1139 interface Some
1140 static count: number
1141 def Method(nr: number)
1142 endinterface
1143
1144 class SomeImpl implements Some
1145 static count: number
1146 def Method(nr: number)
1147 echo nr
1148 enddef
1149 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001150
1151 interface Another
1152 this.member: string
1153 endinterface
1154
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001155 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001156 this.member = 'abc'
1157 static count: number
1158 def Method(nr: number)
1159 echo nr
1160 enddef
1161 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001162 END
1163 v9.CheckScriptSuccess(lines)
1164
1165 lines =<< trim END
1166 vim9script
1167
1168 interface Some
1169 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001170 endinterface
1171
1172 class SomeImpl implements Some implements Some
1173 static count: number
1174 endclass
1175 END
1176 v9.CheckScriptFailure(lines, 'E1350:')
1177
1178 lines =<< trim END
1179 vim9script
1180
1181 interface Some
1182 static counter: number
1183 endinterface
1184
1185 class SomeImpl implements Some, Some
1186 static count: number
1187 endclass
1188 END
1189 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1190
1191 lines =<< trim END
1192 vim9script
1193
1194 interface Some
1195 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001196 def Method(nr: number)
1197 endinterface
1198
1199 class SomeImpl implements Some
1200 static count: number
1201 def Method(nr: number)
1202 echo nr
1203 enddef
1204 endclass
1205 END
1206 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1207
1208 lines =<< trim END
1209 vim9script
1210
1211 interface Some
1212 static count: number
1213 def Methods(nr: number)
1214 endinterface
1215
1216 class SomeImpl implements Some
1217 static count: number
1218 def Method(nr: number)
1219 echo nr
1220 enddef
1221 endclass
1222 END
1223 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001224
1225 # Check different order of members in class and interface works.
1226 lines =<< trim END
1227 vim9script
1228
1229 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001230 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001231 this.errpos: number
1232 endinterface
1233
1234 # order of members is opposite of interface
1235 class Failure implements Result
1236 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001237 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001238 endclass
1239
1240 def Test()
1241 var result: Result = Failure.new()
1242
1243 assert_equal('label', result.label)
1244 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001245
1246 result.label = 'different'
1247 assert_equal('different', result.label)
1248 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001249 enddef
1250
1251 Test()
1252 END
1253 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001254enddef
1255
Bram Moolenaard0200c82023-01-28 15:19:40 +00001256def Test_call_interface_method()
1257 var lines =<< trim END
1258 vim9script
1259 interface Base
1260 def Enter(): void
1261 endinterface
1262
1263 class Child implements Base
1264 def Enter(): void
1265 g:result ..= 'child'
1266 enddef
1267 endclass
1268
1269 def F(obj: Base)
1270 obj.Enter()
1271 enddef
1272
1273 g:result = ''
1274 F(Child.new())
1275 assert_equal('child', g:result)
1276 unlet g:result
1277 END
1278 v9.CheckScriptSuccess(lines)
1279
1280 lines =<< trim END
1281 vim9script
1282 class Base
1283 def Enter(): void
1284 g:result ..= 'base'
1285 enddef
1286 endclass
1287
1288 class Child extends Base
1289 def Enter(): void
1290 g:result ..= 'child'
1291 enddef
1292 endclass
1293
1294 def F(obj: Base)
1295 obj.Enter()
1296 enddef
1297
1298 g:result = ''
1299 F(Child.new())
1300 assert_equal('child', g:result)
1301 unlet g:result
1302 END
1303 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001304
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001305 # method of interface returns a value
1306 lines =<< trim END
1307 vim9script
1308 interface Base
1309 def Enter(): string
1310 endinterface
1311
1312 class Child implements Base
1313 def Enter(): string
1314 g:result ..= 'child'
1315 return "/resource"
1316 enddef
1317 endclass
1318
1319 def F(obj: Base)
1320 var r = obj.Enter()
1321 g:result ..= r
1322 enddef
1323
1324 g:result = ''
1325 F(Child.new())
1326 assert_equal('child/resource', g:result)
1327 unlet g:result
1328 END
1329 v9.CheckScriptSuccess(lines)
1330
1331 lines =<< trim END
1332 vim9script
1333 class Base
1334 def Enter(): string
1335 return null_string
1336 enddef
1337 endclass
1338
1339 class Child extends Base
1340 def Enter(): string
1341 g:result ..= 'child'
1342 return "/resource"
1343 enddef
1344 endclass
1345
1346 def F(obj: Base)
1347 var r = obj.Enter()
1348 g:result ..= r
1349 enddef
1350
1351 g:result = ''
1352 F(Child.new())
1353 assert_equal('child/resource', g:result)
1354 unlet g:result
1355 END
1356 v9.CheckScriptSuccess(lines)
1357
1358
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001359 # No class that implements the interface.
1360 lines =<< trim END
1361 vim9script
1362
1363 interface IWithEE
1364 def Enter(): any
1365 def Exit(): void
1366 endinterface
1367
1368 def With1(ee: IWithEE, F: func)
1369 var r = ee.Enter()
1370 enddef
1371
1372 defcompile
1373 END
1374 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001375enddef
1376
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001377def Test_class_used_as_type()
1378 var lines =<< trim END
1379 vim9script
1380
1381 class Point
1382 this.x = 0
1383 this.y = 0
1384 endclass
1385
1386 var p: Point
1387 p = Point.new(2, 33)
1388 assert_equal(2, p.x)
1389 assert_equal(33, p.y)
1390 END
1391 v9.CheckScriptSuccess(lines)
1392
1393 lines =<< trim END
1394 vim9script
1395
1396 interface HasX
1397 this.x: number
1398 endinterface
1399
1400 class Point implements HasX
1401 this.x = 0
1402 this.y = 0
1403 endclass
1404
1405 var p: Point
1406 p = Point.new(2, 33)
1407 var hx = p
1408 assert_equal(2, hx.x)
1409 END
1410 v9.CheckScriptSuccess(lines)
1411
1412 lines =<< trim END
1413 vim9script
1414
1415 class Point
1416 this.x = 0
1417 this.y = 0
1418 endclass
1419
1420 var p: Point
1421 p = 'text'
1422 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001423 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001424enddef
1425
Bram Moolenaar83677162023-01-08 19:54:10 +00001426def Test_class_extends()
1427 var lines =<< trim END
1428 vim9script
1429 class Base
1430 this.one = 1
1431 def GetOne(): number
1432 return this.one
1433 enddef
1434 endclass
1435 class Child extends Base
1436 this.two = 2
1437 def GetTotal(): number
1438 return this.one + this.two
1439 enddef
1440 endclass
1441 var o = Child.new()
1442 assert_equal(1, o.one)
1443 assert_equal(2, o.two)
1444 assert_equal(1, o.GetOne())
1445 assert_equal(3, o.GetTotal())
1446 END
1447 v9.CheckScriptSuccess(lines)
1448
1449 lines =<< trim END
1450 vim9script
1451 class Base
1452 this.one = 1
1453 endclass
1454 class Child extends Base
1455 this.two = 2
1456 endclass
1457 var o = Child.new(3, 44)
1458 assert_equal(3, o.one)
1459 assert_equal(44, o.two)
1460 END
1461 v9.CheckScriptSuccess(lines)
1462
1463 lines =<< trim END
1464 vim9script
1465 class Base
1466 this.one = 1
1467 endclass
1468 class Child extends Base extends Base
1469 this.two = 2
1470 endclass
1471 END
1472 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1473
1474 lines =<< trim END
1475 vim9script
1476 class Child extends BaseClass
1477 this.two = 2
1478 endclass
1479 END
1480 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1481
1482 lines =<< trim END
1483 vim9script
1484 var SomeVar = 99
1485 class Child extends SomeVar
1486 this.two = 2
1487 endclass
1488 END
1489 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001490
1491 lines =<< trim END
1492 vim9script
1493 class Base
1494 this.name: string
1495 def ToString(): string
1496 return this.name
1497 enddef
1498 endclass
1499
1500 class Child extends Base
1501 this.age: number
1502 def ToString(): string
1503 return super.ToString() .. ': ' .. this.age
1504 enddef
1505 endclass
1506
1507 var o = Child.new('John', 42)
1508 assert_equal('John: 42', o.ToString())
1509 END
1510 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001511
1512 lines =<< trim END
1513 vim9script
1514 class Child
1515 this.age: number
1516 def ToString(): number
1517 return this.age
1518 enddef
1519 def ToString(): string
1520 return this.age
1521 enddef
1522 endclass
1523 END
1524 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1525
1526 lines =<< trim END
1527 vim9script
1528 class Child
1529 this.age: number
1530 def ToString(): string
1531 return super .ToString() .. ': ' .. this.age
1532 enddef
1533 endclass
1534 var o = Child.new(42)
1535 echo o.ToString()
1536 END
1537 v9.CheckScriptFailure(lines, 'E1356:')
1538
1539 lines =<< trim END
1540 vim9script
1541 class Base
1542 this.name: string
1543 def ToString(): string
1544 return this.name
1545 enddef
1546 endclass
1547
1548 var age = 42
1549 def ToString(): string
1550 return super.ToString() .. ': ' .. age
1551 enddef
1552 echo ToString()
1553 END
1554 v9.CheckScriptFailure(lines, 'E1357:')
1555
1556 lines =<< trim END
1557 vim9script
1558 class Child
1559 this.age: number
1560 def ToString(): string
1561 return super.ToString() .. ': ' .. this.age
1562 enddef
1563 endclass
1564 var o = Child.new(42)
1565 echo o.ToString()
1566 END
1567 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001568
1569 lines =<< trim END
1570 vim9script
1571 class Base
1572 this.name: string
1573 static def ToString(): string
1574 return 'Base class'
1575 enddef
1576 endclass
1577
1578 class Child extends Base
1579 this.age: number
1580 def ToString(): string
1581 return Base.ToString() .. ': ' .. this.age
1582 enddef
1583 endclass
1584
1585 var o = Child.new('John', 42)
1586 assert_equal('Base class: 42', o.ToString())
1587 END
1588 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001589
1590 lines =<< trim END
1591 vim9script
1592 class Base
1593 this.value = 1
1594 def new(init: number)
1595 this.value = number + 1
1596 enddef
1597 endclass
1598 class Child extends Base
1599 def new()
1600 this.new(3)
1601 enddef
1602 endclass
1603 var c = Child.new()
1604 END
1605 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001606
1607 # base class with more than one object member
1608 lines =<< trim END
1609 vim9script
1610
1611 class Result
1612 this.success: bool
1613 this.value: any = null
1614 endclass
1615
1616 class Success extends Result
1617 def new(this.value = v:none)
1618 this.success = true
1619 enddef
1620 endclass
1621
1622 var v = Success.new('asdf')
1623 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1624 END
1625 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001626enddef
1627
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001628def Test_using_base_class()
1629 var lines =<< trim END
1630 vim9script
1631
1632 class BaseEE
1633 def Enter(): any
1634 return null
1635 enddef
1636 def Exit(resource: any): void
1637 enddef
1638 endclass
1639
1640 class ChildEE extends BaseEE
1641 def Enter(): any
1642 return 42
1643 enddef
1644
1645 def Exit(resource: number): void
1646 g:result ..= '/exit'
1647 enddef
1648 endclass
1649
1650 def With(ee: BaseEE)
1651 var r = ee.Enter()
1652 try
1653 g:result ..= r
1654 finally
1655 g:result ..= '/finally'
1656 ee.Exit(r)
1657 endtry
1658 enddef
1659
1660 g:result = ''
1661 With(ChildEE.new())
1662 assert_equal('42/finally/exit', g:result)
1663 END
1664 v9.CheckScriptSuccess(lines)
1665 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01001666
1667 # Using super, Child invokes Base method which has optional arg. #12471
1668 lines =<< trim END
1669 vim9script
1670
1671 class Base
1672 this.success: bool = false
1673 def Method(arg = 0)
1674 this.success = true
1675 enddef
1676 endclass
1677
1678 class Child extends Base
1679 def new()
1680 super.Method()
1681 enddef
1682 endclass
1683
1684 var obj = Child.new()
1685 assert_equal(true, obj.success)
1686 END
1687 v9.CheckScriptSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001688enddef
1689
1690
Bram Moolenaara86655a2023-01-12 17:06:27 +00001691def Test_class_import()
1692 var lines =<< trim END
1693 vim9script
1694 export class Animal
1695 this.kind: string
1696 this.name: string
1697 endclass
1698 END
1699 writefile(lines, 'Xanimal.vim', 'D')
1700
1701 lines =<< trim END
1702 vim9script
1703 import './Xanimal.vim' as animal
1704
1705 var a: animal.Animal
1706 a = animal.Animal.new('fish', 'Eric')
1707 assert_equal('fish', a.kind)
1708 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001709
1710 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1711 assert_equal('cat', b.kind)
1712 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001713 END
1714 v9.CheckScriptSuccess(lines)
1715enddef
1716
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001717def Test_abstract_class()
1718 var lines =<< trim END
1719 vim9script
1720 abstract class Base
1721 this.name: string
1722 endclass
1723 class Person extends Base
1724 this.age: number
1725 endclass
1726 var p: Base = Person.new('Peter', 42)
1727 assert_equal('Peter', p.name)
1728 assert_equal(42, p.age)
1729 END
1730 v9.CheckScriptSuccess(lines)
1731
1732 lines =<< trim END
1733 vim9script
1734 abstract class Base
1735 this.name: string
1736 endclass
1737 class Person extends Base
1738 this.age: number
1739 endclass
1740 var p = Base.new('Peter')
1741 END
1742 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1743
1744 lines =<< trim END
1745 abstract class Base
1746 this.name: string
1747 endclass
1748 END
1749 v9.CheckScriptFailure(lines, 'E1316:')
1750enddef
1751
Bram Moolenaar486fc252023-01-18 14:51:07 +00001752def Test_closure_in_class()
1753 var lines =<< trim END
1754 vim9script
1755
1756 class Foo
1757 this.y: list<string> = ['B']
1758
1759 def new()
1760 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1761 enddef
1762 endclass
1763
1764 Foo.new()
1765 assert_equal(['A'], g:result)
1766 END
1767 v9.CheckScriptSuccess(lines)
1768enddef
1769
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01001770def Test_call_constructor_from_legacy()
1771 var lines =<< trim END
1772 vim9script
1773
1774 var newCalled = 'false'
1775
1776 class A
1777 def new()
1778 newCalled = 'true'
1779 enddef
1780 endclass
1781
1782 export def F(options = {}): any
1783 return A
1784 enddef
1785
1786 g:p = F()
1787 legacy call p.new()
1788 assert_equal('true', newCalled)
1789 END
1790 v9.CheckScriptSuccess(lines)
1791enddef
1792
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001793def Test_defer_with_object()
1794 var lines =<< trim END
1795 vim9script
1796
1797 class CWithEE
1798 def Enter()
1799 g:result ..= "entered/"
1800 enddef
1801 def Exit()
1802 g:result ..= "exited"
1803 enddef
1804 endclass
1805
1806 def With(ee: CWithEE, F: func)
1807 ee.Enter()
1808 defer ee.Exit()
1809 F()
1810 enddef
1811
1812 g:result = ''
1813 var obj = CWithEE.new()
1814 obj->With(() => {
1815 g:result ..= "called/"
1816 })
1817 assert_equal('entered/called/exited', g:result)
1818 END
1819 v9.CheckScriptSuccess(lines)
1820 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00001821
1822 lines =<< trim END
1823 vim9script
1824
1825 class BaseWithEE
1826 def Enter()
1827 g:result ..= "entered-base/"
1828 enddef
1829 def Exit()
1830 g:result ..= "exited-base"
1831 enddef
1832 endclass
1833
1834 class CWithEE extends BaseWithEE
1835 def Enter()
1836 g:result ..= "entered-child/"
1837 enddef
1838 def Exit()
1839 g:result ..= "exited-child"
1840 enddef
1841 endclass
1842
1843 def With(ee: BaseWithEE, F: func)
1844 ee.Enter()
1845 defer ee.Exit()
1846 F()
1847 enddef
1848
1849 g:result = ''
1850 var obj = CWithEE.new()
1851 obj->With(() => {
1852 g:result ..= "called/"
1853 })
1854 assert_equal('entered-child/called/exited-child', g:result)
1855 END
1856 v9.CheckScriptSuccess(lines)
1857 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001858enddef
1859
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001860
1861" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker