blob: c228f2642ba3c0f03ef75200f094aea3cce27e39 [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 Moolenaar657aea72023-01-27 13:16:19 +0000206def Test_class_interface_wrong_end()
207 var lines =<< trim END
208 vim9script
209 abstract class SomeName
210 this.member = 'text'
211 endinterface
212 END
213 v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
214
215 lines =<< trim END
216 vim9script
217 export interface AnotherName
218 this.member: string
219 endclass
220 END
221 v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
222enddef
223
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000224def Test_object_not_set()
225 var lines =<< trim END
226 vim9script
227
228 class State
229 this.value = 'xyz'
230 endclass
231
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000232 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000233 var db = {'xyz': 789}
234 echo db[state.value]
235 END
236 v9.CheckScriptFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000237
238 lines =<< trim END
239 vim9script
240
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000241 class Class
242 this.id: string
243 def Method1()
244 echo 'Method1' .. this.id
245 enddef
246 endclass
247
248 var obj: Class
249 def Func()
250 obj.Method1()
251 enddef
252 Func()
253 END
254 v9.CheckScriptFailure(lines, 'E1360:')
255
256 lines =<< trim END
257 vim9script
258
Bram Moolenaar0917e862023-02-18 14:42:44 +0000259 class Background
260 this.background = 'dark'
261 endclass
262
263 class Colorscheme
264 this._bg: Background
265
266 def GetBackground(): string
267 return this._bg.background
268 enddef
269 endclass
270
271 var bg: Background # UNINITIALIZED
272 echo Colorscheme.new(bg).GetBackground()
273 END
274 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Background> but got object<Unknown>')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000275enddef
276
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000277def Test_class_member_initializer()
278 var lines =<< trim END
279 vim9script
280
281 class TextPosition
282 this.lnum: number = 1
283 this.col: number = 1
284
Bram Moolenaar418b5472022-12-20 13:38:22 +0000285 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000286 def new(lnum: number)
287 this.lnum = lnum
288 enddef
289 endclass
290
291 var pos = TextPosition.new(3)
292 assert_equal(3, pos.lnum)
293 assert_equal(1, pos.col)
294
295 var instr = execute('disassemble TextPosition.new')
296 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000297 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000298 '\d PUSHNR 1\_s*' ..
299 '\d STORE_THIS 0\_s*' ..
300 '\d PUSHNR 1\_s*' ..
301 '\d STORE_THIS 1\_s*' ..
302 'this.lnum = lnum\_s*' ..
303 '\d LOAD arg\[-1]\_s*' ..
304 '\d PUSHNR 0\_s*' ..
305 '\d LOAD $0\_s*' ..
306 '\d\+ STOREINDEX object\_s*' ..
307 '\d\+ RETURN object.*',
308 instr)
309 END
310 v9.CheckScriptSuccess(lines)
311enddef
312
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000313def Test_member_any_used_as_object()
314 var lines =<< trim END
315 vim9script
316
317 class Inner
318 this.value: number = 0
319 endclass
320
321 class Outer
322 this.inner: any
323 endclass
324
325 def F(outer: Outer)
326 outer.inner.value = 1
327 enddef
328
329 var inner_obj = Inner.new(0)
330 var outer_obj = Outer.new(inner_obj)
331 F(outer_obj)
332 assert_equal(1, inner_obj.value)
333 END
334 v9.CheckScriptSuccess(lines)
335
336 lines =<< trim END
337 vim9script
338
339 class Inner
340 this.value: number = 0
341 endclass
342
343 class Outer
344 this.inner: Inner
345 endclass
346
347 def F(outer: Outer)
348 outer.inner.value = 1
349 enddef
350
351 def Test_assign_to_nested_typed_member()
352 var inner = Inner.new(0)
353 var outer = Outer.new(inner)
354 F(outer)
355 assert_equal(1, inner.value)
356 enddef
357
358 Test_assign_to_nested_typed_member()
359 END
360 v9.CheckScriptSuccess(lines)
361enddef
362
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000363def Test_assignment_with_operator()
364 var lines =<< trim END
365 vim9script
366
367 class Foo
368 this.x: number
369
370 def Add(n: number)
371 this.x += n
372 enddef
373 endclass
374
375 var f = Foo.new(3)
376 f.Add(17)
377 assert_equal(20, f.x)
378 END
379 v9.CheckScriptSuccess(lines)
380enddef
381
Bram Moolenaarf4508042023-01-15 16:54:57 +0000382def Test_list_of_objects()
383 var lines =<< trim END
384 vim9script
385
386 class Foo
387 def Add()
388 enddef
389 endclass
390
391 def ProcessList(fooList: list<Foo>)
392 for foo in fooList
393 foo.Add()
394 endfor
395 enddef
396
397 var l: list<Foo> = [Foo.new()]
398 ProcessList(l)
399 END
400 v9.CheckScriptSuccess(lines)
401enddef
402
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000403def Test_expr_after_using_object()
404 var lines =<< trim END
405 vim9script
406
407 class Something
408 this.label: string = ''
409 endclass
410
411 def Foo(): Something
412 var v = Something.new()
413 echo 'in Foo(): ' .. typename(v)
414 return v
415 enddef
416
417 Foo()
418 END
419 v9.CheckScriptSuccess(lines)
420enddef
421
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000422def Test_class_default_new()
423 var lines =<< trim END
424 vim9script
425
426 class TextPosition
427 this.lnum: number = 1
428 this.col: number = 1
429 endclass
430
431 var pos = TextPosition.new()
432 assert_equal(1, pos.lnum)
433 assert_equal(1, pos.col)
434
435 pos = TextPosition.new(v:none, v:none)
436 assert_equal(1, pos.lnum)
437 assert_equal(1, pos.col)
438
439 pos = TextPosition.new(3, 22)
440 assert_equal(3, pos.lnum)
441 assert_equal(22, pos.col)
442
443 pos = TextPosition.new(v:none, 33)
444 assert_equal(1, pos.lnum)
445 assert_equal(33, pos.col)
446 END
447 v9.CheckScriptSuccess(lines)
448
449 lines =<< trim END
450 vim9script
451 class Person
452 this.name: string
453 this.age: number = 42
454 this.education: string = "unknown"
455
456 def new(this.name, this.age = v:none, this.education = v:none)
457 enddef
458 endclass
459
460 var piet = Person.new("Piet")
461 assert_equal("Piet", piet.name)
462 assert_equal(42, piet.age)
463 assert_equal("unknown", piet.education)
464
465 var chris = Person.new("Chris", 4, "none")
466 assert_equal("Chris", chris.name)
467 assert_equal(4, chris.age)
468 assert_equal("none", chris.education)
469 END
470 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000471
472 lines =<< trim END
473 vim9script
474 class Person
475 this.name: string
476 this.age: number = 42
477 this.education: string = "unknown"
478
479 def new(this.name, this.age = v:none, this.education = v:none)
480 enddef
481 endclass
482
483 var missing = Person.new()
484 END
485 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000486enddef
487
Bram Moolenaar74e12742022-12-13 21:14:28 +0000488def Test_class_object_member_inits()
489 var lines =<< trim END
490 vim9script
491 class TextPosition
492 this.lnum: number
493 this.col = 1
494 this.addcol: number = 2
495 endclass
496
497 var pos = TextPosition.new()
498 assert_equal(0, pos.lnum)
499 assert_equal(1, pos.col)
500 assert_equal(2, pos.addcol)
501 END
502 v9.CheckScriptSuccess(lines)
503
504 lines =<< trim END
505 vim9script
506 class TextPosition
507 this.lnum
508 this.col = 1
509 endclass
510 END
511 v9.CheckScriptFailure(lines, 'E1022:')
512
513 lines =<< trim END
514 vim9script
515 class TextPosition
516 this.lnum = v:none
517 this.col = 1
518 endclass
519 END
520 v9.CheckScriptFailure(lines, 'E1330:')
521enddef
522
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000523def Test_class_object_member_access()
524 var lines =<< trim END
525 vim9script
526 class Triple
527 this._one = 1
528 this.two = 2
529 public this.three = 3
530
531 def GetOne(): number
532 return this._one
533 enddef
534 endclass
535
536 var trip = Triple.new()
537 assert_equal(1, trip.GetOne())
538 assert_equal(2, trip.two)
539 assert_equal(3, trip.three)
540 assert_fails('echo trip._one', 'E1333')
541
542 assert_fails('trip._one = 11', 'E1333')
543 assert_fails('trip.two = 22', 'E1335')
544 trip.three = 33
545 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000546
547 assert_fails('trip.four = 4', 'E1334')
548 END
549 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000550
551 lines =<< trim END
552 vim9script
553
554 class MyCar
555 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000556 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000557
558 def new(make_arg: string)
559 this.make = make_arg
560 enddef
561
562 def GetMake(): string
563 return $"make = {this.make}"
564 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000565 def GetAge(): number
566 return this.age
567 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000568 endclass
569
570 var c = MyCar.new("abc")
571 assert_equal('make = abc', c.GetMake())
572
573 c = MyCar.new("def")
574 assert_equal('make = def', c.GetMake())
575
576 var c2 = MyCar.new("123")
577 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000578
579 def CheckCar()
580 assert_equal("make = def", c.GetMake())
581 assert_equal(5, c.GetAge())
582 enddef
583 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000584 END
585 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000586
587 lines =<< trim END
588 vim9script
589
590 class MyCar
591 this.make: string
592
593 def new(make_arg: string)
594 this.make = make_arg
595 enddef
596 endclass
597
598 var c = MyCar.new("abc")
599 var c = MyCar.new("def")
600 END
601 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000602
603 lines =<< trim END
604 vim9script
605
606 class Foo
607 this.x: list<number> = []
608
609 def Add(n: number): any
610 this.x->add(n)
611 return this
612 enddef
613 endclass
614
615 echo Foo.new().Add(1).Add(2).x
616 echo Foo.new().Add(1).Add(2)
617 .x
618 echo Foo.new().Add(1)
619 .Add(2).x
620 echo Foo.new()
621 .Add(1).Add(2).x
622 echo Foo.new()
623 .Add(1)
624 .Add(2)
625 .x
626 END
627 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000628enddef
629
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000630def Test_class_object_compare()
631 var class_lines =<< trim END
632 vim9script
633 class Item
634 this.nr = 0
635 this.name = 'xx'
636 endclass
637 END
638
639 # used at the script level and in a compiled function
640 var test_lines =<< trim END
641 var i1 = Item.new()
642 assert_equal(i1, i1)
643 assert_true(i1 is i1)
644 var i2 = Item.new()
645 assert_equal(i1, i2)
646 assert_false(i1 is i2)
647 var i3 = Item.new(0, 'xx')
648 assert_equal(i1, i3)
649
650 var io1 = Item.new(1, 'xx')
651 assert_notequal(i1, io1)
652 var io2 = Item.new(0, 'yy')
653 assert_notequal(i1, io2)
654 END
655
656 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000657 v9.CheckScriptSuccess(
658 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000659
660 for op in ['>', '>=', '<', '<=', '=~', '!~']
661 var op_lines = [
662 'var i1 = Item.new()',
663 'var i2 = Item.new()',
664 'echo i1 ' .. op .. ' i2',
665 ]
666 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000667 v9.CheckScriptFailure(class_lines
668 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000669 endfor
670enddef
671
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000672def Test_object_type()
673 var lines =<< trim END
674 vim9script
675
676 class One
677 this.one = 1
678 endclass
679 class Two
680 this.two = 2
681 endclass
682 class TwoMore extends Two
683 this.more = 9
684 endclass
685
686 var o: One = One.new()
687 var t: Two = Two.new()
688 var m: TwoMore = TwoMore.new()
689 var tm: Two = TwoMore.new()
690
691 t = m
692 END
693 v9.CheckScriptSuccess(lines)
694
695 lines =<< trim END
696 vim9script
697
698 class One
699 this.one = 1
700 endclass
701 class Two
702 this.two = 2
703 endclass
704
705 var o: One = Two.new()
706 END
707 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000708
709 lines =<< trim END
710 vim9script
711
712 interface One
713 def GetMember(): number
714 endinterface
715 class Two implements One
716 this.one = 1
717 def GetMember(): number
718 return this.one
719 enddef
720 endclass
721
722 var o: One = Two.new(5)
723 assert_equal(5, o.GetMember())
724 END
725 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000726
727 lines =<< trim END
728 vim9script
729
730 class Num
731 this.n: number = 0
732 endclass
733
734 def Ref(name: string): func(Num): Num
735 return (arg: Num): Num => {
736 return eval(name)(arg)
737 }
738 enddef
739
740 const Fn = Ref('Double')
741 var Double = (m: Num): Num => Num.new(m.n * 2)
742
743 echo Fn(Num.new(4))
744 END
745 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000746enddef
747
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000748def Test_class_member()
749 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000750 var lines =<< trim END
751 vim9script
752 class TextPos
753 this.lnum = 1
754 this.col = 1
755 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000756 static _secret = 7
757 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000758
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000759 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000760 counter += nr
761 enddef
762 endclass
763
764 assert_equal(0, TextPos.counter)
765 TextPos.AddToCounter(3)
766 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000767 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000768
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000769 def GetCounter(): number
770 return TextPos.counter
771 enddef
772 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000773
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000774 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000775 assert_fails('TextPos.counter = 5', 'E1335:')
776 assert_fails('TextPos.counter += 5', 'E1335:')
777
778 assert_fails('echo TextPos._secret', 'E1333:')
779 assert_fails('TextPos._secret = 8', 'E1333:')
780
781 assert_equal(42, TextPos.anybody)
782 TextPos.anybody = 12
783 assert_equal(12, TextPos.anybody)
784 TextPos.anybody += 5
785 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000786 END
787 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000788
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000789 # example in the help
790 lines =<< trim END
791 vim9script
792 class OtherThing
793 this.size: number
794 static totalSize: number
795
796 def new(this.size)
797 totalSize += this.size
798 enddef
799 endclass
800 assert_equal(0, OtherThing.totalSize)
801 var to3 = OtherThing.new(3)
802 assert_equal(3, OtherThing.totalSize)
803 var to7 = OtherThing.new(7)
804 assert_equal(10, OtherThing.totalSize)
805 END
806 v9.CheckScriptSuccess(lines)
807
Bram Moolenaar62a69232023-01-24 15:07:04 +0000808 # access private member in lambda
809 lines =<< trim END
810 vim9script
811
812 class Foo
813 this._x: number = 0
814
815 def Add(n: number): number
816 const F = (): number => this._x + n
817 return F()
818 enddef
819 endclass
820
821 var foo = Foo.new()
822 assert_equal(5, foo.Add(5))
823 END
824 v9.CheckScriptSuccess(lines)
825
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000826 # check shadowing
827 lines =<< trim END
828 vim9script
829
830 class Some
831 static count = 0
832 def Method(count: number)
833 echo count
834 enddef
835 endclass
836
837 var s = Some.new()
838 s.Method(7)
839 END
840 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
841
842 lines =<< trim END
843 vim9script
844
845 class Some
846 static count = 0
847 def Method(arg: number)
848 var count = 3
849 echo arg count
850 enddef
851 endclass
852
853 var s = Some.new()
854 s.Method(7)
855 END
856 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000857enddef
858
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000859func Test_class_garbagecollect()
860 let lines =<< trim END
861 vim9script
862
863 class Point
864 this.p = [2, 3]
865 static pl = ['a', 'b']
866 static pd = {a: 'a', b: 'b'}
867 endclass
868
869 echo Point.pl Point.pd
870 call test_garbagecollect_now()
871 echo Point.pl Point.pd
872 END
873 call v9.CheckScriptSuccess(lines)
874endfunc
875
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000876def Test_class_function()
877 var lines =<< trim END
878 vim9script
879 class Value
880 this.value = 0
881 static objects = 0
882
883 def new(v: number)
884 this.value = v
885 ++objects
886 enddef
887
888 static def GetCount(): number
889 return objects
890 enddef
891 endclass
892
893 assert_equal(0, Value.GetCount())
894 var v1 = Value.new(2)
895 assert_equal(1, Value.GetCount())
896 var v2 = Value.new(7)
897 assert_equal(2, Value.GetCount())
898 END
899 v9.CheckScriptSuccess(lines)
900enddef
901
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +0000902def Test_class_defcompile()
903 var lines =<< trim END
904 vim9script
905
906 class C
907 def Fo(i: number): string
908 return i
909 enddef
910 endclass
911
912 defcompile C.Fo
913 END
914 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
915
916 lines =<< trim END
917 vim9script
918
919 class C
920 static def Fc(): number
921 return 'x'
922 enddef
923 endclass
924
925 defcompile C.Fc
926 END
927 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
928enddef
929
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000930def Test_class_object_to_string()
931 var lines =<< trim END
932 vim9script
933 class TextPosition
934 this.lnum = 1
935 this.col = 22
936 endclass
937
938 assert_equal("class TextPosition", string(TextPosition))
939
940 var pos = TextPosition.new()
941 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
942 END
943 v9.CheckScriptSuccess(lines)
944enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000945
Bram Moolenaar554d0312023-01-05 19:59:18 +0000946def Test_interface_basics()
947 var lines =<< trim END
948 vim9script
949 interface Something
950 this.value: string
951 static count: number
952 def GetCount(): number
953 endinterface
954 END
955 v9.CheckScriptSuccess(lines)
956
957 lines =<< trim END
958 interface SomethingWrong
959 static count = 7
960 endinterface
961 END
962 v9.CheckScriptFailure(lines, 'E1342:')
963
964 lines =<< trim END
965 vim9script
966
967 interface Some
968 static count: number
969 def Method(count: number)
970 endinterface
971 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000972 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
973
974 lines =<< trim END
975 vim9script
976
977 interface Some
978 this.value: number
979 def Method(value: number)
980 endinterface
981 END
982 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +0000983
984 lines =<< trim END
985 vim9script
986 interface somethingWrong
987 static count = 7
988 endinterface
989 END
990 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
991
992 lines =<< trim END
993 vim9script
994 interface SomethingWrong
995 this.value: string
996 static count = 7
997 def GetCount(): number
998 endinterface
999 END
1000 v9.CheckScriptFailure(lines, 'E1344:')
1001
1002 lines =<< trim END
1003 vim9script
1004 interface SomethingWrong
1005 this.value: string
1006 static count: number
1007 def GetCount(): number
1008 return 5
1009 enddef
1010 endinterface
1011 END
1012 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001013
1014 lines =<< trim END
1015 vim9script
1016 export interface EnterExit
1017 def Enter(): void
1018 def Exit(): void
1019 endinterface
1020 END
1021 writefile(lines, 'XdefIntf.vim', 'D')
1022
1023 lines =<< trim END
1024 vim9script
1025 import './XdefIntf.vim' as defIntf
1026 export def With(ee: defIntf.EnterExit, F: func)
1027 ee.Enter()
1028 try
1029 F()
1030 finally
1031 ee.Exit()
1032 endtry
1033 enddef
1034 END
1035 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001036
1037 var imported =<< trim END
1038 vim9script
1039 export abstract class EnterExit
1040 def Enter(): void
1041 enddef
1042 def Exit(): void
1043 enddef
1044 endclass
1045 END
1046 writefile(imported, 'XdefIntf2.vim', 'D')
1047
1048 lines[1] = " import './XdefIntf2.vim' as defIntf"
1049 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001050enddef
1051
Bram Moolenaar94674f22023-01-06 18:42:20 +00001052def Test_class_implements_interface()
1053 var lines =<< trim END
1054 vim9script
1055
1056 interface Some
1057 static count: number
1058 def Method(nr: number)
1059 endinterface
1060
1061 class SomeImpl implements Some
1062 static count: number
1063 def Method(nr: number)
1064 echo nr
1065 enddef
1066 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001067
1068 interface Another
1069 this.member: string
1070 endinterface
1071
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001072 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001073 this.member = 'abc'
1074 static count: number
1075 def Method(nr: number)
1076 echo nr
1077 enddef
1078 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001079 END
1080 v9.CheckScriptSuccess(lines)
1081
1082 lines =<< trim END
1083 vim9script
1084
1085 interface Some
1086 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001087 endinterface
1088
1089 class SomeImpl implements Some implements Some
1090 static count: number
1091 endclass
1092 END
1093 v9.CheckScriptFailure(lines, 'E1350:')
1094
1095 lines =<< trim END
1096 vim9script
1097
1098 interface Some
1099 static counter: number
1100 endinterface
1101
1102 class SomeImpl implements Some, Some
1103 static count: number
1104 endclass
1105 END
1106 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1107
1108 lines =<< trim END
1109 vim9script
1110
1111 interface Some
1112 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001113 def Method(nr: number)
1114 endinterface
1115
1116 class SomeImpl implements Some
1117 static count: number
1118 def Method(nr: number)
1119 echo nr
1120 enddef
1121 endclass
1122 END
1123 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1124
1125 lines =<< trim END
1126 vim9script
1127
1128 interface Some
1129 static count: number
1130 def Methods(nr: number)
1131 endinterface
1132
1133 class SomeImpl implements Some
1134 static count: number
1135 def Method(nr: number)
1136 echo nr
1137 enddef
1138 endclass
1139 END
1140 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001141
1142 # Check different order of members in class and interface works.
1143 lines =<< trim END
1144 vim9script
1145
1146 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001147 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001148 this.errpos: number
1149 endinterface
1150
1151 # order of members is opposite of interface
1152 class Failure implements Result
1153 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001154 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001155 endclass
1156
1157 def Test()
1158 var result: Result = Failure.new()
1159
1160 assert_equal('label', result.label)
1161 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001162
1163 result.label = 'different'
1164 assert_equal('different', result.label)
1165 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001166 enddef
1167
1168 Test()
1169 END
1170 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001171enddef
1172
Bram Moolenaard0200c82023-01-28 15:19:40 +00001173def Test_call_interface_method()
1174 var lines =<< trim END
1175 vim9script
1176 interface Base
1177 def Enter(): void
1178 endinterface
1179
1180 class Child implements Base
1181 def Enter(): void
1182 g:result ..= 'child'
1183 enddef
1184 endclass
1185
1186 def F(obj: Base)
1187 obj.Enter()
1188 enddef
1189
1190 g:result = ''
1191 F(Child.new())
1192 assert_equal('child', g:result)
1193 unlet g:result
1194 END
1195 v9.CheckScriptSuccess(lines)
1196
1197 lines =<< trim END
1198 vim9script
1199 class Base
1200 def Enter(): void
1201 g:result ..= 'base'
1202 enddef
1203 endclass
1204
1205 class Child extends Base
1206 def Enter(): void
1207 g:result ..= 'child'
1208 enddef
1209 endclass
1210
1211 def F(obj: Base)
1212 obj.Enter()
1213 enddef
1214
1215 g:result = ''
1216 F(Child.new())
1217 assert_equal('child', g:result)
1218 unlet g:result
1219 END
1220 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001221
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001222 # method of interface returns a value
1223 lines =<< trim END
1224 vim9script
1225 interface Base
1226 def Enter(): string
1227 endinterface
1228
1229 class Child implements Base
1230 def Enter(): string
1231 g:result ..= 'child'
1232 return "/resource"
1233 enddef
1234 endclass
1235
1236 def F(obj: Base)
1237 var r = obj.Enter()
1238 g:result ..= r
1239 enddef
1240
1241 g:result = ''
1242 F(Child.new())
1243 assert_equal('child/resource', g:result)
1244 unlet g:result
1245 END
1246 v9.CheckScriptSuccess(lines)
1247
1248 lines =<< trim END
1249 vim9script
1250 class Base
1251 def Enter(): string
1252 return null_string
1253 enddef
1254 endclass
1255
1256 class Child extends Base
1257 def Enter(): string
1258 g:result ..= 'child'
1259 return "/resource"
1260 enddef
1261 endclass
1262
1263 def F(obj: Base)
1264 var r = obj.Enter()
1265 g:result ..= r
1266 enddef
1267
1268 g:result = ''
1269 F(Child.new())
1270 assert_equal('child/resource', g:result)
1271 unlet g:result
1272 END
1273 v9.CheckScriptSuccess(lines)
1274
1275
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001276 # No class that implements the interface.
1277 lines =<< trim END
1278 vim9script
1279
1280 interface IWithEE
1281 def Enter(): any
1282 def Exit(): void
1283 endinterface
1284
1285 def With1(ee: IWithEE, F: func)
1286 var r = ee.Enter()
1287 enddef
1288
1289 defcompile
1290 END
1291 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001292enddef
1293
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001294def Test_class_used_as_type()
1295 var lines =<< trim END
1296 vim9script
1297
1298 class Point
1299 this.x = 0
1300 this.y = 0
1301 endclass
1302
1303 var p: Point
1304 p = Point.new(2, 33)
1305 assert_equal(2, p.x)
1306 assert_equal(33, p.y)
1307 END
1308 v9.CheckScriptSuccess(lines)
1309
1310 lines =<< trim END
1311 vim9script
1312
1313 interface HasX
1314 this.x: number
1315 endinterface
1316
1317 class Point implements HasX
1318 this.x = 0
1319 this.y = 0
1320 endclass
1321
1322 var p: Point
1323 p = Point.new(2, 33)
1324 var hx = p
1325 assert_equal(2, hx.x)
1326 END
1327 v9.CheckScriptSuccess(lines)
1328
1329 lines =<< trim END
1330 vim9script
1331
1332 class Point
1333 this.x = 0
1334 this.y = 0
1335 endclass
1336
1337 var p: Point
1338 p = 'text'
1339 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001340 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001341enddef
1342
Bram Moolenaar83677162023-01-08 19:54:10 +00001343def Test_class_extends()
1344 var lines =<< trim END
1345 vim9script
1346 class Base
1347 this.one = 1
1348 def GetOne(): number
1349 return this.one
1350 enddef
1351 endclass
1352 class Child extends Base
1353 this.two = 2
1354 def GetTotal(): number
1355 return this.one + this.two
1356 enddef
1357 endclass
1358 var o = Child.new()
1359 assert_equal(1, o.one)
1360 assert_equal(2, o.two)
1361 assert_equal(1, o.GetOne())
1362 assert_equal(3, o.GetTotal())
1363 END
1364 v9.CheckScriptSuccess(lines)
1365
1366 lines =<< trim END
1367 vim9script
1368 class Base
1369 this.one = 1
1370 endclass
1371 class Child extends Base
1372 this.two = 2
1373 endclass
1374 var o = Child.new(3, 44)
1375 assert_equal(3, o.one)
1376 assert_equal(44, o.two)
1377 END
1378 v9.CheckScriptSuccess(lines)
1379
1380 lines =<< trim END
1381 vim9script
1382 class Base
1383 this.one = 1
1384 endclass
1385 class Child extends Base extends Base
1386 this.two = 2
1387 endclass
1388 END
1389 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1390
1391 lines =<< trim END
1392 vim9script
1393 class Child extends BaseClass
1394 this.two = 2
1395 endclass
1396 END
1397 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1398
1399 lines =<< trim END
1400 vim9script
1401 var SomeVar = 99
1402 class Child extends SomeVar
1403 this.two = 2
1404 endclass
1405 END
1406 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001407
1408 lines =<< trim END
1409 vim9script
1410 class Base
1411 this.name: string
1412 def ToString(): string
1413 return this.name
1414 enddef
1415 endclass
1416
1417 class Child extends Base
1418 this.age: number
1419 def ToString(): string
1420 return super.ToString() .. ': ' .. this.age
1421 enddef
1422 endclass
1423
1424 var o = Child.new('John', 42)
1425 assert_equal('John: 42', o.ToString())
1426 END
1427 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001428
1429 lines =<< trim END
1430 vim9script
1431 class Child
1432 this.age: number
1433 def ToString(): number
1434 return this.age
1435 enddef
1436 def ToString(): string
1437 return this.age
1438 enddef
1439 endclass
1440 END
1441 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1442
1443 lines =<< trim END
1444 vim9script
1445 class Child
1446 this.age: number
1447 def ToString(): string
1448 return super .ToString() .. ': ' .. this.age
1449 enddef
1450 endclass
1451 var o = Child.new(42)
1452 echo o.ToString()
1453 END
1454 v9.CheckScriptFailure(lines, 'E1356:')
1455
1456 lines =<< trim END
1457 vim9script
1458 class Base
1459 this.name: string
1460 def ToString(): string
1461 return this.name
1462 enddef
1463 endclass
1464
1465 var age = 42
1466 def ToString(): string
1467 return super.ToString() .. ': ' .. age
1468 enddef
1469 echo ToString()
1470 END
1471 v9.CheckScriptFailure(lines, 'E1357:')
1472
1473 lines =<< trim END
1474 vim9script
1475 class Child
1476 this.age: number
1477 def ToString(): string
1478 return super.ToString() .. ': ' .. this.age
1479 enddef
1480 endclass
1481 var o = Child.new(42)
1482 echo o.ToString()
1483 END
1484 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001485
1486 lines =<< trim END
1487 vim9script
1488 class Base
1489 this.name: string
1490 static def ToString(): string
1491 return 'Base class'
1492 enddef
1493 endclass
1494
1495 class Child extends Base
1496 this.age: number
1497 def ToString(): string
1498 return Base.ToString() .. ': ' .. this.age
1499 enddef
1500 endclass
1501
1502 var o = Child.new('John', 42)
1503 assert_equal('Base class: 42', o.ToString())
1504 END
1505 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001506
1507 lines =<< trim END
1508 vim9script
1509 class Base
1510 this.value = 1
1511 def new(init: number)
1512 this.value = number + 1
1513 enddef
1514 endclass
1515 class Child extends Base
1516 def new()
1517 this.new(3)
1518 enddef
1519 endclass
1520 var c = Child.new()
1521 END
1522 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001523
1524 # base class with more than one object member
1525 lines =<< trim END
1526 vim9script
1527
1528 class Result
1529 this.success: bool
1530 this.value: any = null
1531 endclass
1532
1533 class Success extends Result
1534 def new(this.value = v:none)
1535 this.success = true
1536 enddef
1537 endclass
1538
1539 var v = Success.new('asdf')
1540 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1541 END
1542 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001543enddef
1544
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001545def Test_using_base_class()
1546 var lines =<< trim END
1547 vim9script
1548
1549 class BaseEE
1550 def Enter(): any
1551 return null
1552 enddef
1553 def Exit(resource: any): void
1554 enddef
1555 endclass
1556
1557 class ChildEE extends BaseEE
1558 def Enter(): any
1559 return 42
1560 enddef
1561
1562 def Exit(resource: number): void
1563 g:result ..= '/exit'
1564 enddef
1565 endclass
1566
1567 def With(ee: BaseEE)
1568 var r = ee.Enter()
1569 try
1570 g:result ..= r
1571 finally
1572 g:result ..= '/finally'
1573 ee.Exit(r)
1574 endtry
1575 enddef
1576
1577 g:result = ''
1578 With(ChildEE.new())
1579 assert_equal('42/finally/exit', g:result)
1580 END
1581 v9.CheckScriptSuccess(lines)
1582 unlet g:result
1583enddef
1584
1585
Bram Moolenaara86655a2023-01-12 17:06:27 +00001586def Test_class_import()
1587 var lines =<< trim END
1588 vim9script
1589 export class Animal
1590 this.kind: string
1591 this.name: string
1592 endclass
1593 END
1594 writefile(lines, 'Xanimal.vim', 'D')
1595
1596 lines =<< trim END
1597 vim9script
1598 import './Xanimal.vim' as animal
1599
1600 var a: animal.Animal
1601 a = animal.Animal.new('fish', 'Eric')
1602 assert_equal('fish', a.kind)
1603 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001604
1605 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1606 assert_equal('cat', b.kind)
1607 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001608 END
1609 v9.CheckScriptSuccess(lines)
1610enddef
1611
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001612def Test_abstract_class()
1613 var lines =<< trim END
1614 vim9script
1615 abstract class Base
1616 this.name: string
1617 endclass
1618 class Person extends Base
1619 this.age: number
1620 endclass
1621 var p: Base = Person.new('Peter', 42)
1622 assert_equal('Peter', p.name)
1623 assert_equal(42, p.age)
1624 END
1625 v9.CheckScriptSuccess(lines)
1626
1627 lines =<< trim END
1628 vim9script
1629 abstract class Base
1630 this.name: string
1631 endclass
1632 class Person extends Base
1633 this.age: number
1634 endclass
1635 var p = Base.new('Peter')
1636 END
1637 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1638
1639 lines =<< trim END
1640 abstract class Base
1641 this.name: string
1642 endclass
1643 END
1644 v9.CheckScriptFailure(lines, 'E1316:')
1645enddef
1646
Bram Moolenaar486fc252023-01-18 14:51:07 +00001647def Test_closure_in_class()
1648 var lines =<< trim END
1649 vim9script
1650
1651 class Foo
1652 this.y: list<string> = ['B']
1653
1654 def new()
1655 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1656 enddef
1657 endclass
1658
1659 Foo.new()
1660 assert_equal(['A'], g:result)
1661 END
1662 v9.CheckScriptSuccess(lines)
1663enddef
1664
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001665def Test_defer_with_object()
1666 var lines =<< trim END
1667 vim9script
1668
1669 class CWithEE
1670 def Enter()
1671 g:result ..= "entered/"
1672 enddef
1673 def Exit()
1674 g:result ..= "exited"
1675 enddef
1676 endclass
1677
1678 def With(ee: CWithEE, F: func)
1679 ee.Enter()
1680 defer ee.Exit()
1681 F()
1682 enddef
1683
1684 g:result = ''
1685 var obj = CWithEE.new()
1686 obj->With(() => {
1687 g:result ..= "called/"
1688 })
1689 assert_equal('entered/called/exited', g:result)
1690 END
1691 v9.CheckScriptSuccess(lines)
1692 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00001693
1694 lines =<< trim END
1695 vim9script
1696
1697 class BaseWithEE
1698 def Enter()
1699 g:result ..= "entered-base/"
1700 enddef
1701 def Exit()
1702 g:result ..= "exited-base"
1703 enddef
1704 endclass
1705
1706 class CWithEE extends BaseWithEE
1707 def Enter()
1708 g:result ..= "entered-child/"
1709 enddef
1710 def Exit()
1711 g:result ..= "exited-child"
1712 enddef
1713 endclass
1714
1715 def With(ee: BaseWithEE, F: func)
1716 ee.Enter()
1717 defer ee.Exit()
1718 F()
1719 enddef
1720
1721 g:result = ''
1722 var obj = CWithEE.new()
1723 obj->With(() => {
1724 g:result ..= "called/"
1725 })
1726 assert_equal('entered-child/called/exited-child', g:result)
1727 END
1728 v9.CheckScriptSuccess(lines)
1729 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001730enddef
1731
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001732
1733" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker