blob: 5edd511a3cb593fc38c7aafc51d020715a3f9db7 [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')
Bram Moolenaar53f54e42023-01-26 20:36:56 +0000825
826 lines =<< trim END
827 vim9script
828 export interface EnterExit
829 def Enter(): void
830 def Exit(): void
831 endinterface
832 END
833 writefile(lines, 'XdefIntf.vim', 'D')
834
835 lines =<< trim END
836 vim9script
837 import './XdefIntf.vim' as defIntf
838 export def With(ee: defIntf.EnterExit, F: func)
839 ee.Enter()
840 try
841 F()
842 finally
843 ee.Exit()
844 endtry
845 enddef
846 END
847 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +0000848enddef
849
Bram Moolenaar94674f22023-01-06 18:42:20 +0000850def Test_class_implements_interface()
851 var lines =<< trim END
852 vim9script
853
854 interface Some
855 static count: number
856 def Method(nr: number)
857 endinterface
858
859 class SomeImpl implements Some
860 static count: number
861 def Method(nr: number)
862 echo nr
863 enddef
864 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000865
866 interface Another
867 this.member: string
868 endinterface
869
870 class SomeImpl implements Some, Another
871 this.member = 'abc'
872 static count: number
873 def Method(nr: number)
874 echo nr
875 enddef
876 endclass
877
Bram Moolenaar94674f22023-01-06 18:42:20 +0000878 END
879 v9.CheckScriptSuccess(lines)
880
881 lines =<< trim END
882 vim9script
883
884 interface Some
885 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +0000886 endinterface
887
888 class SomeImpl implements Some implements Some
889 static count: number
890 endclass
891 END
892 v9.CheckScriptFailure(lines, 'E1350:')
893
894 lines =<< trim END
895 vim9script
896
897 interface Some
898 static counter: number
899 endinterface
900
901 class SomeImpl implements Some, Some
902 static count: number
903 endclass
904 END
905 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
906
907 lines =<< trim END
908 vim9script
909
910 interface Some
911 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +0000912 def Method(nr: number)
913 endinterface
914
915 class SomeImpl implements Some
916 static count: number
917 def Method(nr: number)
918 echo nr
919 enddef
920 endclass
921 END
922 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
923
924 lines =<< trim END
925 vim9script
926
927 interface Some
928 static count: number
929 def Methods(nr: number)
930 endinterface
931
932 class SomeImpl implements Some
933 static count: number
934 def Method(nr: number)
935 echo nr
936 enddef
937 endclass
938 END
939 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000940
941 # Check different order of members in class and interface works.
942 lines =<< trim END
943 vim9script
944
945 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000946 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000947 this.errpos: number
948 endinterface
949
950 # order of members is opposite of interface
951 class Failure implements Result
952 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000953 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000954 endclass
955
956 def Test()
957 var result: Result = Failure.new()
958
959 assert_equal('label', result.label)
960 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +0000961
962 result.label = 'different'
963 assert_equal('different', result.label)
964 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +0000965 enddef
966
967 Test()
968 END
969 v9.CheckScriptSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +0000970enddef
971
Bram Moolenaareca2c5f2023-01-07 12:08:41 +0000972def Test_class_used_as_type()
973 var lines =<< trim END
974 vim9script
975
976 class Point
977 this.x = 0
978 this.y = 0
979 endclass
980
981 var p: Point
982 p = Point.new(2, 33)
983 assert_equal(2, p.x)
984 assert_equal(33, p.y)
985 END
986 v9.CheckScriptSuccess(lines)
987
988 lines =<< trim END
989 vim9script
990
991 interface HasX
992 this.x: number
993 endinterface
994
995 class Point implements HasX
996 this.x = 0
997 this.y = 0
998 endclass
999
1000 var p: Point
1001 p = Point.new(2, 33)
1002 var hx = p
1003 assert_equal(2, hx.x)
1004 END
1005 v9.CheckScriptSuccess(lines)
1006
1007 lines =<< trim END
1008 vim9script
1009
1010 class Point
1011 this.x = 0
1012 this.y = 0
1013 endclass
1014
1015 var p: Point
1016 p = 'text'
1017 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001018 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001019enddef
1020
Bram Moolenaar83677162023-01-08 19:54:10 +00001021def Test_class_extends()
1022 var lines =<< trim END
1023 vim9script
1024 class Base
1025 this.one = 1
1026 def GetOne(): number
1027 return this.one
1028 enddef
1029 endclass
1030 class Child extends Base
1031 this.two = 2
1032 def GetTotal(): number
1033 return this.one + this.two
1034 enddef
1035 endclass
1036 var o = Child.new()
1037 assert_equal(1, o.one)
1038 assert_equal(2, o.two)
1039 assert_equal(1, o.GetOne())
1040 assert_equal(3, o.GetTotal())
1041 END
1042 v9.CheckScriptSuccess(lines)
1043
1044 lines =<< trim END
1045 vim9script
1046 class Base
1047 this.one = 1
1048 endclass
1049 class Child extends Base
1050 this.two = 2
1051 endclass
1052 var o = Child.new(3, 44)
1053 assert_equal(3, o.one)
1054 assert_equal(44, o.two)
1055 END
1056 v9.CheckScriptSuccess(lines)
1057
1058 lines =<< trim END
1059 vim9script
1060 class Base
1061 this.one = 1
1062 endclass
1063 class Child extends Base extends Base
1064 this.two = 2
1065 endclass
1066 END
1067 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1068
1069 lines =<< trim END
1070 vim9script
1071 class Child extends BaseClass
1072 this.two = 2
1073 endclass
1074 END
1075 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1076
1077 lines =<< trim END
1078 vim9script
1079 var SomeVar = 99
1080 class Child extends SomeVar
1081 this.two = 2
1082 endclass
1083 END
1084 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001085
1086 lines =<< trim END
1087 vim9script
1088 class Base
1089 this.name: string
1090 def ToString(): string
1091 return this.name
1092 enddef
1093 endclass
1094
1095 class Child extends Base
1096 this.age: number
1097 def ToString(): string
1098 return super.ToString() .. ': ' .. this.age
1099 enddef
1100 endclass
1101
1102 var o = Child.new('John', 42)
1103 assert_equal('John: 42', o.ToString())
1104 END
1105 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001106
1107 lines =<< trim END
1108 vim9script
1109 class Child
1110 this.age: number
1111 def ToString(): number
1112 return this.age
1113 enddef
1114 def ToString(): string
1115 return this.age
1116 enddef
1117 endclass
1118 END
1119 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1120
1121 lines =<< trim END
1122 vim9script
1123 class Child
1124 this.age: number
1125 def ToString(): string
1126 return super .ToString() .. ': ' .. this.age
1127 enddef
1128 endclass
1129 var o = Child.new(42)
1130 echo o.ToString()
1131 END
1132 v9.CheckScriptFailure(lines, 'E1356:')
1133
1134 lines =<< trim END
1135 vim9script
1136 class Base
1137 this.name: string
1138 def ToString(): string
1139 return this.name
1140 enddef
1141 endclass
1142
1143 var age = 42
1144 def ToString(): string
1145 return super.ToString() .. ': ' .. age
1146 enddef
1147 echo ToString()
1148 END
1149 v9.CheckScriptFailure(lines, 'E1357:')
1150
1151 lines =<< trim END
1152 vim9script
1153 class Child
1154 this.age: number
1155 def ToString(): string
1156 return super.ToString() .. ': ' .. this.age
1157 enddef
1158 endclass
1159 var o = Child.new(42)
1160 echo o.ToString()
1161 END
1162 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001163
1164 lines =<< trim END
1165 vim9script
1166 class Base
1167 this.name: string
1168 static def ToString(): string
1169 return 'Base class'
1170 enddef
1171 endclass
1172
1173 class Child extends Base
1174 this.age: number
1175 def ToString(): string
1176 return Base.ToString() .. ': ' .. this.age
1177 enddef
1178 endclass
1179
1180 var o = Child.new('John', 42)
1181 assert_equal('Base class: 42', o.ToString())
1182 END
1183 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001184
1185 lines =<< trim END
1186 vim9script
1187 class Base
1188 this.value = 1
1189 def new(init: number)
1190 this.value = number + 1
1191 enddef
1192 endclass
1193 class Child extends Base
1194 def new()
1195 this.new(3)
1196 enddef
1197 endclass
1198 var c = Child.new()
1199 END
1200 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00001201
1202 # base class with more than one object member
1203 lines =<< trim END
1204 vim9script
1205
1206 class Result
1207 this.success: bool
1208 this.value: any = null
1209 endclass
1210
1211 class Success extends Result
1212 def new(this.value = v:none)
1213 this.success = true
1214 enddef
1215 endclass
1216
1217 var v = Success.new('asdf')
1218 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1219 END
1220 v9.CheckScriptSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00001221enddef
1222
Bram Moolenaara86655a2023-01-12 17:06:27 +00001223def Test_class_import()
1224 var lines =<< trim END
1225 vim9script
1226 export class Animal
1227 this.kind: string
1228 this.name: string
1229 endclass
1230 END
1231 writefile(lines, 'Xanimal.vim', 'D')
1232
1233 lines =<< trim END
1234 vim9script
1235 import './Xanimal.vim' as animal
1236
1237 var a: animal.Animal
1238 a = animal.Animal.new('fish', 'Eric')
1239 assert_equal('fish', a.kind)
1240 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00001241
1242 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
1243 assert_equal('cat', b.kind)
1244 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00001245 END
1246 v9.CheckScriptSuccess(lines)
1247enddef
1248
Bram Moolenaar24a8d062023-01-14 13:12:06 +00001249def Test_abstract_class()
1250 var lines =<< trim END
1251 vim9script
1252 abstract class Base
1253 this.name: string
1254 endclass
1255 class Person extends Base
1256 this.age: number
1257 endclass
1258 var p: Base = Person.new('Peter', 42)
1259 assert_equal('Peter', p.name)
1260 assert_equal(42, p.age)
1261 END
1262 v9.CheckScriptSuccess(lines)
1263
1264 lines =<< trim END
1265 vim9script
1266 abstract class Base
1267 this.name: string
1268 endclass
1269 class Person extends Base
1270 this.age: number
1271 endclass
1272 var p = Base.new('Peter')
1273 END
1274 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
1275
1276 lines =<< trim END
1277 abstract class Base
1278 this.name: string
1279 endclass
1280 END
1281 v9.CheckScriptFailure(lines, 'E1316:')
1282enddef
1283
Bram Moolenaar486fc252023-01-18 14:51:07 +00001284def Test_closure_in_class()
1285 var lines =<< trim END
1286 vim9script
1287
1288 class Foo
1289 this.y: list<string> = ['B']
1290
1291 def new()
1292 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
1293 enddef
1294 endclass
1295
1296 Foo.new()
1297 assert_equal(['A'], g:result)
1298 END
1299 v9.CheckScriptSuccess(lines)
1300enddef
1301
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001302
1303" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker