blob: a3fdbdb9c33cdfa6b54f001127494f060ec743e0 [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
51 endclass school's out
52 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 Moolenaar7ce7daf2022-12-10 18:42:12 +0000167def Test_class_member_initializer()
168 var lines =<< trim END
169 vim9script
170
171 class TextPosition
172 this.lnum: number = 1
173 this.col: number = 1
174
Bram Moolenaar418b5472022-12-20 13:38:22 +0000175 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000176 def new(lnum: number)
177 this.lnum = lnum
178 enddef
179 endclass
180
181 var pos = TextPosition.new(3)
182 assert_equal(3, pos.lnum)
183 assert_equal(1, pos.col)
184
185 var instr = execute('disassemble TextPosition.new')
186 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000187 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000188 '\d PUSHNR 1\_s*' ..
189 '\d STORE_THIS 0\_s*' ..
190 '\d PUSHNR 1\_s*' ..
191 '\d STORE_THIS 1\_s*' ..
192 'this.lnum = lnum\_s*' ..
193 '\d LOAD arg\[-1]\_s*' ..
194 '\d PUSHNR 0\_s*' ..
195 '\d LOAD $0\_s*' ..
196 '\d\+ STOREINDEX object\_s*' ..
197 '\d\+ RETURN object.*',
198 instr)
199 END
200 v9.CheckScriptSuccess(lines)
201enddef
202
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000203def Test_assignment_with_operator()
204 var lines =<< trim END
205 vim9script
206
207 class Foo
208 this.x: number
209
210 def Add(n: number)
211 this.x += n
212 enddef
213 endclass
214
215 var f = Foo.new(3)
216 f.Add(17)
217 assert_equal(20, f.x)
218 END
219 v9.CheckScriptSuccess(lines)
220enddef
221
Bram Moolenaarf4508042023-01-15 16:54:57 +0000222def Test_list_of_objects()
223 var lines =<< trim END
224 vim9script
225
226 class Foo
227 def Add()
228 enddef
229 endclass
230
231 def ProcessList(fooList: list<Foo>)
232 for foo in fooList
233 foo.Add()
234 endfor
235 enddef
236
237 var l: list<Foo> = [Foo.new()]
238 ProcessList(l)
239 END
240 v9.CheckScriptSuccess(lines)
241enddef
242
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000243def Test_expr_after_using_object()
244 var lines =<< trim END
245 vim9script
246
247 class Something
248 this.label: string = ''
249 endclass
250
251 def Foo(): Something
252 var v = Something.new()
253 echo 'in Foo(): ' .. typename(v)
254 return v
255 enddef
256
257 Foo()
258 END
259 v9.CheckScriptSuccess(lines)
260enddef
261
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000262def Test_class_default_new()
263 var lines =<< trim END
264 vim9script
265
266 class TextPosition
267 this.lnum: number = 1
268 this.col: number = 1
269 endclass
270
271 var pos = TextPosition.new()
272 assert_equal(1, pos.lnum)
273 assert_equal(1, pos.col)
274
275 pos = TextPosition.new(v:none, v:none)
276 assert_equal(1, pos.lnum)
277 assert_equal(1, pos.col)
278
279 pos = TextPosition.new(3, 22)
280 assert_equal(3, pos.lnum)
281 assert_equal(22, pos.col)
282
283 pos = TextPosition.new(v:none, 33)
284 assert_equal(1, pos.lnum)
285 assert_equal(33, pos.col)
286 END
287 v9.CheckScriptSuccess(lines)
288
289 lines =<< trim END
290 vim9script
291 class Person
292 this.name: string
293 this.age: number = 42
294 this.education: string = "unknown"
295
296 def new(this.name, this.age = v:none, this.education = v:none)
297 enddef
298 endclass
299
300 var piet = Person.new("Piet")
301 assert_equal("Piet", piet.name)
302 assert_equal(42, piet.age)
303 assert_equal("unknown", piet.education)
304
305 var chris = Person.new("Chris", 4, "none")
306 assert_equal("Chris", chris.name)
307 assert_equal(4, chris.age)
308 assert_equal("none", chris.education)
309 END
310 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000311
312 lines =<< trim END
313 vim9script
314 class Person
315 this.name: string
316 this.age: number = 42
317 this.education: string = "unknown"
318
319 def new(this.name, this.age = v:none, this.education = v:none)
320 enddef
321 endclass
322
323 var missing = Person.new()
324 END
325 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000326enddef
327
Bram Moolenaar74e12742022-12-13 21:14:28 +0000328def Test_class_object_member_inits()
329 var lines =<< trim END
330 vim9script
331 class TextPosition
332 this.lnum: number
333 this.col = 1
334 this.addcol: number = 2
335 endclass
336
337 var pos = TextPosition.new()
338 assert_equal(0, pos.lnum)
339 assert_equal(1, pos.col)
340 assert_equal(2, pos.addcol)
341 END
342 v9.CheckScriptSuccess(lines)
343
344 lines =<< trim END
345 vim9script
346 class TextPosition
347 this.lnum
348 this.col = 1
349 endclass
350 END
351 v9.CheckScriptFailure(lines, 'E1022:')
352
353 lines =<< trim END
354 vim9script
355 class TextPosition
356 this.lnum = v:none
357 this.col = 1
358 endclass
359 END
360 v9.CheckScriptFailure(lines, 'E1330:')
361enddef
362
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000363def Test_class_object_member_access()
364 var lines =<< trim END
365 vim9script
366 class Triple
367 this._one = 1
368 this.two = 2
369 public this.three = 3
370
371 def GetOne(): number
372 return this._one
373 enddef
374 endclass
375
376 var trip = Triple.new()
377 assert_equal(1, trip.GetOne())
378 assert_equal(2, trip.two)
379 assert_equal(3, trip.three)
380 assert_fails('echo trip._one', 'E1333')
381
382 assert_fails('trip._one = 11', 'E1333')
383 assert_fails('trip.two = 22', 'E1335')
384 trip.three = 33
385 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000386
387 assert_fails('trip.four = 4', 'E1334')
388 END
389 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000390
391 lines =<< trim END
392 vim9script
393
394 class MyCar
395 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000396 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000397
398 def new(make_arg: string)
399 this.make = make_arg
400 enddef
401
402 def GetMake(): string
403 return $"make = {this.make}"
404 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000405 def GetAge(): number
406 return this.age
407 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000408 endclass
409
410 var c = MyCar.new("abc")
411 assert_equal('make = abc', c.GetMake())
412
413 c = MyCar.new("def")
414 assert_equal('make = def', c.GetMake())
415
416 var c2 = MyCar.new("123")
417 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000418
419 def CheckCar()
420 assert_equal("make = def", c.GetMake())
421 assert_equal(5, c.GetAge())
422 enddef
423 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000424 END
425 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000426
427 lines =<< trim END
428 vim9script
429
430 class MyCar
431 this.make: string
432
433 def new(make_arg: string)
434 this.make = make_arg
435 enddef
436 endclass
437
438 var c = MyCar.new("abc")
439 var c = MyCar.new("def")
440 END
441 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000442
443 lines =<< trim END
444 vim9script
445
446 class Foo
447 this.x: list<number> = []
448
449 def Add(n: number): any
450 this.x->add(n)
451 return this
452 enddef
453 endclass
454
455 echo Foo.new().Add(1).Add(2).x
456 echo Foo.new().Add(1).Add(2)
457 .x
458 echo Foo.new().Add(1)
459 .Add(2).x
460 echo Foo.new()
461 .Add(1).Add(2).x
462 echo Foo.new()
463 .Add(1)
464 .Add(2)
465 .x
466 END
467 v9.CheckScriptSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +0000468enddef
469
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000470def Test_class_object_compare()
471 var class_lines =<< trim END
472 vim9script
473 class Item
474 this.nr = 0
475 this.name = 'xx'
476 endclass
477 END
478
479 # used at the script level and in a compiled function
480 var test_lines =<< trim END
481 var i1 = Item.new()
482 assert_equal(i1, i1)
483 assert_true(i1 is i1)
484 var i2 = Item.new()
485 assert_equal(i1, i2)
486 assert_false(i1 is i2)
487 var i3 = Item.new(0, 'xx')
488 assert_equal(i1, i3)
489
490 var io1 = Item.new(1, 'xx')
491 assert_notequal(i1, io1)
492 var io2 = Item.new(0, 'yy')
493 assert_notequal(i1, io2)
494 END
495
496 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000497 v9.CheckScriptSuccess(
498 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000499
500 for op in ['>', '>=', '<', '<=', '=~', '!~']
501 var op_lines = [
502 'var i1 = Item.new()',
503 'var i2 = Item.new()',
504 'echo i1 ' .. op .. ' i2',
505 ]
506 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000507 v9.CheckScriptFailure(class_lines
508 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000509 endfor
510enddef
511
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000512def Test_object_type()
513 var lines =<< trim END
514 vim9script
515
516 class One
517 this.one = 1
518 endclass
519 class Two
520 this.two = 2
521 endclass
522 class TwoMore extends Two
523 this.more = 9
524 endclass
525
526 var o: One = One.new()
527 var t: Two = Two.new()
528 var m: TwoMore = TwoMore.new()
529 var tm: Two = TwoMore.new()
530
531 t = m
532 END
533 v9.CheckScriptSuccess(lines)
534
535 lines =<< trim END
536 vim9script
537
538 class One
539 this.one = 1
540 endclass
541 class Two
542 this.two = 2
543 endclass
544
545 var o: One = Two.new()
546 END
547 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000548
549 lines =<< trim END
550 vim9script
551
552 interface One
553 def GetMember(): number
554 endinterface
555 class Two implements One
556 this.one = 1
557 def GetMember(): number
558 return this.one
559 enddef
560 endclass
561
562 var o: One = Two.new(5)
563 assert_equal(5, o.GetMember())
564 END
565 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000566
567 lines =<< trim END
568 vim9script
569
570 class Num
571 this.n: number = 0
572 endclass
573
574 def Ref(name: string): func(Num): Num
575 return (arg: Num): Num => {
576 return eval(name)(arg)
577 }
578 enddef
579
580 const Fn = Ref('Double')
581 var Double = (m: Num): Num => Num.new(m.n * 2)
582
583 echo Fn(Num.new(4))
584 END
585 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000586enddef
587
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000588def Test_class_member()
589 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000590 var lines =<< trim END
591 vim9script
592 class TextPos
593 this.lnum = 1
594 this.col = 1
595 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000596 static _secret = 7
597 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000598
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000599 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000600 counter += nr
601 enddef
602 endclass
603
604 assert_equal(0, TextPos.counter)
605 TextPos.AddToCounter(3)
606 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000607 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000608
609 def GetCounter(): number
610 return TextPos.counter
611 enddef
612 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000613
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000614 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000615 assert_fails('TextPos.counter = 5', 'E1335:')
616 assert_fails('TextPos.counter += 5', 'E1335:')
617
618 assert_fails('echo TextPos._secret', 'E1333:')
619 assert_fails('TextPos._secret = 8', 'E1333:')
620
621 assert_equal(42, TextPos.anybody)
622 TextPos.anybody = 12
623 assert_equal(12, TextPos.anybody)
624 TextPos.anybody += 5
625 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000626 END
627 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000628
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000629 # example in the help
630 lines =<< trim END
631 vim9script
632 class OtherThing
633 this.size: number
634 static totalSize: number
635
636 def new(this.size)
637 totalSize += this.size
638 enddef
639 endclass
640 assert_equal(0, OtherThing.totalSize)
641 var to3 = OtherThing.new(3)
642 assert_equal(3, OtherThing.totalSize)
643 var to7 = OtherThing.new(7)
644 assert_equal(10, OtherThing.totalSize)
645 END
646 v9.CheckScriptSuccess(lines)
647
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000648 # check shadowing
649 lines =<< trim END
650 vim9script
651
652 class Some
653 static count = 0
654 def Method(count: number)
655 echo count
656 enddef
657 endclass
658
659 var s = Some.new()
660 s.Method(7)
661 END
662 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
663
664 lines =<< trim END
665 vim9script
666
667 class Some
668 static count = 0
669 def Method(arg: number)
670 var count = 3
671 echo arg count
672 enddef
673 endclass
674
675 var s = Some.new()
676 s.Method(7)
677 END
678 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000679enddef
680
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000681func Test_class_garbagecollect()
682 let lines =<< trim END
683 vim9script
684
685 class Point
686 this.p = [2, 3]
687 static pl = ['a', 'b']
688 static pd = {a: 'a', b: 'b'}
689 endclass
690
691 echo Point.pl Point.pd
692 call test_garbagecollect_now()
693 echo Point.pl Point.pd
694 END
695 call v9.CheckScriptSuccess(lines)
696endfunc
697
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000698def Test_class_function()
699 var lines =<< trim END
700 vim9script
701 class Value
702 this.value = 0
703 static objects = 0
704
705 def new(v: number)
706 this.value = v
707 ++objects
708 enddef
709
710 static def GetCount(): number
711 return objects
712 enddef
713 endclass
714
715 assert_equal(0, Value.GetCount())
716 var v1 = Value.new(2)
717 assert_equal(1, Value.GetCount())
718 var v2 = Value.new(7)
719 assert_equal(2, Value.GetCount())
720 END
721 v9.CheckScriptSuccess(lines)
722enddef
723
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000724def Test_class_object_to_string()
725 var lines =<< trim END
726 vim9script
727 class TextPosition
728 this.lnum = 1
729 this.col = 22
730 endclass
731
732 assert_equal("class TextPosition", string(TextPosition))
733
734 var pos = TextPosition.new()
735 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
736 END
737 v9.CheckScriptSuccess(lines)
738enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000739
Bram Moolenaar554d0312023-01-05 19:59:18 +0000740def Test_interface_basics()
741 var lines =<< trim END
742 vim9script
743 interface Something
744 this.value: string
745 static count: number
746 def GetCount(): number
747 endinterface
748 END
749 v9.CheckScriptSuccess(lines)
750
751 lines =<< trim END
752 interface SomethingWrong
753 static count = 7
754 endinterface
755 END
756 v9.CheckScriptFailure(lines, 'E1342:')
757
758 lines =<< trim END
759 vim9script
760
761 interface Some
762 static count: number
763 def Method(count: number)
764 endinterface
765 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000766 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
767
768 lines =<< trim END
769 vim9script
770
771 interface Some
772 this.value: number
773 def Method(value: number)
774 endinterface
775 END
776 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +0000777
778 lines =<< trim END
779 vim9script
780 interface somethingWrong
781 static count = 7
782 endinterface
783 END
784 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
785
786 lines =<< trim END
787 vim9script
788 interface SomethingWrong
789 this.value: string
790 static count = 7
791 def GetCount(): number
792 endinterface
793 END
794 v9.CheckScriptFailure(lines, 'E1344:')
795
796 lines =<< trim END
797 vim9script
798 interface SomethingWrong
799 this.value: string
800 static count: number
801 def GetCount(): number
802 return 5
803 enddef
804 endinterface
805 END
806 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
807enddef
808
Bram Moolenaar94674f22023-01-06 18:42:20 +0000809def Test_class_implements_interface()
810 var lines =<< trim END
811 vim9script
812
813 interface Some
814 static count: number
815 def Method(nr: number)
816 endinterface
817
818 class SomeImpl implements Some
819 static count: number
820 def Method(nr: number)
821 echo nr
822 enddef
823 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000824
825 interface Another
826 this.member: string
827 endinterface
828
829 class SomeImpl implements Some, Another
830 this.member = 'abc'
831 static count: number
832 def Method(nr: number)
833 echo nr
834 enddef
835 endclass
836
Bram Moolenaar94674f22023-01-06 18:42:20 +0000837 END
838 v9.CheckScriptSuccess(lines)
839
840 lines =<< trim END
841 vim9script
842
843 interface Some
844 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000845 endinterface
846
847 class SomeImpl implements Some implements Some
848 static count: number
849 endclass
850 END
851 v9.CheckScriptFailure(lines, 'E1350:')
852
853 lines =<< trim END
854 vim9script
855
856 interface Some
857 static counter: number
858 endinterface
859
860 class SomeImpl implements Some, Some
861 static count: number
862 endclass
863 END
864 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
865
866 lines =<< trim END
867 vim9script
868
869 interface Some
870 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +0000871 def Method(nr: number)
872 endinterface
873
874 class SomeImpl implements Some
875 static count: number
876 def Method(nr: number)
877 echo nr
878 enddef
879 endclass
880 END
881 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
882
883 lines =<< trim END
884 vim9script
885
886 interface Some
887 static count: number
888 def Methods(nr: number)
889 endinterface
890
891 class SomeImpl implements Some
892 static count: number
893 def Method(nr: number)
894 echo nr
895 enddef
896 endclass
897 END
898 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000899
900 # Check different order of members in class and interface works.
901 lines =<< trim END
902 vim9script
903
904 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000905 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000906 this.errpos: number
907 endinterface
908
909 # order of members is opposite of interface
910 class Failure implements Result
911 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000912 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000913 endclass
914
915 def Test()
916 var result: Result = Failure.new()
917
918 assert_equal('label', result.label)
919 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000920
921 result.label = 'different'
922 assert_equal('different', result.label)
923 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000924 enddef
925
926 Test()
927 END
928 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +0000929enddef
930
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000931def Test_class_used_as_type()
932 var lines =<< trim END
933 vim9script
934
935 class Point
936 this.x = 0
937 this.y = 0
938 endclass
939
940 var p: Point
941 p = Point.new(2, 33)
942 assert_equal(2, p.x)
943 assert_equal(33, p.y)
944 END
945 v9.CheckScriptSuccess(lines)
946
947 lines =<< trim END
948 vim9script
949
950 interface HasX
951 this.x: number
952 endinterface
953
954 class Point implements HasX
955 this.x = 0
956 this.y = 0
957 endclass
958
959 var p: Point
960 p = Point.new(2, 33)
961 var hx = p
962 assert_equal(2, hx.x)
963 END
964 v9.CheckScriptSuccess(lines)
965
966 lines =<< trim END
967 vim9script
968
969 class Point
970 this.x = 0
971 this.y = 0
972 endclass
973
974 var p: Point
975 p = 'text'
976 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000977 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000978enddef
979
Bram Moolenaar83677162023-01-08 19:54:10 +0000980def Test_class_extends()
981 var lines =<< trim END
982 vim9script
983 class Base
984 this.one = 1
985 def GetOne(): number
986 return this.one
987 enddef
988 endclass
989 class Child extends Base
990 this.two = 2
991 def GetTotal(): number
992 return this.one + this.two
993 enddef
994 endclass
995 var o = Child.new()
996 assert_equal(1, o.one)
997 assert_equal(2, o.two)
998 assert_equal(1, o.GetOne())
999 assert_equal(3, o.GetTotal())
1000 END
1001 v9.CheckScriptSuccess(lines)
1002
1003 lines =<< trim END
1004 vim9script
1005 class Base
1006 this.one = 1
1007 endclass
1008 class Child extends Base
1009 this.two = 2
1010 endclass
1011 var o = Child.new(3, 44)
1012 assert_equal(3, o.one)
1013 assert_equal(44, o.two)
1014 END
1015 v9.CheckScriptSuccess(lines)
1016
1017 lines =<< trim END
1018 vim9script
1019 class Base
1020 this.one = 1
1021 endclass
1022 class Child extends Base extends Base
1023 this.two = 2
1024 endclass
1025 END
1026 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1027
1028 lines =<< trim END
1029 vim9script
1030 class Child extends BaseClass
1031 this.two = 2
1032 endclass
1033 END
1034 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1035
1036 lines =<< trim END
1037 vim9script
1038 var SomeVar = 99
1039 class Child extends SomeVar
1040 this.two = 2
1041 endclass
1042 END
1043 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001044
1045 lines =<< trim END
1046 vim9script
1047 class Base
1048 this.name: string
1049 def ToString(): string
1050 return this.name
1051 enddef
1052 endclass
1053
1054 class Child extends Base
1055 this.age: number
1056 def ToString(): string
1057 return super.ToString() .. ': ' .. this.age
1058 enddef
1059 endclass
1060
1061 var o = Child.new('John', 42)
1062 assert_equal('John: 42', o.ToString())
1063 END
1064 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001065
1066 lines =<< trim END
1067 vim9script
1068 class Child
1069 this.age: number
1070 def ToString(): number
1071 return this.age
1072 enddef
1073 def ToString(): string
1074 return this.age
1075 enddef
1076 endclass
1077 END
1078 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1079
1080 lines =<< trim END
1081 vim9script
1082 class Child
1083 this.age: number
1084 def ToString(): string
1085 return super .ToString() .. ': ' .. this.age
1086 enddef
1087 endclass
1088 var o = Child.new(42)
1089 echo o.ToString()
1090 END
1091 v9.CheckScriptFailure(lines, 'E1356:')
1092
1093 lines =<< trim END
1094 vim9script
1095 class Base
1096 this.name: string
1097 def ToString(): string
1098 return this.name
1099 enddef
1100 endclass
1101
1102 var age = 42
1103 def ToString(): string
1104 return super.ToString() .. ': ' .. age
1105 enddef
1106 echo ToString()
1107 END
1108 v9.CheckScriptFailure(lines, 'E1357:')
1109
1110 lines =<< trim END
1111 vim9script
1112 class Child
1113 this.age: number
1114 def ToString(): string
1115 return super.ToString() .. ': ' .. this.age
1116 enddef
1117 endclass
1118 var o = Child.new(42)
1119 echo o.ToString()
1120 END
1121 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001122
1123 lines =<< trim END
1124 vim9script
1125 class Base
1126 this.name: string
1127 static def ToString(): string
1128 return 'Base class'
1129 enddef
1130 endclass
1131
1132 class Child extends Base
1133 this.age: number
1134 def ToString(): string
1135 return Base.ToString() .. ': ' .. this.age
1136 enddef
1137 endclass
1138
1139 var o = Child.new('John', 42)
1140 assert_equal('Base class: 42', o.ToString())
1141 END
1142 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001143
1144 lines =<< trim END
1145 vim9script
1146 class Base
1147 this.value = 1
1148 def new(init: number)
1149 this.value = number + 1
1150 enddef
1151 endclass
1152 class Child extends Base
1153 def new()
1154 this.new(3)
1155 enddef
1156 endclass
1157 var c = Child.new()
1158 END
1159 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001160
1161 # base class with more than one object member
1162 lines =<< trim END
1163 vim9script
1164
1165 class Result
1166 this.success: bool
1167 this.value: any = null
1168 endclass
1169
1170 class Success extends Result
1171 def new(this.value = v:none)
1172 this.success = true
1173 enddef
1174 endclass
1175
1176 var v = Success.new('asdf')
1177 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1178 END
1179 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001180enddef
1181
Bram Moolenaara86655a2023-01-12 17:06:27 +00001182def Test_class_import()
1183 var lines =<< trim END
1184 vim9script
1185 export class Animal
1186 this.kind: string
1187 this.name: string
1188 endclass
1189 END
1190 writefile(lines, 'Xanimal.vim', 'D')
1191
1192 lines =<< trim END
1193 vim9script
1194 import './Xanimal.vim' as animal
1195
1196 var a: animal.Animal
1197 a = animal.Animal.new('fish', 'Eric')
1198 assert_equal('fish', a.kind)
1199 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001200
1201 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1202 assert_equal('cat', b.kind)
1203 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001204 END
1205 v9.CheckScriptSuccess(lines)
1206enddef
1207
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001208def Test_abstract_class()
1209 var lines =<< trim END
1210 vim9script
1211 abstract class Base
1212 this.name: string
1213 endclass
1214 class Person extends Base
1215 this.age: number
1216 endclass
1217 var p: Base = Person.new('Peter', 42)
1218 assert_equal('Peter', p.name)
1219 assert_equal(42, p.age)
1220 END
1221 v9.CheckScriptSuccess(lines)
1222
1223 lines =<< trim END
1224 vim9script
1225 abstract class Base
1226 this.name: string
1227 endclass
1228 class Person extends Base
1229 this.age: number
1230 endclass
1231 var p = Base.new('Peter')
1232 END
1233 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1234
1235 lines =<< trim END
1236 abstract class Base
1237 this.name: string
1238 endclass
1239 END
1240 v9.CheckScriptFailure(lines, 'E1316:')
1241enddef
1242
Bram Moolenaar486fc252023-01-18 14:51:07 +00001243def Test_closure_in_class()
1244 var lines =<< trim END
1245 vim9script
1246
1247 class Foo
1248 this.y: list<string> = ['B']
1249
1250 def new()
1251 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1252 enddef
1253 endclass
1254
1255 Foo.new()
1256 assert_equal(['A'], g:result)
1257 END
1258 v9.CheckScriptSuccess(lines)
1259enddef
1260
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001261
1262" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker