blob: 4b6a730bbd7799cb916d502736ef5df446b296c9 [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)
404 END
405 v9.CheckScriptSuccess(lines)
406enddef
407
Bram Moolenaarf4508042023-01-15 16:54:57 +0000408def Test_list_of_objects()
409 var lines =<< trim END
410 vim9script
411
412 class Foo
413 def Add()
414 enddef
415 endclass
416
417 def ProcessList(fooList: list<Foo>)
418 for foo in fooList
419 foo.Add()
420 endfor
421 enddef
422
423 var l: list<Foo> = [Foo.new()]
424 ProcessList(l)
425 END
426 v9.CheckScriptSuccess(lines)
427enddef
428
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000429def Test_expr_after_using_object()
430 var lines =<< trim END
431 vim9script
432
433 class Something
434 this.label: string = ''
435 endclass
436
437 def Foo(): Something
438 var v = Something.new()
439 echo 'in Foo(): ' .. typename(v)
440 return v
441 enddef
442
443 Foo()
444 END
445 v9.CheckScriptSuccess(lines)
446enddef
447
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000448def Test_class_default_new()
449 var lines =<< trim END
450 vim9script
451
452 class TextPosition
453 this.lnum: number = 1
454 this.col: number = 1
455 endclass
456
457 var pos = TextPosition.new()
458 assert_equal(1, pos.lnum)
459 assert_equal(1, pos.col)
460
461 pos = TextPosition.new(v:none, v:none)
462 assert_equal(1, pos.lnum)
463 assert_equal(1, pos.col)
464
465 pos = TextPosition.new(3, 22)
466 assert_equal(3, pos.lnum)
467 assert_equal(22, pos.col)
468
469 pos = TextPosition.new(v:none, 33)
470 assert_equal(1, pos.lnum)
471 assert_equal(33, pos.col)
472 END
473 v9.CheckScriptSuccess(lines)
474
475 lines =<< trim END
476 vim9script
477 class Person
478 this.name: string
479 this.age: number = 42
480 this.education: string = "unknown"
481
482 def new(this.name, this.age = v:none, this.education = v:none)
483 enddef
484 endclass
485
486 var piet = Person.new("Piet")
487 assert_equal("Piet", piet.name)
488 assert_equal(42, piet.age)
489 assert_equal("unknown", piet.education)
490
491 var chris = Person.new("Chris", 4, "none")
492 assert_equal("Chris", chris.name)
493 assert_equal(4, chris.age)
494 assert_equal("none", chris.education)
495 END
496 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000497
498 lines =<< trim END
499 vim9script
500 class Person
501 this.name: string
502 this.age: number = 42
503 this.education: string = "unknown"
504
505 def new(this.name, this.age = v:none, this.education = v:none)
506 enddef
507 endclass
508
509 var missing = Person.new()
510 END
511 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000512enddef
513
Bram Moolenaar74e12742022-12-13 21:14:28 +0000514def Test_class_object_member_inits()
515 var lines =<< trim END
516 vim9script
517 class TextPosition
518 this.lnum: number
519 this.col = 1
520 this.addcol: number = 2
521 endclass
522
523 var pos = TextPosition.new()
524 assert_equal(0, pos.lnum)
525 assert_equal(1, pos.col)
526 assert_equal(2, pos.addcol)
527 END
528 v9.CheckScriptSuccess(lines)
529
530 lines =<< trim END
531 vim9script
532 class TextPosition
533 this.lnum
534 this.col = 1
535 endclass
536 END
537 v9.CheckScriptFailure(lines, 'E1022:')
538
539 lines =<< trim END
540 vim9script
541 class TextPosition
542 this.lnum = v:none
543 this.col = 1
544 endclass
545 END
546 v9.CheckScriptFailure(lines, 'E1330:')
547enddef
548
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000549def Test_class_object_member_access()
550 var lines =<< trim END
551 vim9script
552 class Triple
553 this._one = 1
554 this.two = 2
555 public this.three = 3
556
557 def GetOne(): number
558 return this._one
559 enddef
560 endclass
561
562 var trip = Triple.new()
563 assert_equal(1, trip.GetOne())
564 assert_equal(2, trip.two)
565 assert_equal(3, trip.three)
566 assert_fails('echo trip._one', 'E1333')
567
568 assert_fails('trip._one = 11', 'E1333')
569 assert_fails('trip.two = 22', 'E1335')
570 trip.three = 33
571 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000572
573 assert_fails('trip.four = 4', 'E1334')
574 END
575 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000576
577 lines =<< trim END
578 vim9script
579
580 class MyCar
581 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000582 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000583
584 def new(make_arg: string)
585 this.make = make_arg
586 enddef
587
588 def GetMake(): string
589 return $"make = {this.make}"
590 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000591 def GetAge(): number
592 return this.age
593 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000594 endclass
595
596 var c = MyCar.new("abc")
597 assert_equal('make = abc', c.GetMake())
598
599 c = MyCar.new("def")
600 assert_equal('make = def', c.GetMake())
601
602 var c2 = MyCar.new("123")
603 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000604
605 def CheckCar()
606 assert_equal("make = def", c.GetMake())
607 assert_equal(5, c.GetAge())
608 enddef
609 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000610 END
611 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000612
613 lines =<< trim END
614 vim9script
615
616 class MyCar
617 this.make: string
618
619 def new(make_arg: string)
620 this.make = make_arg
621 enddef
622 endclass
623
624 var c = MyCar.new("abc")
625 var c = MyCar.new("def")
626 END
627 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000628
629 lines =<< trim END
630 vim9script
631
632 class Foo
633 this.x: list<number> = []
634
635 def Add(n: number): any
636 this.x->add(n)
637 return this
638 enddef
639 endclass
640
641 echo Foo.new().Add(1).Add(2).x
642 echo Foo.new().Add(1).Add(2)
643 .x
644 echo Foo.new().Add(1)
645 .Add(2).x
646 echo Foo.new()
647 .Add(1).Add(2).x
648 echo Foo.new()
649 .Add(1)
650 .Add(2)
651 .x
652 END
653 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000654enddef
655
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000656def Test_class_object_compare()
657 var class_lines =<< trim END
658 vim9script
659 class Item
660 this.nr = 0
661 this.name = 'xx'
662 endclass
663 END
664
665 # used at the script level and in a compiled function
666 var test_lines =<< trim END
667 var i1 = Item.new()
668 assert_equal(i1, i1)
669 assert_true(i1 is i1)
670 var i2 = Item.new()
671 assert_equal(i1, i2)
672 assert_false(i1 is i2)
673 var i3 = Item.new(0, 'xx')
674 assert_equal(i1, i3)
675
676 var io1 = Item.new(1, 'xx')
677 assert_notequal(i1, io1)
678 var io2 = Item.new(0, 'yy')
679 assert_notequal(i1, io2)
680 END
681
682 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000683 v9.CheckScriptSuccess(
684 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000685
686 for op in ['>', '>=', '<', '<=', '=~', '!~']
687 var op_lines = [
688 'var i1 = Item.new()',
689 'var i2 = Item.new()',
690 'echo i1 ' .. op .. ' i2',
691 ]
692 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000693 v9.CheckScriptFailure(class_lines
694 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000695 endfor
696enddef
697
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000698def Test_object_type()
699 var lines =<< trim END
700 vim9script
701
702 class One
703 this.one = 1
704 endclass
705 class Two
706 this.two = 2
707 endclass
708 class TwoMore extends Two
709 this.more = 9
710 endclass
711
712 var o: One = One.new()
713 var t: Two = Two.new()
714 var m: TwoMore = TwoMore.new()
715 var tm: Two = TwoMore.new()
716
717 t = m
718 END
719 v9.CheckScriptSuccess(lines)
720
721 lines =<< trim END
722 vim9script
723
724 class One
725 this.one = 1
726 endclass
727 class Two
728 this.two = 2
729 endclass
730
731 var o: One = Two.new()
732 END
733 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000734
735 lines =<< trim END
736 vim9script
737
738 interface One
739 def GetMember(): number
740 endinterface
741 class Two implements One
742 this.one = 1
743 def GetMember(): number
744 return this.one
745 enddef
746 endclass
747
748 var o: One = Two.new(5)
749 assert_equal(5, o.GetMember())
750 END
751 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000752
753 lines =<< trim END
754 vim9script
755
756 class Num
757 this.n: number = 0
758 endclass
759
760 def Ref(name: string): func(Num): Num
761 return (arg: Num): Num => {
762 return eval(name)(arg)
763 }
764 enddef
765
766 const Fn = Ref('Double')
767 var Double = (m: Num): Num => Num.new(m.n * 2)
768
769 echo Fn(Num.new(4))
770 END
771 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000772enddef
773
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000774def Test_class_member()
775 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000776 var lines =<< trim END
777 vim9script
778 class TextPos
779 this.lnum = 1
780 this.col = 1
781 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000782 static _secret = 7
783 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000784
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000785 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000786 counter += nr
787 enddef
788 endclass
789
790 assert_equal(0, TextPos.counter)
791 TextPos.AddToCounter(3)
792 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000793 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000794
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000795 def GetCounter(): number
796 return TextPos.counter
797 enddef
798 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000799
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000800 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000801 assert_fails('TextPos.counter = 5', 'E1335:')
802 assert_fails('TextPos.counter += 5', 'E1335:')
803
804 assert_fails('echo TextPos._secret', 'E1333:')
805 assert_fails('TextPos._secret = 8', 'E1333:')
806
807 assert_equal(42, TextPos.anybody)
808 TextPos.anybody = 12
809 assert_equal(12, TextPos.anybody)
810 TextPos.anybody += 5
811 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000812 END
813 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000814
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000815 # example in the help
816 lines =<< trim END
817 vim9script
818 class OtherThing
819 this.size: number
820 static totalSize: number
821
822 def new(this.size)
823 totalSize += this.size
824 enddef
825 endclass
826 assert_equal(0, OtherThing.totalSize)
827 var to3 = OtherThing.new(3)
828 assert_equal(3, OtherThing.totalSize)
829 var to7 = OtherThing.new(7)
830 assert_equal(10, OtherThing.totalSize)
831 END
832 v9.CheckScriptSuccess(lines)
833
Bram Moolenaar62a69232023-01-24 15:07:04 +0000834 # access private member in lambda
835 lines =<< trim END
836 vim9script
837
838 class Foo
839 this._x: number = 0
840
841 def Add(n: number): number
842 const F = (): number => this._x + n
843 return F()
844 enddef
845 endclass
846
847 var foo = Foo.new()
848 assert_equal(5, foo.Add(5))
849 END
850 v9.CheckScriptSuccess(lines)
851
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000852 # check shadowing
853 lines =<< trim END
854 vim9script
855
856 class Some
857 static count = 0
858 def Method(count: number)
859 echo count
860 enddef
861 endclass
862
863 var s = Some.new()
864 s.Method(7)
865 END
866 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
867
868 lines =<< trim END
869 vim9script
870
871 class Some
872 static count = 0
873 def Method(arg: number)
874 var count = 3
875 echo arg count
876 enddef
877 endclass
878
879 var s = Some.new()
880 s.Method(7)
881 END
882 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000883enddef
884
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000885func Test_class_garbagecollect()
886 let lines =<< trim END
887 vim9script
888
889 class Point
890 this.p = [2, 3]
891 static pl = ['a', 'b']
892 static pd = {a: 'a', b: 'b'}
893 endclass
894
895 echo Point.pl Point.pd
896 call test_garbagecollect_now()
897 echo Point.pl Point.pd
898 END
899 call v9.CheckScriptSuccess(lines)
900endfunc
901
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000902def Test_class_function()
903 var lines =<< trim END
904 vim9script
905 class Value
906 this.value = 0
907 static objects = 0
908
909 def new(v: number)
910 this.value = v
911 ++objects
912 enddef
913
914 static def GetCount(): number
915 return objects
916 enddef
917 endclass
918
919 assert_equal(0, Value.GetCount())
920 var v1 = Value.new(2)
921 assert_equal(1, Value.GetCount())
922 var v2 = Value.new(7)
923 assert_equal(2, Value.GetCount())
924 END
925 v9.CheckScriptSuccess(lines)
926enddef
927
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +0000928def Test_class_defcompile()
929 var lines =<< trim END
930 vim9script
931
932 class C
933 def Fo(i: number): string
934 return i
935 enddef
936 endclass
937
938 defcompile C.Fo
939 END
940 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
941
942 lines =<< trim END
943 vim9script
944
945 class C
946 static def Fc(): number
947 return 'x'
948 enddef
949 endclass
950
951 defcompile C.Fc
952 END
953 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
954enddef
955
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000956def Test_class_object_to_string()
957 var lines =<< trim END
958 vim9script
959 class TextPosition
960 this.lnum = 1
961 this.col = 22
962 endclass
963
964 assert_equal("class TextPosition", string(TextPosition))
965
966 var pos = TextPosition.new()
967 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
968 END
969 v9.CheckScriptSuccess(lines)
970enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000971
Bram Moolenaar554d0312023-01-05 19:59:18 +0000972def Test_interface_basics()
973 var lines =<< trim END
974 vim9script
975 interface Something
976 this.value: string
977 static count: number
978 def GetCount(): number
979 endinterface
980 END
981 v9.CheckScriptSuccess(lines)
982
983 lines =<< trim END
984 interface SomethingWrong
985 static count = 7
986 endinterface
987 END
988 v9.CheckScriptFailure(lines, 'E1342:')
989
990 lines =<< trim END
991 vim9script
992
993 interface Some
994 static count: number
995 def Method(count: number)
996 endinterface
997 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000998 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
999
1000 lines =<< trim END
1001 vim9script
1002
1003 interface Some
1004 this.value: number
1005 def Method(value: number)
1006 endinterface
1007 END
1008 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +00001009
1010 lines =<< trim END
1011 vim9script
1012 interface somethingWrong
1013 static count = 7
1014 endinterface
1015 END
1016 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1017
1018 lines =<< trim END
1019 vim9script
1020 interface SomethingWrong
1021 this.value: string
1022 static count = 7
1023 def GetCount(): number
1024 endinterface
1025 END
1026 v9.CheckScriptFailure(lines, 'E1344:')
1027
1028 lines =<< trim END
1029 vim9script
1030 interface SomethingWrong
1031 this.value: string
1032 static count: number
1033 def GetCount(): number
1034 return 5
1035 enddef
1036 endinterface
1037 END
1038 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001039
1040 lines =<< trim END
1041 vim9script
1042 export interface EnterExit
1043 def Enter(): void
1044 def Exit(): void
1045 endinterface
1046 END
1047 writefile(lines, 'XdefIntf.vim', 'D')
1048
1049 lines =<< trim END
1050 vim9script
1051 import './XdefIntf.vim' as defIntf
1052 export def With(ee: defIntf.EnterExit, F: func)
1053 ee.Enter()
1054 try
1055 F()
1056 finally
1057 ee.Exit()
1058 endtry
1059 enddef
1060 END
1061 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001062
1063 var imported =<< trim END
1064 vim9script
1065 export abstract class EnterExit
1066 def Enter(): void
1067 enddef
1068 def Exit(): void
1069 enddef
1070 endclass
1071 END
1072 writefile(imported, 'XdefIntf2.vim', 'D')
1073
1074 lines[1] = " import './XdefIntf2.vim' as defIntf"
1075 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001076enddef
1077
Bram Moolenaar94674f22023-01-06 18:42:20 +00001078def Test_class_implements_interface()
1079 var lines =<< trim END
1080 vim9script
1081
1082 interface Some
1083 static count: number
1084 def Method(nr: number)
1085 endinterface
1086
1087 class SomeImpl implements Some
1088 static count: number
1089 def Method(nr: number)
1090 echo nr
1091 enddef
1092 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001093
1094 interface Another
1095 this.member: string
1096 endinterface
1097
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001098 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001099 this.member = 'abc'
1100 static count: number
1101 def Method(nr: number)
1102 echo nr
1103 enddef
1104 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001105 END
1106 v9.CheckScriptSuccess(lines)
1107
1108 lines =<< trim END
1109 vim9script
1110
1111 interface Some
1112 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001113 endinterface
1114
1115 class SomeImpl implements Some implements Some
1116 static count: number
1117 endclass
1118 END
1119 v9.CheckScriptFailure(lines, 'E1350:')
1120
1121 lines =<< trim END
1122 vim9script
1123
1124 interface Some
1125 static counter: number
1126 endinterface
1127
1128 class SomeImpl implements Some, Some
1129 static count: number
1130 endclass
1131 END
1132 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1133
1134 lines =<< trim END
1135 vim9script
1136
1137 interface Some
1138 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001139 def Method(nr: number)
1140 endinterface
1141
1142 class SomeImpl implements Some
1143 static count: number
1144 def Method(nr: number)
1145 echo nr
1146 enddef
1147 endclass
1148 END
1149 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1150
1151 lines =<< trim END
1152 vim9script
1153
1154 interface Some
1155 static count: number
1156 def Methods(nr: number)
1157 endinterface
1158
1159 class SomeImpl implements Some
1160 static count: number
1161 def Method(nr: number)
1162 echo nr
1163 enddef
1164 endclass
1165 END
1166 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001167
1168 # Check different order of members in class and interface works.
1169 lines =<< trim END
1170 vim9script
1171
1172 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001173 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001174 this.errpos: number
1175 endinterface
1176
1177 # order of members is opposite of interface
1178 class Failure implements Result
1179 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001180 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001181 endclass
1182
1183 def Test()
1184 var result: Result = Failure.new()
1185
1186 assert_equal('label', result.label)
1187 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001188
1189 result.label = 'different'
1190 assert_equal('different', result.label)
1191 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001192 enddef
1193
1194 Test()
1195 END
1196 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001197enddef
1198
Bram Moolenaard0200c82023-01-28 15:19:40 +00001199def Test_call_interface_method()
1200 var lines =<< trim END
1201 vim9script
1202 interface Base
1203 def Enter(): void
1204 endinterface
1205
1206 class Child implements Base
1207 def Enter(): void
1208 g:result ..= 'child'
1209 enddef
1210 endclass
1211
1212 def F(obj: Base)
1213 obj.Enter()
1214 enddef
1215
1216 g:result = ''
1217 F(Child.new())
1218 assert_equal('child', g:result)
1219 unlet g:result
1220 END
1221 v9.CheckScriptSuccess(lines)
1222
1223 lines =<< trim END
1224 vim9script
1225 class Base
1226 def Enter(): void
1227 g:result ..= 'base'
1228 enddef
1229 endclass
1230
1231 class Child extends Base
1232 def Enter(): void
1233 g:result ..= 'child'
1234 enddef
1235 endclass
1236
1237 def F(obj: Base)
1238 obj.Enter()
1239 enddef
1240
1241 g:result = ''
1242 F(Child.new())
1243 assert_equal('child', g:result)
1244 unlet g:result
1245 END
1246 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001247
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001248 # method of interface returns a value
1249 lines =<< trim END
1250 vim9script
1251 interface Base
1252 def Enter(): string
1253 endinterface
1254
1255 class Child implements Base
1256 def Enter(): string
1257 g:result ..= 'child'
1258 return "/resource"
1259 enddef
1260 endclass
1261
1262 def F(obj: Base)
1263 var r = obj.Enter()
1264 g:result ..= r
1265 enddef
1266
1267 g:result = ''
1268 F(Child.new())
1269 assert_equal('child/resource', g:result)
1270 unlet g:result
1271 END
1272 v9.CheckScriptSuccess(lines)
1273
1274 lines =<< trim END
1275 vim9script
1276 class Base
1277 def Enter(): string
1278 return null_string
1279 enddef
1280 endclass
1281
1282 class Child extends Base
1283 def Enter(): string
1284 g:result ..= 'child'
1285 return "/resource"
1286 enddef
1287 endclass
1288
1289 def F(obj: Base)
1290 var r = obj.Enter()
1291 g:result ..= r
1292 enddef
1293
1294 g:result = ''
1295 F(Child.new())
1296 assert_equal('child/resource', g:result)
1297 unlet g:result
1298 END
1299 v9.CheckScriptSuccess(lines)
1300
1301
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001302 # No class that implements the interface.
1303 lines =<< trim END
1304 vim9script
1305
1306 interface IWithEE
1307 def Enter(): any
1308 def Exit(): void
1309 endinterface
1310
1311 def With1(ee: IWithEE, F: func)
1312 var r = ee.Enter()
1313 enddef
1314
1315 defcompile
1316 END
1317 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001318enddef
1319
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001320def Test_class_used_as_type()
1321 var lines =<< trim END
1322 vim9script
1323
1324 class Point
1325 this.x = 0
1326 this.y = 0
1327 endclass
1328
1329 var p: Point
1330 p = Point.new(2, 33)
1331 assert_equal(2, p.x)
1332 assert_equal(33, p.y)
1333 END
1334 v9.CheckScriptSuccess(lines)
1335
1336 lines =<< trim END
1337 vim9script
1338
1339 interface HasX
1340 this.x: number
1341 endinterface
1342
1343 class Point implements HasX
1344 this.x = 0
1345 this.y = 0
1346 endclass
1347
1348 var p: Point
1349 p = Point.new(2, 33)
1350 var hx = p
1351 assert_equal(2, hx.x)
1352 END
1353 v9.CheckScriptSuccess(lines)
1354
1355 lines =<< trim END
1356 vim9script
1357
1358 class Point
1359 this.x = 0
1360 this.y = 0
1361 endclass
1362
1363 var p: Point
1364 p = 'text'
1365 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001366 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001367enddef
1368
Bram Moolenaar83677162023-01-08 19:54:10 +00001369def Test_class_extends()
1370 var lines =<< trim END
1371 vim9script
1372 class Base
1373 this.one = 1
1374 def GetOne(): number
1375 return this.one
1376 enddef
1377 endclass
1378 class Child extends Base
1379 this.two = 2
1380 def GetTotal(): number
1381 return this.one + this.two
1382 enddef
1383 endclass
1384 var o = Child.new()
1385 assert_equal(1, o.one)
1386 assert_equal(2, o.two)
1387 assert_equal(1, o.GetOne())
1388 assert_equal(3, o.GetTotal())
1389 END
1390 v9.CheckScriptSuccess(lines)
1391
1392 lines =<< trim END
1393 vim9script
1394 class Base
1395 this.one = 1
1396 endclass
1397 class Child extends Base
1398 this.two = 2
1399 endclass
1400 var o = Child.new(3, 44)
1401 assert_equal(3, o.one)
1402 assert_equal(44, o.two)
1403 END
1404 v9.CheckScriptSuccess(lines)
1405
1406 lines =<< trim END
1407 vim9script
1408 class Base
1409 this.one = 1
1410 endclass
1411 class Child extends Base extends Base
1412 this.two = 2
1413 endclass
1414 END
1415 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1416
1417 lines =<< trim END
1418 vim9script
1419 class Child extends BaseClass
1420 this.two = 2
1421 endclass
1422 END
1423 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1424
1425 lines =<< trim END
1426 vim9script
1427 var SomeVar = 99
1428 class Child extends SomeVar
1429 this.two = 2
1430 endclass
1431 END
1432 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001433
1434 lines =<< trim END
1435 vim9script
1436 class Base
1437 this.name: string
1438 def ToString(): string
1439 return this.name
1440 enddef
1441 endclass
1442
1443 class Child extends Base
1444 this.age: number
1445 def ToString(): string
1446 return super.ToString() .. ': ' .. this.age
1447 enddef
1448 endclass
1449
1450 var o = Child.new('John', 42)
1451 assert_equal('John: 42', o.ToString())
1452 END
1453 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001454
1455 lines =<< trim END
1456 vim9script
1457 class Child
1458 this.age: number
1459 def ToString(): number
1460 return this.age
1461 enddef
1462 def ToString(): string
1463 return this.age
1464 enddef
1465 endclass
1466 END
1467 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1468
1469 lines =<< trim END
1470 vim9script
1471 class Child
1472 this.age: number
1473 def ToString(): string
1474 return super .ToString() .. ': ' .. this.age
1475 enddef
1476 endclass
1477 var o = Child.new(42)
1478 echo o.ToString()
1479 END
1480 v9.CheckScriptFailure(lines, 'E1356:')
1481
1482 lines =<< trim END
1483 vim9script
1484 class Base
1485 this.name: string
1486 def ToString(): string
1487 return this.name
1488 enddef
1489 endclass
1490
1491 var age = 42
1492 def ToString(): string
1493 return super.ToString() .. ': ' .. age
1494 enddef
1495 echo ToString()
1496 END
1497 v9.CheckScriptFailure(lines, 'E1357:')
1498
1499 lines =<< trim END
1500 vim9script
1501 class Child
1502 this.age: number
1503 def ToString(): string
1504 return super.ToString() .. ': ' .. this.age
1505 enddef
1506 endclass
1507 var o = Child.new(42)
1508 echo o.ToString()
1509 END
1510 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001511
1512 lines =<< trim END
1513 vim9script
1514 class Base
1515 this.name: string
1516 static def ToString(): string
1517 return 'Base class'
1518 enddef
1519 endclass
1520
1521 class Child extends Base
1522 this.age: number
1523 def ToString(): string
1524 return Base.ToString() .. ': ' .. this.age
1525 enddef
1526 endclass
1527
1528 var o = Child.new('John', 42)
1529 assert_equal('Base class: 42', o.ToString())
1530 END
1531 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001532
1533 lines =<< trim END
1534 vim9script
1535 class Base
1536 this.value = 1
1537 def new(init: number)
1538 this.value = number + 1
1539 enddef
1540 endclass
1541 class Child extends Base
1542 def new()
1543 this.new(3)
1544 enddef
1545 endclass
1546 var c = Child.new()
1547 END
1548 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001549
1550 # base class with more than one object member
1551 lines =<< trim END
1552 vim9script
1553
1554 class Result
1555 this.success: bool
1556 this.value: any = null
1557 endclass
1558
1559 class Success extends Result
1560 def new(this.value = v:none)
1561 this.success = true
1562 enddef
1563 endclass
1564
1565 var v = Success.new('asdf')
1566 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1567 END
1568 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001569enddef
1570
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001571def Test_using_base_class()
1572 var lines =<< trim END
1573 vim9script
1574
1575 class BaseEE
1576 def Enter(): any
1577 return null
1578 enddef
1579 def Exit(resource: any): void
1580 enddef
1581 endclass
1582
1583 class ChildEE extends BaseEE
1584 def Enter(): any
1585 return 42
1586 enddef
1587
1588 def Exit(resource: number): void
1589 g:result ..= '/exit'
1590 enddef
1591 endclass
1592
1593 def With(ee: BaseEE)
1594 var r = ee.Enter()
1595 try
1596 g:result ..= r
1597 finally
1598 g:result ..= '/finally'
1599 ee.Exit(r)
1600 endtry
1601 enddef
1602
1603 g:result = ''
1604 With(ChildEE.new())
1605 assert_equal('42/finally/exit', g:result)
1606 END
1607 v9.CheckScriptSuccess(lines)
1608 unlet g:result
1609enddef
1610
1611
Bram Moolenaara86655a2023-01-12 17:06:27 +00001612def Test_class_import()
1613 var lines =<< trim END
1614 vim9script
1615 export class Animal
1616 this.kind: string
1617 this.name: string
1618 endclass
1619 END
1620 writefile(lines, 'Xanimal.vim', 'D')
1621
1622 lines =<< trim END
1623 vim9script
1624 import './Xanimal.vim' as animal
1625
1626 var a: animal.Animal
1627 a = animal.Animal.new('fish', 'Eric')
1628 assert_equal('fish', a.kind)
1629 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001630
1631 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1632 assert_equal('cat', b.kind)
1633 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001634 END
1635 v9.CheckScriptSuccess(lines)
1636enddef
1637
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001638def Test_abstract_class()
1639 var lines =<< trim END
1640 vim9script
1641 abstract class Base
1642 this.name: string
1643 endclass
1644 class Person extends Base
1645 this.age: number
1646 endclass
1647 var p: Base = Person.new('Peter', 42)
1648 assert_equal('Peter', p.name)
1649 assert_equal(42, p.age)
1650 END
1651 v9.CheckScriptSuccess(lines)
1652
1653 lines =<< trim END
1654 vim9script
1655 abstract class Base
1656 this.name: string
1657 endclass
1658 class Person extends Base
1659 this.age: number
1660 endclass
1661 var p = Base.new('Peter')
1662 END
1663 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1664
1665 lines =<< trim END
1666 abstract class Base
1667 this.name: string
1668 endclass
1669 END
1670 v9.CheckScriptFailure(lines, 'E1316:')
1671enddef
1672
Bram Moolenaar486fc252023-01-18 14:51:07 +00001673def Test_closure_in_class()
1674 var lines =<< trim END
1675 vim9script
1676
1677 class Foo
1678 this.y: list<string> = ['B']
1679
1680 def new()
1681 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1682 enddef
1683 endclass
1684
1685 Foo.new()
1686 assert_equal(['A'], g:result)
1687 END
1688 v9.CheckScriptSuccess(lines)
1689enddef
1690
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001691def Test_defer_with_object()
1692 var lines =<< trim END
1693 vim9script
1694
1695 class CWithEE
1696 def Enter()
1697 g:result ..= "entered/"
1698 enddef
1699 def Exit()
1700 g:result ..= "exited"
1701 enddef
1702 endclass
1703
1704 def With(ee: CWithEE, F: func)
1705 ee.Enter()
1706 defer ee.Exit()
1707 F()
1708 enddef
1709
1710 g:result = ''
1711 var obj = CWithEE.new()
1712 obj->With(() => {
1713 g:result ..= "called/"
1714 })
1715 assert_equal('entered/called/exited', g:result)
1716 END
1717 v9.CheckScriptSuccess(lines)
1718 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00001719
1720 lines =<< trim END
1721 vim9script
1722
1723 class BaseWithEE
1724 def Enter()
1725 g:result ..= "entered-base/"
1726 enddef
1727 def Exit()
1728 g:result ..= "exited-base"
1729 enddef
1730 endclass
1731
1732 class CWithEE extends BaseWithEE
1733 def Enter()
1734 g:result ..= "entered-child/"
1735 enddef
1736 def Exit()
1737 g:result ..= "exited-child"
1738 enddef
1739 endclass
1740
1741 def With(ee: BaseWithEE, F: func)
1742 ee.Enter()
1743 defer ee.Exit()
1744 F()
1745 enddef
1746
1747 g:result = ''
1748 var obj = CWithEE.new()
1749 obj->With(() => {
1750 g:result ..= "called/"
1751 })
1752 assert_equal('entered-child/called/exited-child', g:result)
1753 END
1754 v9.CheckScriptSuccess(lines)
1755 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001756enddef
1757
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001758
1759" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker