blob: bc8a8e1d548a27fd7e679cf073fe995cb514f2a0 [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>')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000275
276 # TODO: this should not give an error but be handled at runtime
277 lines =<< trim END
278 vim9script
279
280 class Class
281 this.id: string
282 def Method1()
283 echo 'Method1' .. this.id
284 enddef
285 endclass
286
287 var obj = null_object
288 def Func()
289 obj.Method1()
290 enddef
291 Func()
292 END
293 v9.CheckScriptFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000294enddef
295
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000296def Test_class_member_initializer()
297 var lines =<< trim END
298 vim9script
299
300 class TextPosition
301 this.lnum: number = 1
302 this.col: number = 1
303
Bram Moolenaar418b5472022-12-20 13:38:22 +0000304 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000305 def new(lnum: number)
306 this.lnum = lnum
307 enddef
308 endclass
309
310 var pos = TextPosition.new(3)
311 assert_equal(3, pos.lnum)
312 assert_equal(1, pos.col)
313
314 var instr = execute('disassemble TextPosition.new')
315 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000316 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000317 '\d PUSHNR 1\_s*' ..
318 '\d STORE_THIS 0\_s*' ..
319 '\d PUSHNR 1\_s*' ..
320 '\d STORE_THIS 1\_s*' ..
321 'this.lnum = lnum\_s*' ..
322 '\d LOAD arg\[-1]\_s*' ..
323 '\d PUSHNR 0\_s*' ..
324 '\d LOAD $0\_s*' ..
325 '\d\+ STOREINDEX object\_s*' ..
326 '\d\+ RETURN object.*',
327 instr)
328 END
329 v9.CheckScriptSuccess(lines)
330enddef
331
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000332def Test_member_any_used_as_object()
333 var lines =<< trim END
334 vim9script
335
336 class Inner
337 this.value: number = 0
338 endclass
339
340 class Outer
341 this.inner: any
342 endclass
343
344 def F(outer: Outer)
345 outer.inner.value = 1
346 enddef
347
348 var inner_obj = Inner.new(0)
349 var outer_obj = Outer.new(inner_obj)
350 F(outer_obj)
351 assert_equal(1, inner_obj.value)
352 END
353 v9.CheckScriptSuccess(lines)
354
355 lines =<< trim END
356 vim9script
357
358 class Inner
359 this.value: number = 0
360 endclass
361
362 class Outer
363 this.inner: Inner
364 endclass
365
366 def F(outer: Outer)
367 outer.inner.value = 1
368 enddef
369
370 def Test_assign_to_nested_typed_member()
371 var inner = Inner.new(0)
372 var outer = Outer.new(inner)
373 F(outer)
374 assert_equal(1, inner.value)
375 enddef
376
377 Test_assign_to_nested_typed_member()
378 END
379 v9.CheckScriptSuccess(lines)
380enddef
381
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000382def Test_assignment_with_operator()
383 var lines =<< trim END
384 vim9script
385
386 class Foo
387 this.x: number
388
389 def Add(n: number)
390 this.x += n
391 enddef
392 endclass
393
394 var f = Foo.new(3)
395 f.Add(17)
396 assert_equal(20, f.x)
397 END
398 v9.CheckScriptSuccess(lines)
399enddef
400
Bram Moolenaarf4508042023-01-15 16:54:57 +0000401def Test_list_of_objects()
402 var lines =<< trim END
403 vim9script
404
405 class Foo
406 def Add()
407 enddef
408 endclass
409
410 def ProcessList(fooList: list<Foo>)
411 for foo in fooList
412 foo.Add()
413 endfor
414 enddef
415
416 var l: list<Foo> = [Foo.new()]
417 ProcessList(l)
418 END
419 v9.CheckScriptSuccess(lines)
420enddef
421
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000422def Test_expr_after_using_object()
423 var lines =<< trim END
424 vim9script
425
426 class Something
427 this.label: string = ''
428 endclass
429
430 def Foo(): Something
431 var v = Something.new()
432 echo 'in Foo(): ' .. typename(v)
433 return v
434 enddef
435
436 Foo()
437 END
438 v9.CheckScriptSuccess(lines)
439enddef
440
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000441def Test_class_default_new()
442 var lines =<< trim END
443 vim9script
444
445 class TextPosition
446 this.lnum: number = 1
447 this.col: number = 1
448 endclass
449
450 var pos = TextPosition.new()
451 assert_equal(1, pos.lnum)
452 assert_equal(1, pos.col)
453
454 pos = TextPosition.new(v:none, v:none)
455 assert_equal(1, pos.lnum)
456 assert_equal(1, pos.col)
457
458 pos = TextPosition.new(3, 22)
459 assert_equal(3, pos.lnum)
460 assert_equal(22, pos.col)
461
462 pos = TextPosition.new(v:none, 33)
463 assert_equal(1, pos.lnum)
464 assert_equal(33, pos.col)
465 END
466 v9.CheckScriptSuccess(lines)
467
468 lines =<< trim END
469 vim9script
470 class Person
471 this.name: string
472 this.age: number = 42
473 this.education: string = "unknown"
474
475 def new(this.name, this.age = v:none, this.education = v:none)
476 enddef
477 endclass
478
479 var piet = Person.new("Piet")
480 assert_equal("Piet", piet.name)
481 assert_equal(42, piet.age)
482 assert_equal("unknown", piet.education)
483
484 var chris = Person.new("Chris", 4, "none")
485 assert_equal("Chris", chris.name)
486 assert_equal(4, chris.age)
487 assert_equal("none", chris.education)
488 END
489 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000490
491 lines =<< trim END
492 vim9script
493 class Person
494 this.name: string
495 this.age: number = 42
496 this.education: string = "unknown"
497
498 def new(this.name, this.age = v:none, this.education = v:none)
499 enddef
500 endclass
501
502 var missing = Person.new()
503 END
504 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000505enddef
506
Bram Moolenaar74e12742022-12-13 21:14:28 +0000507def Test_class_object_member_inits()
508 var lines =<< trim END
509 vim9script
510 class TextPosition
511 this.lnum: number
512 this.col = 1
513 this.addcol: number = 2
514 endclass
515
516 var pos = TextPosition.new()
517 assert_equal(0, pos.lnum)
518 assert_equal(1, pos.col)
519 assert_equal(2, pos.addcol)
520 END
521 v9.CheckScriptSuccess(lines)
522
523 lines =<< trim END
524 vim9script
525 class TextPosition
526 this.lnum
527 this.col = 1
528 endclass
529 END
530 v9.CheckScriptFailure(lines, 'E1022:')
531
532 lines =<< trim END
533 vim9script
534 class TextPosition
535 this.lnum = v:none
536 this.col = 1
537 endclass
538 END
539 v9.CheckScriptFailure(lines, 'E1330:')
540enddef
541
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000542def Test_class_object_member_access()
543 var lines =<< trim END
544 vim9script
545 class Triple
546 this._one = 1
547 this.two = 2
548 public this.three = 3
549
550 def GetOne(): number
551 return this._one
552 enddef
553 endclass
554
555 var trip = Triple.new()
556 assert_equal(1, trip.GetOne())
557 assert_equal(2, trip.two)
558 assert_equal(3, trip.three)
559 assert_fails('echo trip._one', 'E1333')
560
561 assert_fails('trip._one = 11', 'E1333')
562 assert_fails('trip.two = 22', 'E1335')
563 trip.three = 33
564 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000565
566 assert_fails('trip.four = 4', 'E1334')
567 END
568 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000569
570 lines =<< trim END
571 vim9script
572
573 class MyCar
574 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000575 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000576
577 def new(make_arg: string)
578 this.make = make_arg
579 enddef
580
581 def GetMake(): string
582 return $"make = {this.make}"
583 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000584 def GetAge(): number
585 return this.age
586 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000587 endclass
588
589 var c = MyCar.new("abc")
590 assert_equal('make = abc', c.GetMake())
591
592 c = MyCar.new("def")
593 assert_equal('make = def', c.GetMake())
594
595 var c2 = MyCar.new("123")
596 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000597
598 def CheckCar()
599 assert_equal("make = def", c.GetMake())
600 assert_equal(5, c.GetAge())
601 enddef
602 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000603 END
604 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000605
606 lines =<< trim END
607 vim9script
608
609 class MyCar
610 this.make: string
611
612 def new(make_arg: string)
613 this.make = make_arg
614 enddef
615 endclass
616
617 var c = MyCar.new("abc")
618 var c = MyCar.new("def")
619 END
620 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000621
622 lines =<< trim END
623 vim9script
624
625 class Foo
626 this.x: list<number> = []
627
628 def Add(n: number): any
629 this.x->add(n)
630 return this
631 enddef
632 endclass
633
634 echo Foo.new().Add(1).Add(2).x
635 echo Foo.new().Add(1).Add(2)
636 .x
637 echo Foo.new().Add(1)
638 .Add(2).x
639 echo Foo.new()
640 .Add(1).Add(2).x
641 echo Foo.new()
642 .Add(1)
643 .Add(2)
644 .x
645 END
646 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000647enddef
648
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000649def Test_class_object_compare()
650 var class_lines =<< trim END
651 vim9script
652 class Item
653 this.nr = 0
654 this.name = 'xx'
655 endclass
656 END
657
658 # used at the script level and in a compiled function
659 var test_lines =<< trim END
660 var i1 = Item.new()
661 assert_equal(i1, i1)
662 assert_true(i1 is i1)
663 var i2 = Item.new()
664 assert_equal(i1, i2)
665 assert_false(i1 is i2)
666 var i3 = Item.new(0, 'xx')
667 assert_equal(i1, i3)
668
669 var io1 = Item.new(1, 'xx')
670 assert_notequal(i1, io1)
671 var io2 = Item.new(0, 'yy')
672 assert_notequal(i1, io2)
673 END
674
675 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000676 v9.CheckScriptSuccess(
677 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000678
679 for op in ['>', '>=', '<', '<=', '=~', '!~']
680 var op_lines = [
681 'var i1 = Item.new()',
682 'var i2 = Item.new()',
683 'echo i1 ' .. op .. ' i2',
684 ]
685 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000686 v9.CheckScriptFailure(class_lines
687 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000688 endfor
689enddef
690
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000691def Test_object_type()
692 var lines =<< trim END
693 vim9script
694
695 class One
696 this.one = 1
697 endclass
698 class Two
699 this.two = 2
700 endclass
701 class TwoMore extends Two
702 this.more = 9
703 endclass
704
705 var o: One = One.new()
706 var t: Two = Two.new()
707 var m: TwoMore = TwoMore.new()
708 var tm: Two = TwoMore.new()
709
710 t = m
711 END
712 v9.CheckScriptSuccess(lines)
713
714 lines =<< trim END
715 vim9script
716
717 class One
718 this.one = 1
719 endclass
720 class Two
721 this.two = 2
722 endclass
723
724 var o: One = Two.new()
725 END
726 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000727
728 lines =<< trim END
729 vim9script
730
731 interface One
732 def GetMember(): number
733 endinterface
734 class Two implements One
735 this.one = 1
736 def GetMember(): number
737 return this.one
738 enddef
739 endclass
740
741 var o: One = Two.new(5)
742 assert_equal(5, o.GetMember())
743 END
744 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000745
746 lines =<< trim END
747 vim9script
748
749 class Num
750 this.n: number = 0
751 endclass
752
753 def Ref(name: string): func(Num): Num
754 return (arg: Num): Num => {
755 return eval(name)(arg)
756 }
757 enddef
758
759 const Fn = Ref('Double')
760 var Double = (m: Num): Num => Num.new(m.n * 2)
761
762 echo Fn(Num.new(4))
763 END
764 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000765enddef
766
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000767def Test_class_member()
768 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000769 var lines =<< trim END
770 vim9script
771 class TextPos
772 this.lnum = 1
773 this.col = 1
774 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000775 static _secret = 7
776 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000777
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000778 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000779 counter += nr
780 enddef
781 endclass
782
783 assert_equal(0, TextPos.counter)
784 TextPos.AddToCounter(3)
785 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000786 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +0000787
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000788 def GetCounter(): number
789 return TextPos.counter
790 enddef
791 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000792
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000793 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000794 assert_fails('TextPos.counter = 5', 'E1335:')
795 assert_fails('TextPos.counter += 5', 'E1335:')
796
797 assert_fails('echo TextPos._secret', 'E1333:')
798 assert_fails('TextPos._secret = 8', 'E1333:')
799
800 assert_equal(42, TextPos.anybody)
801 TextPos.anybody = 12
802 assert_equal(12, TextPos.anybody)
803 TextPos.anybody += 5
804 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000805 END
806 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000807
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000808 # example in the help
809 lines =<< trim END
810 vim9script
811 class OtherThing
812 this.size: number
813 static totalSize: number
814
815 def new(this.size)
816 totalSize += this.size
817 enddef
818 endclass
819 assert_equal(0, OtherThing.totalSize)
820 var to3 = OtherThing.new(3)
821 assert_equal(3, OtherThing.totalSize)
822 var to7 = OtherThing.new(7)
823 assert_equal(10, OtherThing.totalSize)
824 END
825 v9.CheckScriptSuccess(lines)
826
Bram Moolenaar62a69232023-01-24 15:07:04 +0000827 # access private member in lambda
828 lines =<< trim END
829 vim9script
830
831 class Foo
832 this._x: number = 0
833
834 def Add(n: number): number
835 const F = (): number => this._x + n
836 return F()
837 enddef
838 endclass
839
840 var foo = Foo.new()
841 assert_equal(5, foo.Add(5))
842 END
843 v9.CheckScriptSuccess(lines)
844
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000845 # check shadowing
846 lines =<< trim END
847 vim9script
848
849 class Some
850 static count = 0
851 def Method(count: number)
852 echo count
853 enddef
854 endclass
855
856 var s = Some.new()
857 s.Method(7)
858 END
859 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
860
861 lines =<< trim END
862 vim9script
863
864 class Some
865 static count = 0
866 def Method(arg: number)
867 var count = 3
868 echo arg count
869 enddef
870 endclass
871
872 var s = Some.new()
873 s.Method(7)
874 END
875 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000876enddef
877
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000878func Test_class_garbagecollect()
879 let lines =<< trim END
880 vim9script
881
882 class Point
883 this.p = [2, 3]
884 static pl = ['a', 'b']
885 static pd = {a: 'a', b: 'b'}
886 endclass
887
888 echo Point.pl Point.pd
889 call test_garbagecollect_now()
890 echo Point.pl Point.pd
891 END
892 call v9.CheckScriptSuccess(lines)
893endfunc
894
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000895def Test_class_function()
896 var lines =<< trim END
897 vim9script
898 class Value
899 this.value = 0
900 static objects = 0
901
902 def new(v: number)
903 this.value = v
904 ++objects
905 enddef
906
907 static def GetCount(): number
908 return objects
909 enddef
910 endclass
911
912 assert_equal(0, Value.GetCount())
913 var v1 = Value.new(2)
914 assert_equal(1, Value.GetCount())
915 var v2 = Value.new(7)
916 assert_equal(2, Value.GetCount())
917 END
918 v9.CheckScriptSuccess(lines)
919enddef
920
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +0000921def Test_class_defcompile()
922 var lines =<< trim END
923 vim9script
924
925 class C
926 def Fo(i: number): string
927 return i
928 enddef
929 endclass
930
931 defcompile C.Fo
932 END
933 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
934
935 lines =<< trim END
936 vim9script
937
938 class C
939 static def Fc(): number
940 return 'x'
941 enddef
942 endclass
943
944 defcompile C.Fc
945 END
946 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
947enddef
948
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000949def Test_class_object_to_string()
950 var lines =<< trim END
951 vim9script
952 class TextPosition
953 this.lnum = 1
954 this.col = 22
955 endclass
956
957 assert_equal("class TextPosition", string(TextPosition))
958
959 var pos = TextPosition.new()
960 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
961 END
962 v9.CheckScriptSuccess(lines)
963enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000964
Bram Moolenaar554d0312023-01-05 19:59:18 +0000965def Test_interface_basics()
966 var lines =<< trim END
967 vim9script
968 interface Something
969 this.value: string
970 static count: number
971 def GetCount(): number
972 endinterface
973 END
974 v9.CheckScriptSuccess(lines)
975
976 lines =<< trim END
977 interface SomethingWrong
978 static count = 7
979 endinterface
980 END
981 v9.CheckScriptFailure(lines, 'E1342:')
982
983 lines =<< trim END
984 vim9script
985
986 interface Some
987 static count: number
988 def Method(count: number)
989 endinterface
990 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000991 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
992
993 lines =<< trim END
994 vim9script
995
996 interface Some
997 this.value: number
998 def Method(value: number)
999 endinterface
1000 END
1001 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +00001002
1003 lines =<< trim END
1004 vim9script
1005 interface somethingWrong
1006 static count = 7
1007 endinterface
1008 END
1009 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1010
1011 lines =<< trim END
1012 vim9script
1013 interface SomethingWrong
1014 this.value: string
1015 static count = 7
1016 def GetCount(): number
1017 endinterface
1018 END
1019 v9.CheckScriptFailure(lines, 'E1344:')
1020
1021 lines =<< trim END
1022 vim9script
1023 interface SomethingWrong
1024 this.value: string
1025 static count: number
1026 def GetCount(): number
1027 return 5
1028 enddef
1029 endinterface
1030 END
1031 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001032
1033 lines =<< trim END
1034 vim9script
1035 export interface EnterExit
1036 def Enter(): void
1037 def Exit(): void
1038 endinterface
1039 END
1040 writefile(lines, 'XdefIntf.vim', 'D')
1041
1042 lines =<< trim END
1043 vim9script
1044 import './XdefIntf.vim' as defIntf
1045 export def With(ee: defIntf.EnterExit, F: func)
1046 ee.Enter()
1047 try
1048 F()
1049 finally
1050 ee.Exit()
1051 endtry
1052 enddef
1053 END
1054 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001055
1056 var imported =<< trim END
1057 vim9script
1058 export abstract class EnterExit
1059 def Enter(): void
1060 enddef
1061 def Exit(): void
1062 enddef
1063 endclass
1064 END
1065 writefile(imported, 'XdefIntf2.vim', 'D')
1066
1067 lines[1] = " import './XdefIntf2.vim' as defIntf"
1068 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001069enddef
1070
Bram Moolenaar94674f22023-01-06 18:42:20 +00001071def Test_class_implements_interface()
1072 var lines =<< trim END
1073 vim9script
1074
1075 interface Some
1076 static count: number
1077 def Method(nr: number)
1078 endinterface
1079
1080 class SomeImpl implements Some
1081 static count: number
1082 def Method(nr: number)
1083 echo nr
1084 enddef
1085 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001086
1087 interface Another
1088 this.member: string
1089 endinterface
1090
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001091 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001092 this.member = 'abc'
1093 static count: number
1094 def Method(nr: number)
1095 echo nr
1096 enddef
1097 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001098 END
1099 v9.CheckScriptSuccess(lines)
1100
1101 lines =<< trim END
1102 vim9script
1103
1104 interface Some
1105 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001106 endinterface
1107
1108 class SomeImpl implements Some implements Some
1109 static count: number
1110 endclass
1111 END
1112 v9.CheckScriptFailure(lines, 'E1350:')
1113
1114 lines =<< trim END
1115 vim9script
1116
1117 interface Some
1118 static counter: number
1119 endinterface
1120
1121 class SomeImpl implements Some, Some
1122 static count: number
1123 endclass
1124 END
1125 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1126
1127 lines =<< trim END
1128 vim9script
1129
1130 interface Some
1131 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001132 def Method(nr: number)
1133 endinterface
1134
1135 class SomeImpl implements Some
1136 static count: number
1137 def Method(nr: number)
1138 echo nr
1139 enddef
1140 endclass
1141 END
1142 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1143
1144 lines =<< trim END
1145 vim9script
1146
1147 interface Some
1148 static count: number
1149 def Methods(nr: number)
1150 endinterface
1151
1152 class SomeImpl implements Some
1153 static count: number
1154 def Method(nr: number)
1155 echo nr
1156 enddef
1157 endclass
1158 END
1159 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001160
1161 # Check different order of members in class and interface works.
1162 lines =<< trim END
1163 vim9script
1164
1165 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001166 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001167 this.errpos: number
1168 endinterface
1169
1170 # order of members is opposite of interface
1171 class Failure implements Result
1172 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001173 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001174 endclass
1175
1176 def Test()
1177 var result: Result = Failure.new()
1178
1179 assert_equal('label', result.label)
1180 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001181
1182 result.label = 'different'
1183 assert_equal('different', result.label)
1184 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001185 enddef
1186
1187 Test()
1188 END
1189 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001190enddef
1191
Bram Moolenaard0200c82023-01-28 15:19:40 +00001192def Test_call_interface_method()
1193 var lines =<< trim END
1194 vim9script
1195 interface Base
1196 def Enter(): void
1197 endinterface
1198
1199 class Child implements Base
1200 def Enter(): void
1201 g:result ..= 'child'
1202 enddef
1203 endclass
1204
1205 def F(obj: Base)
1206 obj.Enter()
1207 enddef
1208
1209 g:result = ''
1210 F(Child.new())
1211 assert_equal('child', g:result)
1212 unlet g:result
1213 END
1214 v9.CheckScriptSuccess(lines)
1215
1216 lines =<< trim END
1217 vim9script
1218 class Base
1219 def Enter(): void
1220 g:result ..= 'base'
1221 enddef
1222 endclass
1223
1224 class Child extends Base
1225 def Enter(): void
1226 g:result ..= 'child'
1227 enddef
1228 endclass
1229
1230 def F(obj: Base)
1231 obj.Enter()
1232 enddef
1233
1234 g:result = ''
1235 F(Child.new())
1236 assert_equal('child', g:result)
1237 unlet g:result
1238 END
1239 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001240
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001241 # method of interface returns a value
1242 lines =<< trim END
1243 vim9script
1244 interface Base
1245 def Enter(): string
1246 endinterface
1247
1248 class Child implements Base
1249 def Enter(): string
1250 g:result ..= 'child'
1251 return "/resource"
1252 enddef
1253 endclass
1254
1255 def F(obj: Base)
1256 var r = obj.Enter()
1257 g:result ..= r
1258 enddef
1259
1260 g:result = ''
1261 F(Child.new())
1262 assert_equal('child/resource', g:result)
1263 unlet g:result
1264 END
1265 v9.CheckScriptSuccess(lines)
1266
1267 lines =<< trim END
1268 vim9script
1269 class Base
1270 def Enter(): string
1271 return null_string
1272 enddef
1273 endclass
1274
1275 class Child extends Base
1276 def Enter(): string
1277 g:result ..= 'child'
1278 return "/resource"
1279 enddef
1280 endclass
1281
1282 def F(obj: Base)
1283 var r = obj.Enter()
1284 g:result ..= r
1285 enddef
1286
1287 g:result = ''
1288 F(Child.new())
1289 assert_equal('child/resource', g:result)
1290 unlet g:result
1291 END
1292 v9.CheckScriptSuccess(lines)
1293
1294
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001295 # No class that implements the interface.
1296 lines =<< trim END
1297 vim9script
1298
1299 interface IWithEE
1300 def Enter(): any
1301 def Exit(): void
1302 endinterface
1303
1304 def With1(ee: IWithEE, F: func)
1305 var r = ee.Enter()
1306 enddef
1307
1308 defcompile
1309 END
1310 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001311enddef
1312
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001313def Test_class_used_as_type()
1314 var lines =<< trim END
1315 vim9script
1316
1317 class Point
1318 this.x = 0
1319 this.y = 0
1320 endclass
1321
1322 var p: Point
1323 p = Point.new(2, 33)
1324 assert_equal(2, p.x)
1325 assert_equal(33, p.y)
1326 END
1327 v9.CheckScriptSuccess(lines)
1328
1329 lines =<< trim END
1330 vim9script
1331
1332 interface HasX
1333 this.x: number
1334 endinterface
1335
1336 class Point implements HasX
1337 this.x = 0
1338 this.y = 0
1339 endclass
1340
1341 var p: Point
1342 p = Point.new(2, 33)
1343 var hx = p
1344 assert_equal(2, hx.x)
1345 END
1346 v9.CheckScriptSuccess(lines)
1347
1348 lines =<< trim END
1349 vim9script
1350
1351 class Point
1352 this.x = 0
1353 this.y = 0
1354 endclass
1355
1356 var p: Point
1357 p = 'text'
1358 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001359 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001360enddef
1361
Bram Moolenaar83677162023-01-08 19:54:10 +00001362def Test_class_extends()
1363 var lines =<< trim END
1364 vim9script
1365 class Base
1366 this.one = 1
1367 def GetOne(): number
1368 return this.one
1369 enddef
1370 endclass
1371 class Child extends Base
1372 this.two = 2
1373 def GetTotal(): number
1374 return this.one + this.two
1375 enddef
1376 endclass
1377 var o = Child.new()
1378 assert_equal(1, o.one)
1379 assert_equal(2, o.two)
1380 assert_equal(1, o.GetOne())
1381 assert_equal(3, o.GetTotal())
1382 END
1383 v9.CheckScriptSuccess(lines)
1384
1385 lines =<< trim END
1386 vim9script
1387 class Base
1388 this.one = 1
1389 endclass
1390 class Child extends Base
1391 this.two = 2
1392 endclass
1393 var o = Child.new(3, 44)
1394 assert_equal(3, o.one)
1395 assert_equal(44, o.two)
1396 END
1397 v9.CheckScriptSuccess(lines)
1398
1399 lines =<< trim END
1400 vim9script
1401 class Base
1402 this.one = 1
1403 endclass
1404 class Child extends Base extends Base
1405 this.two = 2
1406 endclass
1407 END
1408 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1409
1410 lines =<< trim END
1411 vim9script
1412 class Child extends BaseClass
1413 this.two = 2
1414 endclass
1415 END
1416 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1417
1418 lines =<< trim END
1419 vim9script
1420 var SomeVar = 99
1421 class Child extends SomeVar
1422 this.two = 2
1423 endclass
1424 END
1425 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001426
1427 lines =<< trim END
1428 vim9script
1429 class Base
1430 this.name: string
1431 def ToString(): string
1432 return this.name
1433 enddef
1434 endclass
1435
1436 class Child extends Base
1437 this.age: number
1438 def ToString(): string
1439 return super.ToString() .. ': ' .. this.age
1440 enddef
1441 endclass
1442
1443 var o = Child.new('John', 42)
1444 assert_equal('John: 42', o.ToString())
1445 END
1446 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001447
1448 lines =<< trim END
1449 vim9script
1450 class Child
1451 this.age: number
1452 def ToString(): number
1453 return this.age
1454 enddef
1455 def ToString(): string
1456 return this.age
1457 enddef
1458 endclass
1459 END
1460 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1461
1462 lines =<< trim END
1463 vim9script
1464 class Child
1465 this.age: number
1466 def ToString(): string
1467 return super .ToString() .. ': ' .. this.age
1468 enddef
1469 endclass
1470 var o = Child.new(42)
1471 echo o.ToString()
1472 END
1473 v9.CheckScriptFailure(lines, 'E1356:')
1474
1475 lines =<< trim END
1476 vim9script
1477 class Base
1478 this.name: string
1479 def ToString(): string
1480 return this.name
1481 enddef
1482 endclass
1483
1484 var age = 42
1485 def ToString(): string
1486 return super.ToString() .. ': ' .. age
1487 enddef
1488 echo ToString()
1489 END
1490 v9.CheckScriptFailure(lines, 'E1357:')
1491
1492 lines =<< trim END
1493 vim9script
1494 class Child
1495 this.age: number
1496 def ToString(): string
1497 return super.ToString() .. ': ' .. this.age
1498 enddef
1499 endclass
1500 var o = Child.new(42)
1501 echo o.ToString()
1502 END
1503 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001504
1505 lines =<< trim END
1506 vim9script
1507 class Base
1508 this.name: string
1509 static def ToString(): string
1510 return 'Base class'
1511 enddef
1512 endclass
1513
1514 class Child extends Base
1515 this.age: number
1516 def ToString(): string
1517 return Base.ToString() .. ': ' .. this.age
1518 enddef
1519 endclass
1520
1521 var o = Child.new('John', 42)
1522 assert_equal('Base class: 42', o.ToString())
1523 END
1524 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001525
1526 lines =<< trim END
1527 vim9script
1528 class Base
1529 this.value = 1
1530 def new(init: number)
1531 this.value = number + 1
1532 enddef
1533 endclass
1534 class Child extends Base
1535 def new()
1536 this.new(3)
1537 enddef
1538 endclass
1539 var c = Child.new()
1540 END
1541 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001542
1543 # base class with more than one object member
1544 lines =<< trim END
1545 vim9script
1546
1547 class Result
1548 this.success: bool
1549 this.value: any = null
1550 endclass
1551
1552 class Success extends Result
1553 def new(this.value = v:none)
1554 this.success = true
1555 enddef
1556 endclass
1557
1558 var v = Success.new('asdf')
1559 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1560 END
1561 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001562enddef
1563
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00001564def Test_using_base_class()
1565 var lines =<< trim END
1566 vim9script
1567
1568 class BaseEE
1569 def Enter(): any
1570 return null
1571 enddef
1572 def Exit(resource: any): void
1573 enddef
1574 endclass
1575
1576 class ChildEE extends BaseEE
1577 def Enter(): any
1578 return 42
1579 enddef
1580
1581 def Exit(resource: number): void
1582 g:result ..= '/exit'
1583 enddef
1584 endclass
1585
1586 def With(ee: BaseEE)
1587 var r = ee.Enter()
1588 try
1589 g:result ..= r
1590 finally
1591 g:result ..= '/finally'
1592 ee.Exit(r)
1593 endtry
1594 enddef
1595
1596 g:result = ''
1597 With(ChildEE.new())
1598 assert_equal('42/finally/exit', g:result)
1599 END
1600 v9.CheckScriptSuccess(lines)
1601 unlet g:result
1602enddef
1603
1604
Bram Moolenaara86655a2023-01-12 17:06:27 +00001605def Test_class_import()
1606 var lines =<< trim END
1607 vim9script
1608 export class Animal
1609 this.kind: string
1610 this.name: string
1611 endclass
1612 END
1613 writefile(lines, 'Xanimal.vim', 'D')
1614
1615 lines =<< trim END
1616 vim9script
1617 import './Xanimal.vim' as animal
1618
1619 var a: animal.Animal
1620 a = animal.Animal.new('fish', 'Eric')
1621 assert_equal('fish', a.kind)
1622 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001623
1624 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1625 assert_equal('cat', b.kind)
1626 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001627 END
1628 v9.CheckScriptSuccess(lines)
1629enddef
1630
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001631def Test_abstract_class()
1632 var lines =<< trim END
1633 vim9script
1634 abstract class Base
1635 this.name: string
1636 endclass
1637 class Person extends Base
1638 this.age: number
1639 endclass
1640 var p: Base = Person.new('Peter', 42)
1641 assert_equal('Peter', p.name)
1642 assert_equal(42, p.age)
1643 END
1644 v9.CheckScriptSuccess(lines)
1645
1646 lines =<< trim END
1647 vim9script
1648 abstract class Base
1649 this.name: string
1650 endclass
1651 class Person extends Base
1652 this.age: number
1653 endclass
1654 var p = Base.new('Peter')
1655 END
1656 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1657
1658 lines =<< trim END
1659 abstract class Base
1660 this.name: string
1661 endclass
1662 END
1663 v9.CheckScriptFailure(lines, 'E1316:')
1664enddef
1665
Bram Moolenaar486fc252023-01-18 14:51:07 +00001666def Test_closure_in_class()
1667 var lines =<< trim END
1668 vim9script
1669
1670 class Foo
1671 this.y: list<string> = ['B']
1672
1673 def new()
1674 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1675 enddef
1676 endclass
1677
1678 Foo.new()
1679 assert_equal(['A'], g:result)
1680 END
1681 v9.CheckScriptSuccess(lines)
1682enddef
1683
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001684def Test_defer_with_object()
1685 var lines =<< trim END
1686 vim9script
1687
1688 class CWithEE
1689 def Enter()
1690 g:result ..= "entered/"
1691 enddef
1692 def Exit()
1693 g:result ..= "exited"
1694 enddef
1695 endclass
1696
1697 def With(ee: CWithEE, 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/called/exited', g:result)
1709 END
1710 v9.CheckScriptSuccess(lines)
1711 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00001712
1713 lines =<< trim END
1714 vim9script
1715
1716 class BaseWithEE
1717 def Enter()
1718 g:result ..= "entered-base/"
1719 enddef
1720 def Exit()
1721 g:result ..= "exited-base"
1722 enddef
1723 endclass
1724
1725 class CWithEE extends BaseWithEE
1726 def Enter()
1727 g:result ..= "entered-child/"
1728 enddef
1729 def Exit()
1730 g:result ..= "exited-child"
1731 enddef
1732 endclass
1733
1734 def With(ee: BaseWithEE, F: func)
1735 ee.Enter()
1736 defer ee.Exit()
1737 F()
1738 enddef
1739
1740 g:result = ''
1741 var obj = CWithEE.new()
1742 obj->With(() => {
1743 g:result ..= "called/"
1744 })
1745 assert_equal('entered-child/called/exited-child', g:result)
1746 END
1747 v9.CheckScriptSuccess(lines)
1748 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00001749enddef
1750
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001751
1752" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker