blob: dadd3e4df5691557d72a3fe13e84dfb70b3c15b6 [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 Moolenaard505d172022-12-18 21:42:55 +0000442enddef
443
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000444def Test_class_object_compare()
445 var class_lines =<< trim END
446 vim9script
447 class Item
448 this.nr = 0
449 this.name = 'xx'
450 endclass
451 END
452
453 # used at the script level and in a compiled function
454 var test_lines =<< trim END
455 var i1 = Item.new()
456 assert_equal(i1, i1)
457 assert_true(i1 is i1)
458 var i2 = Item.new()
459 assert_equal(i1, i2)
460 assert_false(i1 is i2)
461 var i3 = Item.new(0, 'xx')
462 assert_equal(i1, i3)
463
464 var io1 = Item.new(1, 'xx')
465 assert_notequal(i1, io1)
466 var io2 = Item.new(0, 'yy')
467 assert_notequal(i1, io2)
468 END
469
470 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000471 v9.CheckScriptSuccess(
472 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000473
474 for op in ['>', '>=', '<', '<=', '=~', '!~']
475 var op_lines = [
476 'var i1 = Item.new()',
477 'var i2 = Item.new()',
478 'echo i1 ' .. op .. ' i2',
479 ]
480 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000481 v9.CheckScriptFailure(class_lines
482 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000483 endfor
484enddef
485
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000486def Test_object_type()
487 var lines =<< trim END
488 vim9script
489
490 class One
491 this.one = 1
492 endclass
493 class Two
494 this.two = 2
495 endclass
496 class TwoMore extends Two
497 this.more = 9
498 endclass
499
500 var o: One = One.new()
501 var t: Two = Two.new()
502 var m: TwoMore = TwoMore.new()
503 var tm: Two = TwoMore.new()
504
505 t = m
506 END
507 v9.CheckScriptSuccess(lines)
508
509 lines =<< trim END
510 vim9script
511
512 class One
513 this.one = 1
514 endclass
515 class Two
516 this.two = 2
517 endclass
518
519 var o: One = Two.new()
520 END
521 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000522
523 lines =<< trim END
524 vim9script
525
526 interface One
527 def GetMember(): number
528 endinterface
529 class Two implements One
530 this.one = 1
531 def GetMember(): number
532 return this.one
533 enddef
534 endclass
535
536 var o: One = Two.new(5)
537 assert_equal(5, o.GetMember())
538 END
539 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +0000540
541 lines =<< trim END
542 vim9script
543
544 class Num
545 this.n: number = 0
546 endclass
547
548 def Ref(name: string): func(Num): Num
549 return (arg: Num): Num => {
550 return eval(name)(arg)
551 }
552 enddef
553
554 const Fn = Ref('Double')
555 var Double = (m: Num): Num => Num.new(m.n * 2)
556
557 echo Fn(Num.new(4))
558 END
559 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000560enddef
561
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000562def Test_class_member()
563 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +0000564 var lines =<< trim END
565 vim9script
566 class TextPos
567 this.lnum = 1
568 this.col = 1
569 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000570 static _secret = 7
571 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +0000572
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000573 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +0000574 counter += nr
575 enddef
576 endclass
577
578 assert_equal(0, TextPos.counter)
579 TextPos.AddToCounter(3)
580 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000581 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar3259ff32023-01-04 18:54:09 +0000582
583 def GetCounter(): number
584 return TextPos.counter
585 enddef
586 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +0000587
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000588 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +0000589 assert_fails('TextPos.counter = 5', 'E1335:')
590 assert_fails('TextPos.counter += 5', 'E1335:')
591
592 assert_fails('echo TextPos._secret', 'E1333:')
593 assert_fails('TextPos._secret = 8', 'E1333:')
594
595 assert_equal(42, TextPos.anybody)
596 TextPos.anybody = 12
597 assert_equal(12, TextPos.anybody)
598 TextPos.anybody += 5
599 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000600 END
601 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000602
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000603 # example in the help
604 lines =<< trim END
605 vim9script
606 class OtherThing
607 this.size: number
608 static totalSize: number
609
610 def new(this.size)
611 totalSize += this.size
612 enddef
613 endclass
614 assert_equal(0, OtherThing.totalSize)
615 var to3 = OtherThing.new(3)
616 assert_equal(3, OtherThing.totalSize)
617 var to7 = OtherThing.new(7)
618 assert_equal(10, OtherThing.totalSize)
619 END
620 v9.CheckScriptSuccess(lines)
621
Bram Moolenaar6acf7572023-01-01 19:53:30 +0000622 # check shadowing
623 lines =<< trim END
624 vim9script
625
626 class Some
627 static count = 0
628 def Method(count: number)
629 echo count
630 enddef
631 endclass
632
633 var s = Some.new()
634 s.Method(7)
635 END
636 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
637
638 lines =<< trim END
639 vim9script
640
641 class Some
642 static count = 0
643 def Method(arg: number)
644 var count = 3
645 echo arg count
646 enddef
647 endclass
648
649 var s = Some.new()
650 s.Method(7)
651 END
652 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000653enddef
654
Bram Moolenaarcf760d52023-01-05 13:16:04 +0000655func Test_class_garbagecollect()
656 let lines =<< trim END
657 vim9script
658
659 class Point
660 this.p = [2, 3]
661 static pl = ['a', 'b']
662 static pd = {a: 'a', b: 'b'}
663 endclass
664
665 echo Point.pl Point.pd
666 call test_garbagecollect_now()
667 echo Point.pl Point.pd
668 END
669 call v9.CheckScriptSuccess(lines)
670endfunc
671
Bram Moolenaar6bafdd42023-01-01 12:58:33 +0000672def Test_class_function()
673 var lines =<< trim END
674 vim9script
675 class Value
676 this.value = 0
677 static objects = 0
678
679 def new(v: number)
680 this.value = v
681 ++objects
682 enddef
683
684 static def GetCount(): number
685 return objects
686 enddef
687 endclass
688
689 assert_equal(0, Value.GetCount())
690 var v1 = Value.new(2)
691 assert_equal(1, Value.GetCount())
692 var v2 = Value.new(7)
693 assert_equal(2, Value.GetCount())
694 END
695 v9.CheckScriptSuccess(lines)
696enddef
697
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +0000698def Test_class_object_to_string()
699 var lines =<< trim END
700 vim9script
701 class TextPosition
702 this.lnum = 1
703 this.col = 22
704 endclass
705
706 assert_equal("class TextPosition", string(TextPosition))
707
708 var pos = TextPosition.new()
709 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
710 END
711 v9.CheckScriptSuccess(lines)
712enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +0000713
Bram Moolenaar554d0312023-01-05 19:59:18 +0000714def Test_interface_basics()
715 var lines =<< trim END
716 vim9script
717 interface Something
718 this.value: string
719 static count: number
720 def GetCount(): number
721 endinterface
722 END
723 v9.CheckScriptSuccess(lines)
724
725 lines =<< trim END
726 interface SomethingWrong
727 static count = 7
728 endinterface
729 END
730 v9.CheckScriptFailure(lines, 'E1342:')
731
732 lines =<< trim END
733 vim9script
734
735 interface Some
736 static count: number
737 def Method(count: number)
738 endinterface
739 END
Bram Moolenaard40f00c2023-01-13 17:36:49 +0000740 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
741
742 lines =<< trim END
743 vim9script
744
745 interface Some
746 this.value: number
747 def Method(value: number)
748 endinterface
749 END
750 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: value')
Bram Moolenaar554d0312023-01-05 19:59:18 +0000751
752 lines =<< trim END
753 vim9script
754 interface somethingWrong
755 static count = 7
756 endinterface
757 END
758 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
759
760 lines =<< trim END
761 vim9script
762 interface SomethingWrong
763 this.value: string
764 static count = 7
765 def GetCount(): number
766 endinterface
767 END
768 v9.CheckScriptFailure(lines, 'E1344:')
769
770 lines =<< trim END
771 vim9script
772 interface SomethingWrong
773 this.value: string
774 static count: number
775 def GetCount(): number
776 return 5
777 enddef
778 endinterface
779 END
780 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
781enddef
782
Bram Moolenaar94674f22023-01-06 18:42:20 +0000783def Test_class_implements_interface()
784 var lines =<< trim END
785 vim9script
786
787 interface Some
788 static count: number
789 def Method(nr: number)
790 endinterface
791
792 class SomeImpl implements Some
793 static count: number
794 def Method(nr: number)
795 echo nr
796 enddef
797 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000798
799 interface Another
800 this.member: string
801 endinterface
802
803 class SomeImpl implements Some, Another
804 this.member = 'abc'
805 static count: number
806 def Method(nr: number)
807 echo nr
808 enddef
809 endclass
810
Bram Moolenaar94674f22023-01-06 18:42:20 +0000811 END
812 v9.CheckScriptSuccess(lines)
813
814 lines =<< trim END
815 vim9script
816
817 interface Some
818 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000819 endinterface
820
821 class SomeImpl implements Some implements Some
822 static count: number
823 endclass
824 END
825 v9.CheckScriptFailure(lines, 'E1350:')
826
827 lines =<< trim END
828 vim9script
829
830 interface Some
831 static counter: number
832 endinterface
833
834 class SomeImpl implements Some, Some
835 static count: number
836 endclass
837 END
838 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
839
840 lines =<< trim END
841 vim9script
842
843 interface Some
844 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +0000845 def Method(nr: number)
846 endinterface
847
848 class SomeImpl implements Some
849 static count: number
850 def Method(nr: number)
851 echo nr
852 enddef
853 endclass
854 END
855 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
856
857 lines =<< trim END
858 vim9script
859
860 interface Some
861 static count: number
862 def Methods(nr: number)
863 endinterface
864
865 class SomeImpl implements Some
866 static count: number
867 def Method(nr: number)
868 echo nr
869 enddef
870 endclass
871 END
872 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000873
874 # Check different order of members in class and interface works.
875 lines =<< trim END
876 vim9script
877
878 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000879 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000880 this.errpos: number
881 endinterface
882
883 # order of members is opposite of interface
884 class Failure implements Result
885 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000886 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000887 endclass
888
889 def Test()
890 var result: Result = Failure.new()
891
892 assert_equal('label', result.label)
893 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000894
895 result.label = 'different'
896 assert_equal('different', result.label)
897 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000898 enddef
899
900 Test()
901 END
902 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +0000903enddef
904
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000905def Test_class_used_as_type()
906 var lines =<< trim END
907 vim9script
908
909 class Point
910 this.x = 0
911 this.y = 0
912 endclass
913
914 var p: Point
915 p = Point.new(2, 33)
916 assert_equal(2, p.x)
917 assert_equal(33, p.y)
918 END
919 v9.CheckScriptSuccess(lines)
920
921 lines =<< trim END
922 vim9script
923
924 interface HasX
925 this.x: number
926 endinterface
927
928 class Point implements HasX
929 this.x = 0
930 this.y = 0
931 endclass
932
933 var p: Point
934 p = Point.new(2, 33)
935 var hx = p
936 assert_equal(2, hx.x)
937 END
938 v9.CheckScriptSuccess(lines)
939
940 lines =<< trim END
941 vim9script
942
943 class Point
944 this.x = 0
945 this.y = 0
946 endclass
947
948 var p: Point
949 p = 'text'
950 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000951 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000952enddef
953
Bram Moolenaar83677162023-01-08 19:54:10 +0000954def Test_class_extends()
955 var lines =<< trim END
956 vim9script
957 class Base
958 this.one = 1
959 def GetOne(): number
960 return this.one
961 enddef
962 endclass
963 class Child extends Base
964 this.two = 2
965 def GetTotal(): number
966 return this.one + this.two
967 enddef
968 endclass
969 var o = Child.new()
970 assert_equal(1, o.one)
971 assert_equal(2, o.two)
972 assert_equal(1, o.GetOne())
973 assert_equal(3, o.GetTotal())
974 END
975 v9.CheckScriptSuccess(lines)
976
977 lines =<< trim END
978 vim9script
979 class Base
980 this.one = 1
981 endclass
982 class Child extends Base
983 this.two = 2
984 endclass
985 var o = Child.new(3, 44)
986 assert_equal(3, o.one)
987 assert_equal(44, o.two)
988 END
989 v9.CheckScriptSuccess(lines)
990
991 lines =<< trim END
992 vim9script
993 class Base
994 this.one = 1
995 endclass
996 class Child extends Base extends Base
997 this.two = 2
998 endclass
999 END
1000 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1001
1002 lines =<< trim END
1003 vim9script
1004 class Child extends BaseClass
1005 this.two = 2
1006 endclass
1007 END
1008 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1009
1010 lines =<< trim END
1011 vim9script
1012 var SomeVar = 99
1013 class Child extends SomeVar
1014 this.two = 2
1015 endclass
1016 END
1017 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001018
1019 lines =<< trim END
1020 vim9script
1021 class Base
1022 this.name: string
1023 def ToString(): string
1024 return this.name
1025 enddef
1026 endclass
1027
1028 class Child extends Base
1029 this.age: number
1030 def ToString(): string
1031 return super.ToString() .. ': ' .. this.age
1032 enddef
1033 endclass
1034
1035 var o = Child.new('John', 42)
1036 assert_equal('John: 42', o.ToString())
1037 END
1038 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001039
1040 lines =<< trim END
1041 vim9script
1042 class Child
1043 this.age: number
1044 def ToString(): number
1045 return this.age
1046 enddef
1047 def ToString(): string
1048 return this.age
1049 enddef
1050 endclass
1051 END
1052 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1053
1054 lines =<< trim END
1055 vim9script
1056 class Child
1057 this.age: number
1058 def ToString(): string
1059 return super .ToString() .. ': ' .. this.age
1060 enddef
1061 endclass
1062 var o = Child.new(42)
1063 echo o.ToString()
1064 END
1065 v9.CheckScriptFailure(lines, 'E1356:')
1066
1067 lines =<< trim END
1068 vim9script
1069 class Base
1070 this.name: string
1071 def ToString(): string
1072 return this.name
1073 enddef
1074 endclass
1075
1076 var age = 42
1077 def ToString(): string
1078 return super.ToString() .. ': ' .. age
1079 enddef
1080 echo ToString()
1081 END
1082 v9.CheckScriptFailure(lines, 'E1357:')
1083
1084 lines =<< trim END
1085 vim9script
1086 class Child
1087 this.age: number
1088 def ToString(): string
1089 return super.ToString() .. ': ' .. this.age
1090 enddef
1091 endclass
1092 var o = Child.new(42)
1093 echo o.ToString()
1094 END
1095 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001096
1097 lines =<< trim END
1098 vim9script
1099 class Base
1100 this.name: string
1101 static def ToString(): string
1102 return 'Base class'
1103 enddef
1104 endclass
1105
1106 class Child extends Base
1107 this.age: number
1108 def ToString(): string
1109 return Base.ToString() .. ': ' .. this.age
1110 enddef
1111 endclass
1112
1113 var o = Child.new('John', 42)
1114 assert_equal('Base class: 42', o.ToString())
1115 END
1116 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001117
1118 lines =<< trim END
1119 vim9script
1120 class Base
1121 this.value = 1
1122 def new(init: number)
1123 this.value = number + 1
1124 enddef
1125 endclass
1126 class Child extends Base
1127 def new()
1128 this.new(3)
1129 enddef
1130 endclass
1131 var c = Child.new()
1132 END
1133 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001134
1135 # base class with more than one object member
1136 lines =<< trim END
1137 vim9script
1138
1139 class Result
1140 this.success: bool
1141 this.value: any = null
1142 endclass
1143
1144 class Success extends Result
1145 def new(this.value = v:none)
1146 this.success = true
1147 enddef
1148 endclass
1149
1150 var v = Success.new('asdf')
1151 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1152 END
1153 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001154enddef
1155
Bram Moolenaara86655a2023-01-12 17:06:27 +00001156def Test_class_import()
1157 var lines =<< trim END
1158 vim9script
1159 export class Animal
1160 this.kind: string
1161 this.name: string
1162 endclass
1163 END
1164 writefile(lines, 'Xanimal.vim', 'D')
1165
1166 lines =<< trim END
1167 vim9script
1168 import './Xanimal.vim' as animal
1169
1170 var a: animal.Animal
1171 a = animal.Animal.new('fish', 'Eric')
1172 assert_equal('fish', a.kind)
1173 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001174
1175 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1176 assert_equal('cat', b.kind)
1177 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001178 END
1179 v9.CheckScriptSuccess(lines)
1180enddef
1181
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001182def Test_abstract_class()
1183 var lines =<< trim END
1184 vim9script
1185 abstract class Base
1186 this.name: string
1187 endclass
1188 class Person extends Base
1189 this.age: number
1190 endclass
1191 var p: Base = Person.new('Peter', 42)
1192 assert_equal('Peter', p.name)
1193 assert_equal(42, p.age)
1194 END
1195 v9.CheckScriptSuccess(lines)
1196
1197 lines =<< trim END
1198 vim9script
1199 abstract class Base
1200 this.name: string
1201 endclass
1202 class Person extends Base
1203 this.age: number
1204 endclass
1205 var p = Base.new('Peter')
1206 END
1207 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1208
1209 lines =<< trim END
1210 abstract class Base
1211 this.name: string
1212 endclass
1213 END
1214 v9.CheckScriptFailure(lines, 'E1316:')
1215enddef
1216
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001217
1218" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker