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