blob: 389213680b8c2ca4c4da33c615303c381c6d8288 [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 Moolenaar62a69232023-01-24 15:07:04 +0000648 # access private member in lambda
649 lines =<< trim END
650 vim9script
651
652 class Foo
653 this._x: number = 0
654
655 def Add(n: number): number
656 const F = (): number => this._x + n
657 return F()
658 enddef
659 endclass
660
661 var foo = Foo.new()
662 assert_equal(5, foo.Add(5))
663 END
664 v9.CheckScriptSuccess(lines)
665
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000666 # check shadowing
667 lines =<< trim END
668 vim9script
669
670 class Some
671 static count = 0
672 def Method(count: number)
673 echo count
674 enddef
675 endclass
676
677 var s = Some.new()
678 s.Method(7)
679 END
680 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
681
682 lines =<< trim END
683 vim9script
684
685 class Some
686 static count = 0
687 def Method(arg: number)
688 var count = 3
689 echo arg count
690 enddef
691 endclass
692
693 var s = Some.new()
694 s.Method(7)
695 END
696 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000697enddef
698
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000699func Test_class_garbagecollect()
700 let lines =<< trim END
701 vim9script
702
703 class Point
704 this.p = [2, 3]
705 static pl = ['a', 'b']
706 static pd = {a: 'a', b: 'b'}
707 endclass
708
709 echo Point.pl Point.pd
710 call test_garbagecollect_now()
711 echo Point.pl Point.pd
712 END
713 call v9.CheckScriptSuccess(lines)
714endfunc
715
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000716def Test_class_function()
717 var lines =<< trim END
718 vim9script
719 class Value
720 this.value = 0
721 static objects = 0
722
723 def new(v: number)
724 this.value = v
725 ++objects
726 enddef
727
728 static def GetCount(): number
729 return objects
730 enddef
731 endclass
732
733 assert_equal(0, Value.GetCount())
734 var v1 = Value.new(2)
735 assert_equal(1, Value.GetCount())
736 var v2 = Value.new(7)
737 assert_equal(2, Value.GetCount())
738 END
739 v9.CheckScriptSuccess(lines)
740enddef
741
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000742def Test_class_object_to_string()
743 var lines =<< trim END
744 vim9script
745 class TextPosition
746 this.lnum = 1
747 this.col = 22
748 endclass
749
750 assert_equal("class TextPosition", string(TextPosition))
751
752 var pos = TextPosition.new()
753 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
754 END
755 v9.CheckScriptSuccess(lines)
756enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000757
Bram Moolenaar554d0312023-01-05 19:59:18 +0000758def Test_interface_basics()
759 var lines =<< trim END
760 vim9script
761 interface Something
762 this.value: string
763 static count: number
764 def GetCount(): number
765 endinterface
766 END
767 v9.CheckScriptSuccess(lines)
768
769 lines =<< trim END
770 interface SomethingWrong
771 static count = 7
772 endinterface
773 END
774 v9.CheckScriptFailure(lines, 'E1342:')
775
776 lines =<< trim END
777 vim9script
778
779 interface Some
780 static count: number
781 def Method(count: number)
782 endinterface
783 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000784 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
785
786 lines =<< trim END
787 vim9script
788
789 interface Some
790 this.value: number
791 def Method(value: number)
792 endinterface
793 END
794 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +0000795
796 lines =<< trim END
797 vim9script
798 interface somethingWrong
799 static count = 7
800 endinterface
801 END
802 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
803
804 lines =<< trim END
805 vim9script
806 interface SomethingWrong
807 this.value: string
808 static count = 7
809 def GetCount(): number
810 endinterface
811 END
812 v9.CheckScriptFailure(lines, 'E1344:')
813
814 lines =<< trim END
815 vim9script
816 interface SomethingWrong
817 this.value: string
818 static count: number
819 def GetCount(): number
820 return 5
821 enddef
822 endinterface
823 END
824 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
825enddef
826
Bram Moolenaar94674f22023-01-06 18:42:20 +0000827def Test_class_implements_interface()
828 var lines =<< trim END
829 vim9script
830
831 interface Some
832 static count: number
833 def Method(nr: number)
834 endinterface
835
836 class SomeImpl implements Some
837 static count: number
838 def Method(nr: number)
839 echo nr
840 enddef
841 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000842
843 interface Another
844 this.member: string
845 endinterface
846
847 class SomeImpl implements Some, Another
848 this.member = 'abc'
849 static count: number
850 def Method(nr: number)
851 echo nr
852 enddef
853 endclass
854
Bram Moolenaar94674f22023-01-06 18:42:20 +0000855 END
856 v9.CheckScriptSuccess(lines)
857
858 lines =<< trim END
859 vim9script
860
861 interface Some
862 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000863 endinterface
864
865 class SomeImpl implements Some implements Some
866 static count: number
867 endclass
868 END
869 v9.CheckScriptFailure(lines, 'E1350:')
870
871 lines =<< trim END
872 vim9script
873
874 interface Some
875 static counter: number
876 endinterface
877
878 class SomeImpl implements Some, Some
879 static count: number
880 endclass
881 END
882 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
883
884 lines =<< trim END
885 vim9script
886
887 interface Some
888 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +0000889 def Method(nr: number)
890 endinterface
891
892 class SomeImpl implements Some
893 static count: number
894 def Method(nr: number)
895 echo nr
896 enddef
897 endclass
898 END
899 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
900
901 lines =<< trim END
902 vim9script
903
904 interface Some
905 static count: number
906 def Methods(nr: number)
907 endinterface
908
909 class SomeImpl implements Some
910 static count: number
911 def Method(nr: number)
912 echo nr
913 enddef
914 endclass
915 END
916 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000917
918 # Check different order of members in class and interface works.
919 lines =<< trim END
920 vim9script
921
922 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000923 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000924 this.errpos: number
925 endinterface
926
927 # order of members is opposite of interface
928 class Failure implements Result
929 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000930 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000931 endclass
932
933 def Test()
934 var result: Result = Failure.new()
935
936 assert_equal('label', result.label)
937 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000938
939 result.label = 'different'
940 assert_equal('different', result.label)
941 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000942 enddef
943
944 Test()
945 END
946 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +0000947enddef
948
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000949def Test_class_used_as_type()
950 var lines =<< trim END
951 vim9script
952
953 class Point
954 this.x = 0
955 this.y = 0
956 endclass
957
958 var p: Point
959 p = Point.new(2, 33)
960 assert_equal(2, p.x)
961 assert_equal(33, p.y)
962 END
963 v9.CheckScriptSuccess(lines)
964
965 lines =<< trim END
966 vim9script
967
968 interface HasX
969 this.x: number
970 endinterface
971
972 class Point implements HasX
973 this.x = 0
974 this.y = 0
975 endclass
976
977 var p: Point
978 p = Point.new(2, 33)
979 var hx = p
980 assert_equal(2, hx.x)
981 END
982 v9.CheckScriptSuccess(lines)
983
984 lines =<< trim END
985 vim9script
986
987 class Point
988 this.x = 0
989 this.y = 0
990 endclass
991
992 var p: Point
993 p = 'text'
994 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000995 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000996enddef
997
Bram Moolenaar83677162023-01-08 19:54:10 +0000998def Test_class_extends()
999 var lines =<< trim END
1000 vim9script
1001 class Base
1002 this.one = 1
1003 def GetOne(): number
1004 return this.one
1005 enddef
1006 endclass
1007 class Child extends Base
1008 this.two = 2
1009 def GetTotal(): number
1010 return this.one + this.two
1011 enddef
1012 endclass
1013 var o = Child.new()
1014 assert_equal(1, o.one)
1015 assert_equal(2, o.two)
1016 assert_equal(1, o.GetOne())
1017 assert_equal(3, o.GetTotal())
1018 END
1019 v9.CheckScriptSuccess(lines)
1020
1021 lines =<< trim END
1022 vim9script
1023 class Base
1024 this.one = 1
1025 endclass
1026 class Child extends Base
1027 this.two = 2
1028 endclass
1029 var o = Child.new(3, 44)
1030 assert_equal(3, o.one)
1031 assert_equal(44, o.two)
1032 END
1033 v9.CheckScriptSuccess(lines)
1034
1035 lines =<< trim END
1036 vim9script
1037 class Base
1038 this.one = 1
1039 endclass
1040 class Child extends Base extends Base
1041 this.two = 2
1042 endclass
1043 END
1044 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1045
1046 lines =<< trim END
1047 vim9script
1048 class Child extends BaseClass
1049 this.two = 2
1050 endclass
1051 END
1052 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1053
1054 lines =<< trim END
1055 vim9script
1056 var SomeVar = 99
1057 class Child extends SomeVar
1058 this.two = 2
1059 endclass
1060 END
1061 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001062
1063 lines =<< trim END
1064 vim9script
1065 class Base
1066 this.name: string
1067 def ToString(): string
1068 return this.name
1069 enddef
1070 endclass
1071
1072 class Child extends Base
1073 this.age: number
1074 def ToString(): string
1075 return super.ToString() .. ': ' .. this.age
1076 enddef
1077 endclass
1078
1079 var o = Child.new('John', 42)
1080 assert_equal('John: 42', o.ToString())
1081 END
1082 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001083
1084 lines =<< trim END
1085 vim9script
1086 class Child
1087 this.age: number
1088 def ToString(): number
1089 return this.age
1090 enddef
1091 def ToString(): string
1092 return this.age
1093 enddef
1094 endclass
1095 END
1096 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1097
1098 lines =<< trim END
1099 vim9script
1100 class Child
1101 this.age: number
1102 def ToString(): string
1103 return super .ToString() .. ': ' .. this.age
1104 enddef
1105 endclass
1106 var o = Child.new(42)
1107 echo o.ToString()
1108 END
1109 v9.CheckScriptFailure(lines, 'E1356:')
1110
1111 lines =<< trim END
1112 vim9script
1113 class Base
1114 this.name: string
1115 def ToString(): string
1116 return this.name
1117 enddef
1118 endclass
1119
1120 var age = 42
1121 def ToString(): string
1122 return super.ToString() .. ': ' .. age
1123 enddef
1124 echo ToString()
1125 END
1126 v9.CheckScriptFailure(lines, 'E1357:')
1127
1128 lines =<< trim END
1129 vim9script
1130 class Child
1131 this.age: number
1132 def ToString(): string
1133 return super.ToString() .. ': ' .. this.age
1134 enddef
1135 endclass
1136 var o = Child.new(42)
1137 echo o.ToString()
1138 END
1139 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001140
1141 lines =<< trim END
1142 vim9script
1143 class Base
1144 this.name: string
1145 static def ToString(): string
1146 return 'Base class'
1147 enddef
1148 endclass
1149
1150 class Child extends Base
1151 this.age: number
1152 def ToString(): string
1153 return Base.ToString() .. ': ' .. this.age
1154 enddef
1155 endclass
1156
1157 var o = Child.new('John', 42)
1158 assert_equal('Base class: 42', o.ToString())
1159 END
1160 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001161
1162 lines =<< trim END
1163 vim9script
1164 class Base
1165 this.value = 1
1166 def new(init: number)
1167 this.value = number + 1
1168 enddef
1169 endclass
1170 class Child extends Base
1171 def new()
1172 this.new(3)
1173 enddef
1174 endclass
1175 var c = Child.new()
1176 END
1177 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001178
1179 # base class with more than one object member
1180 lines =<< trim END
1181 vim9script
1182
1183 class Result
1184 this.success: bool
1185 this.value: any = null
1186 endclass
1187
1188 class Success extends Result
1189 def new(this.value = v:none)
1190 this.success = true
1191 enddef
1192 endclass
1193
1194 var v = Success.new('asdf')
1195 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1196 END
1197 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001198enddef
1199
Bram Moolenaara86655a2023-01-12 17:06:27 +00001200def Test_class_import()
1201 var lines =<< trim END
1202 vim9script
1203 export class Animal
1204 this.kind: string
1205 this.name: string
1206 endclass
1207 END
1208 writefile(lines, 'Xanimal.vim', 'D')
1209
1210 lines =<< trim END
1211 vim9script
1212 import './Xanimal.vim' as animal
1213
1214 var a: animal.Animal
1215 a = animal.Animal.new('fish', 'Eric')
1216 assert_equal('fish', a.kind)
1217 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001218
1219 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1220 assert_equal('cat', b.kind)
1221 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001222 END
1223 v9.CheckScriptSuccess(lines)
1224enddef
1225
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001226def Test_abstract_class()
1227 var lines =<< trim END
1228 vim9script
1229 abstract class Base
1230 this.name: string
1231 endclass
1232 class Person extends Base
1233 this.age: number
1234 endclass
1235 var p: Base = Person.new('Peter', 42)
1236 assert_equal('Peter', p.name)
1237 assert_equal(42, p.age)
1238 END
1239 v9.CheckScriptSuccess(lines)
1240
1241 lines =<< trim END
1242 vim9script
1243 abstract class Base
1244 this.name: string
1245 endclass
1246 class Person extends Base
1247 this.age: number
1248 endclass
1249 var p = Base.new('Peter')
1250 END
1251 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1252
1253 lines =<< trim END
1254 abstract class Base
1255 this.name: string
1256 endclass
1257 END
1258 v9.CheckScriptFailure(lines, 'E1316:')
1259enddef
1260
Bram Moolenaar486fc252023-01-18 14:51:07 +00001261def Test_closure_in_class()
1262 var lines =<< trim END
1263 vim9script
1264
1265 class Foo
1266 this.y: list<string> = ['B']
1267
1268 def new()
1269 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1270 enddef
1271 endclass
1272
1273 Foo.new()
1274 assert_equal(['A'], g:result)
1275 END
1276 v9.CheckScriptSuccess(lines)
1277enddef
1278
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001279
1280" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker