blob: fc0edeb5bab2483705799c840ac06ac43519dd11 [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()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmananac773182024-04-27 11:36:12 +020070 # Additional command after "class name"
71 lines =<< trim END
72 vim9script
73 class Something | var x = 10
74 endclass
75 END
76 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
77
78 # Additional command after "object variable"
79 lines =<< trim END
80 vim9script
81 class Something
82 var l: list<number> = [] | var y = 10
83 endclass
84 END
85 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
86
87 # Additional command after "class variable"
88 lines =<< trim END
89 vim9script
90 class Something
91 static var d = {a: 10} | var y = 10
92 endclass
93 END
94 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
95
96 # Additional command after "object method"
97 lines =<< trim END
98 vim9script
99 class Something
100 def Foo() | var y = 10
101 enddef
102 endclass
103 END
104 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var y = 10", 3)
105
Yegappan Lakshmananfe55c312024-04-28 09:54:09 +0200106 # Comments are allowed after an inline block
107 lines =<< trim END
108 vim9script
109 class Foo
110 static const bar = { # {{{
111 baz: 'qux'
112 } # }}}
113 endclass
114 assert_equal({baz: 'qux'}, Foo.bar)
115 END
116 v9.CheckSourceSuccess(lines)
117
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +0100118 # Try to define a class with the same name as an existing variable
119 lines =<< trim END
120 vim9script
121 var Something: list<number> = [1]
122 class Thing
123 endclass
124 interface Api
125 endinterface
126 class Something extends Thing implements Api
127 var v1: string = ''
128 def Foo()
129 enddef
130 endclass
131 END
132 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
133
zeertzjqe7102202024-02-13 20:32:04 +0100134 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100135 lines =<< trim END
136 vim9script
137 class Something
138 this.count: number
139 endclass
140 END
141 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
142
zeertzjqe7102202024-02-13 20:32:04 +0100143 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100144 lines =<< trim END
145 vim9script
146 class Something
147 this.count: number = 42
148 endclass
149 END
150 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
151
152 # Use old "this." prefixed member variable declaration syntax (type inferred)
153 lines =<< trim END
154 vim9script
155 class Something
156 this.count = 42
157 endclass
158 END
159 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
160
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200161 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000162 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 vim9script
164 class Something
165 this
166 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000167 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100168 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000169
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200170 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000171 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200172 vim9script
173 class Something
174 this.
175 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000176 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100177 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000178
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200179 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000180 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200181 vim9script
182 class Something
183 this .count
184 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000185 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100186 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000187
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200188 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000189 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 vim9script
191 class Something
192 this. count
193 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200197 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000198 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200199 vim9script
200 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100201 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200202 that.count
203 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200205 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000206
Doug Kearns74da0ee2023-12-14 20:26:26 +0100207 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200209 vim9script
210 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100211 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000213 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100214 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
215
216 # Use "variable" instead of "var" for member variable declaration (with initialization)
217 lines =<< trim END
218 vim9script
219 class Something
220 variable count: number = 42
221 endclass
222 END
223 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
224
225 # Use "variable" instead of "var" for member variable declaration (type inferred)
226 lines =<< trim END
227 vim9script
228 class Something
229 variable count = 42
230 endclass
231 END
232 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
238 def new()
239 this.state = 0
240 enddef
241 endclass
242 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000243 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200244 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000245
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200246 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000247 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 vim9script
249 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100250 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200251 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200253 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000254
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200255 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200257 vim9script
258 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100259 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200260 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200262 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000263
Doug Kearns74da0ee2023-12-14 20:26:26 +0100264 # Missing ":var" in a "var" member variable declaration (without initialization)
265 lines =<< trim END
266 vim9script
267 class Something
268 var: number
269 endclass
270 END
271 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
272
273 # Missing ":var" in a "var" member variable declaration (with initialization)
274 lines =<< trim END
275 vim9script
276 class Something
277 var: number = 42
278 endclass
279 END
280 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
281
282 # Missing ":var" in a "var" member variable declaration (type inferred)
283 lines =<< trim END
284 vim9script
285 class Something
286 var = 42
287 endclass
288 END
289 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
290
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200291 # Test for unsupported comment specifier
292 lines =<< trim END
293 vim9script
294 class Something
295 # comment
296 #{
297 endclass
298 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200299 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200300
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200301 # Test for using class as a bool
302 lines =<< trim END
303 vim9script
304 class A
305 endclass
306 if A
307 endif
308 END
Ernie Raele75fde62023-12-21 17:18:54 +0100309 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200310
311 # Test for using object as a bool
312 lines =<< trim END
313 vim9script
314 class A
315 endclass
316 var a = A.new()
317 if a
318 endif
319 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200320 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200321
322 # Test for using class as a float
323 lines =<< trim END
324 vim9script
325 class A
326 endclass
327 sort([1.1, A], 'f')
328 END
Ernie Raelfa831102023-12-14 20:06:39 +0100329 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200330
331 # Test for using object as a float
332 lines =<< trim END
333 vim9script
334 class A
335 endclass
336 var a = A.new()
337 sort([1.1, a], 'f')
338 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200339 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200340
341 # Test for using class as a string
342 lines =<< trim END
343 vim9script
344 class A
345 endclass
346 :exe 'call ' .. A
347 END
Ernie Raele75fde62023-12-21 17:18:54 +0100348 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200349
350 # Test for using object as a string
351 lines =<< trim END
352 vim9script
353 class A
354 endclass
355 var a = A.new()
356 :exe 'call ' .. a
357 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200358 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200359
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200360 # Test creating a class with member variables and methods, calling a object
361 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000364
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200365 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100366 var lnum: number
367 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200369 # make a nicely formatted string
370 def ToString(): string
371 return $'({this.lnum}, {this.col})'
372 enddef
373 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000374
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200375 # use the automatically generated new() method
376 var pos = TextPosition.new(2, 12)
377 assert_equal(2, pos.lnum)
378 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200380 # call an object method
381 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200383 assert_equal(v:t_class, type(TextPosition))
384 assert_equal(v:t_object, type(pos))
385 assert_equal('class<TextPosition>', typename(TextPosition))
386 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000387 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200388 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200389
390 # When referencing object methods, space cannot be used after a "."
391 lines =<< trim END
392 vim9script
393 class A
394 def Foo(): number
395 return 10
396 enddef
397 endclass
398 var a = A.new()
399 var v = a. Foo()
400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200402
403 # Using an object without specifying a method or a member variable
404 lines =<< trim END
405 vim9script
406 class A
407 def Foo(): number
408 return 10
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200415
416 # Error when parsing the arguments of an object method.
417 lines =<< trim END
418 vim9script
419 class A
420 def Foo()
421 enddef
422 endclass
423 var a = A.new()
424 var v = a.Foo(,)
425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200426 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200427
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200428 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200429 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200430 vim9script
431 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100432 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200433 X: 1
434 }
435 endclass
436 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200438 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000439enddef
440
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200441" Tests for object/class methods in a class
442def Test_class_def_method()
443 # Using the "public" keyword when defining an object method
444 var lines =<< trim END
445 vim9script
446 class A
447 public def Foo()
448 enddef
449 endclass
450 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200451 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452
453 # Using the "public" keyword when defining a class method
454 lines =<< trim END
455 vim9script
456 class A
457 public static def Foo()
458 enddef
459 endclass
460 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200461 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462
Ernie Rael03042a22023-11-11 08:53:32 +0100463 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200464 lines =<< trim END
465 vim9script
466 class A
467 public def _Foo()
468 enddef
469 endclass
470 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200471 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200472
Ernie Rael03042a22023-11-11 08:53:32 +0100473 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200474 lines =<< trim END
475 vim9script
476 class A
477 public static def _Foo()
478 enddef
479 endclass
480 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200481 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200482
483 # Using a "def" keyword without an object method name
484 lines =<< trim END
485 vim9script
486 class A
487 def
488 enddef
489 endclass
490 END
491 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
492
493 # Using a "def" keyword without a class method name
494 lines =<< trim END
495 vim9script
496 class A
497 static def
498 enddef
499 endclass
500 END
501 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
502enddef
503
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000504def Test_class_defined_twice()
505 # class defined twice should fail
506 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200507 vim9script
508 class There
509 endclass
510 class There
511 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200513 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000514
515 # one class, reload same script twice is OK
516 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
518 class There
519 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000520 END
521 writefile(lines, 'XclassTwice.vim', 'D')
522 source XclassTwice.vim
523 source XclassTwice.vim
524enddef
525
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000526def Test_returning_null_object()
527 # this was causing an internal error
528 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200529 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000530
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200531 class BufferList
532 def Current(): any
533 return null_object
534 enddef
535 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000536
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200537 var buffers = BufferList.new()
538 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000539 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200540 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000541enddef
542
Bram Moolenaard13dd302023-03-11 20:56:35 +0000543def Test_using_null_class()
544 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200547 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200548
549 # Test for using a null class as a value
550 lines =<< trim END
551 vim9script
552 echo empty(null_class)
553 END
554 v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
555
556 # Test for using a null class with string()
557 lines =<< trim END
558 vim9script
559 assert_equal('class [unknown]', string(null_class))
560 END
561 v9.CheckSourceSuccess(lines)
562
Yegappan Lakshmananda9d3452024-05-02 13:02:36 +0200563 # Test for using a null class with type() and typename()
Yegappan Lakshmananb2e42b92024-05-01 11:44:17 +0200564 lines =<< trim END
565 vim9script
566 assert_equal(12, type(null_class))
567 assert_equal('class<Unknown>', typename(null_class))
568 END
569 v9.CheckSourceSuccess(lines)
570enddef
571
Bram Moolenaar657aea72023-01-27 13:16:19 +0000572def Test_class_interface_wrong_end()
573 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200574 vim9script
575 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200579 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000580
581 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200582 vim9script
583 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100584 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200585 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000586 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200587 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000588enddef
589
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000590def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000592 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 var state: State
600 var db = {'xyz': 789}
601 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200603 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000604
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200605 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000608
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200609 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100610 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200611 def Method1()
612 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000613 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 endclass
615
616 var obj: Class
617 def Func()
618 obj.Method1()
619 enddef
620 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000621 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200622 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000623
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200624 # Pass an uninitialized object variable to a "new" function and try to call an
625 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200627 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100630 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200631 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000632
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200633 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100634 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200636 def GetBackground(): string
637 return this._bg.background
638 enddef
639 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000640
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200641 var bg: Background # UNINITIALIZED
642 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200644 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000645
646 # TODO: this should not give an error but be handled at runtime
647 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200648 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200650 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100651 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200652 def Method1()
653 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000654 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200655 endclass
656
657 var obj = null_object
658 def Func()
659 obj.Method1()
660 enddef
661 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200663 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Ernie Raelbe828252024-07-26 18:37:02 +0200664
665 # Reference a object variable through a null class object which is stored in a
666 # variable of type "any".
667 lines =<< trim END
668 vim9script
669
670 def Z()
671 var o: any = null_object
672 o.v = 4
673 enddef
674 Z()
675 END
676 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
677
678 # Do "echom" of a null object variable.
679 lines =<< trim END
680 vim9script
681
682 def X()
683 var x = null_object
684 echom x
685 enddef
686 X()
687 END
688 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 2)
Ernie Rael94082b62024-07-26 19:40:29 +0200689
690 # Use a null object variable that vim wants to force to number.
691 lines =<< trim END
692 vim9script
693
694 def X()
695 var o = null_object
696 var l = [ 1, o]
697 sort(l, 'N')
698 enddef
699 X()
700 END
701 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 3)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000702enddef
703
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200704" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200705def Test_null_object_assign_compare()
706 var lines =<< trim END
707 vim9script
708
709 var nullo = null_object
710 def F(): any
711 return nullo
712 enddef
713 assert_equal('object<Unknown>', typename(F()))
714
715 var o0 = F()
716 assert_true(o0 == null_object)
717 assert_true(o0 == null)
718
719 var o1: any = nullo
720 assert_true(o1 == null_object)
721 assert_true(o1 == null)
722
723 def G()
724 var x = null_object
725 enddef
726
727 class C
728 endclass
729 var o2: C
730 assert_true(o2 == null_object)
731 assert_true(o2 == null)
732
733 o2 = null_object
734 assert_true(o2 == null)
735
736 o2 = C.new()
737 assert_true(o2 != null)
738
739 o2 = null_object
740 assert_true(o2 == null)
741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200742 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200743enddef
744
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200745" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000746def Test_class_member_initializer()
747 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200748 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200750 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100751 var lnum: number = 1
752 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200754 # constructor with only the line number
755 def new(lnum: number)
756 this.lnum = lnum
757 enddef
758 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200760 var pos = TextPosition.new(3)
761 assert_equal(3, pos.lnum)
762 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000763
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200764 var instr = execute('disassemble TextPosition.new')
765 assert_match('new\_s*' ..
766 '0 NEW TextPosition size \d\+\_s*' ..
767 '\d PUSHNR 1\_s*' ..
768 '\d STORE_THIS 0\_s*' ..
769 '\d PUSHNR 1\_s*' ..
770 '\d STORE_THIS 1\_s*' ..
771 'this.lnum = lnum\_s*' ..
772 '\d LOAD arg\[-1]\_s*' ..
773 '\d PUSHNR 0\_s*' ..
774 '\d LOAD $0\_s*' ..
775 '\d\+ STOREINDEX object\_s*' ..
776 '\d\+ RETURN object.*',
777 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000778 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200779 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000780enddef
781
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000782def Test_member_any_used_as_object()
783 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200784 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200786 class Inner
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +0100787 public var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100791 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200792 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def F(outer: Outer)
795 outer.inner.value = 1
796 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200798 var inner_obj = Inner.new(0)
799 var outer_obj = Outer.new(inner_obj)
800 F(outer_obj)
801 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000802 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200803 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000804
Ernie Rael03042a22023-11-11 08:53:32 +0100805 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200806 lines =<< trim END
807 vim9script
808
809 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100810 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200811 endclass
812
813 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100814 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200815 endclass
816
817 def F(outer: Outer)
818 outer.inner._value = 'b'
819 enddef
820
821 var inner_obj = Inner.new('a')
822 var outer_obj = Outer.new(inner_obj)
823 F(outer_obj)
824 END
Ernie Rael03042a22023-11-11 08:53:32 +0100825 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200826
827 # Try modifying a non-existing variable using an "any" object
828 lines =<< trim END
829 vim9script
830
831 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100832 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200833 endclass
834
835 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100836 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200837 endclass
838
839 def F(outer: Outer)
840 outer.inner.someval = 'b'
841 enddef
842
843 var inner_obj = Inner.new('a')
844 var outer_obj = Outer.new(inner_obj)
845 F(outer_obj)
846 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200847 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000848enddef
849
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200850" Nested assignment to a object variable which is of another class type
851def Test_assignment_nested_type()
852 var lines =<< trim END
853 vim9script
854
855 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100856 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200857 endclass
858
859 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100860 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200861 endclass
862
863 def F(outer: Outer)
864 outer.inner.value = 1
865 enddef
866
867 def Test_assign_to_nested_typed_member()
868 var inner = Inner.new(0)
869 var outer = Outer.new(inner)
870 F(outer)
871 assert_equal(1, inner.value)
872 enddef
873
874 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200875
876 var script_inner = Inner.new(0)
877 var script_outer = Outer.new(script_inner)
878 script_outer.inner.value = 1
879 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200880 END
881 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200882
883 # Assignment where target item is read only in :def
884 lines =<< trim END
885 vim9script
886
887 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100888 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200889 endclass
890
891 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100892 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200893 endclass
894
895 def F(outer: Outer)
896 outer.inner.value = 1
897 enddef
898
899 def Test_assign_to_nested_typed_member()
900 var inner = Inner.new(0)
901 var outer = Outer.new(inner)
902 F(outer)
903 assert_equal(1, inner.value)
904 enddef
905
906 Test_assign_to_nested_typed_member()
907 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200908 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200909
910 # Assignment where target item is read only script level
911 lines =<< trim END
912 vim9script
913
914 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100915 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200916 endclass
917
918 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100919 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200920 endclass
921
922 def F(outer: Outer)
923 outer.inner.value = 1
924 enddef
925
926 var script_inner = Inner.new(0)
927 var script_outer = Outer.new(script_inner)
928 script_outer.inner.value = 1
929 assert_equal(1, script_inner.value)
930 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200932enddef
933
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000934def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200935 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000936 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100940 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200942 def Add(n: number)
943 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100944 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200945 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200947 var f = Foo.new(3)
948 f.Add(17)
949 assert_equal(20, f.x)
950
951 def AddToFoo(obj: Foo)
952 obj.x += 3
953 enddef
954
955 AddToFoo(f)
956 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000957 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200958 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000959enddef
960
Bram Moolenaarf4508042023-01-15 16:54:57 +0000961def Test_list_of_objects()
962 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200963 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000964
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200965 class Foo
966 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000967 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200968 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000969
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200970 def ProcessList(fooList: list<Foo>)
971 for foo in fooList
972 foo.Add()
973 endfor
974 enddef
975
976 var l: list<Foo> = [Foo.new()]
977 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000978 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200979 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000980enddef
981
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000982def Test_expr_after_using_object()
983 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200984 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200986 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100987 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200988 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000989
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200990 def Foo(): Something
991 var v = Something.new()
992 echo 'in Foo(): ' .. typename(v)
993 return v
994 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000995
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200996 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000997 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200998 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000999enddef
1000
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001001def Test_class_default_new()
1002 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001004
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001005 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001006 var lnum: number = 1
1007 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var pos = TextPosition.new()
1011 assert_equal(1, pos.lnum)
1012 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 pos = TextPosition.new(v:none, v:none)
1015 assert_equal(1, pos.lnum)
1016 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001017
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001018 pos = TextPosition.new(3, 22)
1019 assert_equal(3, pos.lnum)
1020 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 pos = TextPosition.new(v:none, 33)
1023 assert_equal(1, pos.lnum)
1024 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001027
1028 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001029 vim9script
1030 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001031 var name: string
1032 var age: number = 42
1033 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001034
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001035 def new(this.name, this.age = v:none, this.education = v:none)
1036 enddef
1037 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001038
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001039 var piet = Person.new("Piet")
1040 assert_equal("Piet", piet.name)
1041 assert_equal(42, piet.age)
1042 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 var chris = Person.new("Chris", 4, "none")
1045 assert_equal("Chris", chris.name)
1046 assert_equal(4, chris.age)
1047 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001049 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001050
1051 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001052 vim9script
1053 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +01001054 var name: string
1055 var age: number = 42
1056 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +00001057
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 def new(this.name, this.age = v:none, this.education = v:none)
1059 enddef
1060 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +00001063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001064 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001065
1066 # Using a specific value to initialize an instance variable in the new()
1067 # method.
1068 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 vim9script
1070 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001071 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001072 def new(this.val = 'a')
1073 enddef
1074 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001075 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001076 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001077enddef
1078
h-east2261c892023-08-16 21:49:54 +09001079def Test_class_new_with_object_member()
1080 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001081 vim9script
h-east2261c892023-08-16 21:49:54 +09001082
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001083 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001084 var str: string
1085 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001086 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001087 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001088 def newVals(this.str, this.num)
1089 enddef
1090 endclass
h-east2261c892023-08-16 21:49:54 +09001091
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001092 def Check()
1093 try
1094 var c = C.new('cats', 2)
1095 assert_equal('cats', c.str)
1096 assert_equal(2, c.num)
1097
1098 c = C.newVals('dogs', 4)
1099 assert_equal('dogs', c.str)
1100 assert_equal(4, c.num)
1101 catch
1102 assert_report($'Unexpected exception was caught: {v:exception}')
1103 endtry
1104 enddef
1105
1106 Check()
h-east2261c892023-08-16 21:49:54 +09001107 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001108 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001109
1110 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001111 vim9script
1112
1113 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001114 var str: string
1115 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001116 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001117 enddef
1118 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001119
1120 def Check()
1121 try
1122 var c = C.new(1, 2)
1123 catch
1124 assert_report($'Unexpected exception was caught: {v:exception}')
1125 endtry
1126 enddef
1127
1128 Check()
h-eastdb385522023-09-28 22:18:19 +02001129 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001130 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001131
1132 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001134
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001135 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001136 var str: string
1137 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001138 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001139 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001140 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001141
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001142 def Check()
1143 try
1144 var c = C.newVals('dogs', 'apes')
1145 catch
1146 assert_report($'Unexpected exception was caught: {v:exception}')
1147 endtry
1148 enddef
1149
1150 Check()
1151 END
1152 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1153
1154 lines =<< trim END
1155 vim9script
1156
1157 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001158 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001159 def new(str: any)
1160 enddef
1161 endclass
1162
1163 def Check()
1164 try
1165 var c = C.new(1)
1166 catch
1167 assert_report($'Unexpected exception was caught: {v:exception}')
1168 endtry
1169 enddef
1170
1171 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001172 END
1173 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001174
1175 # Try using "this." argument in a class method
1176 lines =<< trim END
1177 vim9script
1178 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001179 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001180 static def Foo(this.val: number)
1181 enddef
1182 endclass
1183 END
1184 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1185
1186 # Try using "this." argument in an object method
1187 lines =<< trim END
1188 vim9script
1189 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001190 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001191 def Foo(this.val: number)
1192 enddef
1193 endclass
1194 END
1195 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001196enddef
1197
Bram Moolenaar74e12742022-12-13 21:14:28 +00001198def Test_class_object_member_inits()
1199 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 vim9script
1201 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001202 var lnum: number
1203 var col = 1
1204 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001205 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001206
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001207 var pos = TextPosition.new()
1208 assert_equal(0, pos.lnum)
1209 assert_equal(1, pos.col)
1210 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001212 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001213
1214 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 vim9script
1216 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001217 var lnum
1218 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001219 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001220 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001221 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001222
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001223 # If the type is not specified for a member, then it should be set during
1224 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001225 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001227
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001228 var init_count = 0
1229 def Init(): string
1230 init_count += 1
1231 return 'foo'
1232 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001234 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001235 var str1 = Init()
1236 var str2: string = Init()
1237 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001238 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001240 assert_equal(init_count, 0)
1241 var a = A.new()
1242 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001243 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001244 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001245
1246 # Test for initializing an object member with an unknown variable/type
1247 lines =<< trim END
1248 vim9script
1249 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001250 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001251 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001252 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001253 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001254 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001255
1256 # Test for initializing an object member with an special type
1257 lines =<< trim END
1258 vim9script
1259 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001260 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001261 endclass
1262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001263 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001264enddef
1265
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001266" Test for instance variable access
1267def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001268 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 vim9script
1270 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001271 var _one = 1
1272 var two = 2
1273 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001274
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001275 def GetOne(): number
1276 return this._one
1277 enddef
1278 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001279
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001280 var trip = Triple.new()
1281 assert_equal(1, trip.GetOne())
1282 assert_equal(2, trip.two)
1283 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001284 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001285
Ernie Rael03042a22023-11-11 08:53:32 +01001286 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001287 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1288 trip.three = 33
1289 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001290
Ernie Raeld4802ec2023-10-20 11:59:00 +02001291 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001293 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001294
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001295 # Test for a public member variable name beginning with an underscore
1296 lines =<< trim END
1297 vim9script
1298 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001299 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001300 endclass
1301 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001302 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001303
Bram Moolenaar590162c2022-12-24 21:24:06 +00001304 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001305 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001306
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001307 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001308 var make: string
1309 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001310
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001311 def new(make_arg: string)
1312 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001313 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001314
1315 def GetMake(): string
1316 return $"make = {this.make}"
1317 enddef
1318 def GetAge(): number
1319 return this.age
1320 enddef
1321 endclass
1322
1323 var c = MyCar.new("abc")
1324 assert_equal('make = abc', c.GetMake())
1325
1326 c = MyCar.new("def")
1327 assert_equal('make = def', c.GetMake())
1328
1329 var c2 = MyCar.new("123")
1330 assert_equal('make = 123', c2.GetMake())
1331
1332 def CheckCar()
1333 assert_equal("make = def", c.GetMake())
1334 assert_equal(5, c.GetAge())
1335 enddef
1336 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001338 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001339
1340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001341 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001343 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001344 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001345
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001346 def new(make_arg: string)
1347 this.make = make_arg
1348 enddef
1349 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001350
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001351 var c = MyCar.new("abc")
1352 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001353 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001354 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001355
1356 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001357 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001360 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001361
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001362 def Add(n: number): any
1363 this.x->add(n)
1364 return this
1365 enddef
1366 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001367
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001368 echo Foo.new().Add(1).Add(2).x
1369 echo Foo.new().Add(1).Add(2)
1370 .x
1371 echo Foo.new().Add(1)
1372 .Add(2).x
1373 echo Foo.new()
1374 .Add(1).Add(2).x
1375 echo Foo.new()
1376 .Add(1)
1377 .Add(2)
1378 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001379 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001380 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001381
1382 # Test for "public" cannot be abbreviated
1383 lines =<< trim END
1384 vim9script
1385 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001386 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001387 endclass
1388 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001389 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001390
Doug Kearns74da0ee2023-12-14 20:26:26 +01001391 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001392 lines =<< trim END
1393 vim9script
1394 class Something
1395 public val = 1
1396 endclass
1397 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001398 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001399
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001400 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001401 lines =<< trim END
1402 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001403 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001404 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001405 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001407 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001408 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001409
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001410 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001411 lines =<< trim END
1412 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001413 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001414 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001415 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001416 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001417 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001418 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001419
1420 # Modify a instance variable using the class name in a def function
1421 lines =<< trim END
1422 vim9script
1423 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001424 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001425 endclass
1426 def T()
1427 A.val = 1
1428 enddef
1429 T()
1430 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001431 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432
1433 # Read a instance variable using the class name in a def function
1434 lines =<< trim END
1435 vim9script
1436 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001437 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438 endclass
1439 def T()
1440 var i = A.val
1441 enddef
1442 T()
1443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001445
1446 # Access from child class extending a class:
1447 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001448 vim9script
1449 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001450 var ro_obj_var = 10
1451 public var rw_obj_var = 20
1452 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001453 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001454
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001455 class B extends A
1456 def Foo()
1457 var x: number
1458 x = this.ro_obj_var
1459 this.ro_obj_var = 0
1460 x = this.rw_obj_var
1461 this.rw_obj_var = 0
1462 x = this._priv_obj_var
1463 this._priv_obj_var = 0
1464 enddef
1465 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001467 var b = B.new()
1468 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001469 END
1470 v9.CheckSourceSuccess(lines)
1471enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001472
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001473" Test for class variable access
1474def Test_class_variable_access()
1475 # Test for "static" cannot be abbreviated
1476 var lines =<< trim END
1477 vim9script
1478 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001479 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001480 endclass
1481 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001482 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001483
1484 # Test for "static" cannot be followed by "public".
1485 lines =<< trim END
1486 vim9script
1487 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001488 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001489 endclass
1490 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001491 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492
1493 # A readonly class variable cannot be modified from a child class
1494 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001495 vim9script
1496 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001497 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001500 class B extends A
1501 def Foo()
1502 A.ro_class_var = 50
1503 enddef
1504 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001505
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001506 var b = B.new()
1507 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001509 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001510
Ernie Rael03042a22023-11-11 08:53:32 +01001511 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001512 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 vim9script
1514 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001515 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001516 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001517
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001518 class B extends A
1519 def Foo()
1520 var i = A._priv_class_var
1521 enddef
1522 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001523
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001524 var b = B.new()
1525 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 END
Ernie Rael03042a22023-11-11 08:53:32 +01001527 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001528
Ernie Rael03042a22023-11-11 08:53:32 +01001529 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001530 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001531 vim9script
1532 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001533 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001534 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001536 class B extends A
1537 def Foo()
1538 A._priv_class_var = 0
1539 enddef
1540 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 var b = B.new()
1543 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001544 END
Ernie Rael03042a22023-11-11 08:53:32 +01001545 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001546
1547 # Access from child class extending a class and from script context
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
1550 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001551 static var ro_class_var = 10
1552 public static var rw_class_var = 20
1553 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001555
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001556 class B extends A
1557 def Foo()
1558 var x: number
1559 x = A.ro_class_var
1560 assert_equal(10, x)
1561 x = A.rw_class_var
1562 assert_equal(25, x)
1563 A.rw_class_var = 20
1564 assert_equal(20, A.rw_class_var)
1565 enddef
1566 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 assert_equal(10, A.ro_class_var)
1569 assert_equal(20, A.rw_class_var)
1570 A.rw_class_var = 25
1571 assert_equal(25, A.rw_class_var)
1572 var b = B.new()
1573 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001574 END
1575 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001576enddef
1577
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001578def Test_class_object_compare()
1579 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001580 vim9script
1581 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001582 var nr = 0
1583 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001585 END
1586
1587 # used at the script level and in a compiled function
1588 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 var i1 = Item.new()
1590 assert_equal(i1, i1)
1591 assert_true(i1 is i1)
1592 var i2 = Item.new()
1593 assert_equal(i1, i2)
1594 assert_false(i1 is i2)
1595 var i3 = Item.new(0, 'xx')
1596 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var io1 = Item.new(1, 'xx')
1599 assert_notequal(i1, io1)
1600 var io2 = Item.new(0, 'yy')
1601 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001602 END
1603
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001604 v9.CheckSourceSuccess(class_lines + test_lines)
1605 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001607
1608 for op in ['>', '>=', '<', '<=', '=~', '!~']
1609 var op_lines = [
1610 'var i1 = Item.new()',
1611 'var i2 = Item.new()',
1612 'echo i1 ' .. op .. ' i2',
1613 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001615 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001616 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001617 endfor
1618enddef
1619
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001620def Test_object_type()
1621 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001622 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001623
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001624 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001625 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001626 endclass
1627 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001628 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001629 endclass
1630 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001631 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001632 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001633
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 var o: One = One.new()
1635 var t: Two = Two.new()
1636 var m: TwoMore = TwoMore.new()
1637 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001638
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001640 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001641 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001642
1643 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001644 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001645
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001646 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001647 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001648 endclass
1649 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001650 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001651 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001654 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001655 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001656
1657 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001659
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001660 interface One
1661 def GetMember(): number
1662 endinterface
1663 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001664 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001665 def GetMember(): number
1666 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001667 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001670 var o: One = Two.new(5)
1671 assert_equal(5, o.GetMember())
1672 END
1673 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001674
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001675 lines =<< trim END
1676 vim9script
1677
1678 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001679 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001680 endclass
1681
1682 def Ref(name: string): func(Num): Num
1683 return (arg: Num): Num => {
1684 return eval(name)(arg)
1685 }
1686 enddef
1687
1688 const Fn = Ref('Double')
1689 var Double = (m: Num): Num => Num.new(m.n * 2)
1690
1691 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001692 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001693 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001694enddef
1695
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001696def Test_class_member()
1697 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001698 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001699 vim9script
1700 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001701 var lnum = 1
1702 var col = 1
1703 static var counter = 0
1704 static var _secret = 7
1705 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001706
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001707 static def AddToCounter(nr: number)
1708 counter += nr
1709 enddef
1710 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001712 assert_equal(0, TextPos.counter)
1713 TextPos.AddToCounter(3)
1714 assert_equal(3, TextPos.counter)
1715 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001716
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001717 def GetCounter(): number
1718 return TextPos.counter
1719 enddef
1720 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001722 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1723 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1724 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001725
Ernie Rael03042a22023-11-11 08:53:32 +01001726 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1727 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001728
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001729 assert_equal(42, TextPos.anybody)
1730 TextPos.anybody = 12
1731 assert_equal(12, TextPos.anybody)
1732 TextPos.anybody += 5
1733 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001734 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001735 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001736
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001737 # example in the help
1738 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001739 vim9script
1740 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001741 var size: number
1742 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001743
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 def new(this.size)
1745 totalSize += this.size
1746 enddef
1747 endclass
1748 assert_equal(0, OtherThing.totalSize)
1749 var to3 = OtherThing.new(3)
1750 assert_equal(3, OtherThing.totalSize)
1751 var to7 = OtherThing.new(7)
1752 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001753 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001754 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001755
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001756 # using static class member twice
1757 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001761 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 static def MacroSubstitute(s: string): string
1764 return substitute(s, '{{author}}', author, 'gi')
1765 enddef
1766 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001767
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001768 assert_equal('some text', HTML.MacroSubstitute('some text'))
1769 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001770 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001771 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001772
Ernie Rael03042a22023-11-11 08:53:32 +01001773 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001774 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001775 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001776
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001777 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001778 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001779
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 def Add(n: number): number
1781 const F = (): number => this._x + n
1782 return F()
1783 enddef
1784 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001785
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001786 var foo = Foo.new()
1787 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001789 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001790
Ernie Rael03042a22023-11-11 08:53:32 +01001791 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001792 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001793 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001794
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001795 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001796 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001797
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001798 def Add(n: number): number
1799 var Lam = () => {
1800 this._x = this._x + n
1801 }
1802 Lam()
1803 return this._x
1804 enddef
1805 endclass
h-east2bd6a092023-05-19 19:01:17 +01001806
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001807 var foo = Foo.new()
1808 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001809 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001810 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001811
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001812 # check shadowing
1813 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001814 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001815
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001816 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001817 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001818 def Method(count: number)
1819 echo count
1820 enddef
1821 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001822
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001823 var s = Some.new()
1824 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001825 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001826 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001827
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001828 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001829 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001830 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001831
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001832 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001833 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 def Method(arg: number)
1835 var count = 3
1836 echo arg count
1837 enddef
1838 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001839
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001840 var s = Some.new()
1841 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001842 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001843 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001844
1845 # Test for using an invalid type for a member variable
1846 lines =<< trim END
1847 vim9script
1848 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001849 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001850 endclass
1851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001852 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001853
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001854 # Test for setting a member on a null object
1855 lines =<< trim END
1856 vim9script
1857 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001858 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001859 endclass
1860
1861 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001862 var obj: A
1863 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001864 enddef
1865 F()
1866 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001867 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001868
1869 # Test for accessing a member on a null object
1870 lines =<< trim END
1871 vim9script
1872 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001873 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001874 endclass
1875
1876 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001877 var obj: A
1878 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001879 enddef
1880 F()
1881 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001882 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001883
1884 # Test for setting a member on a null object, at script level
1885 lines =<< trim END
1886 vim9script
1887 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001888 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001889 endclass
1890
1891 var obj: A
1892 obj.val = ""
1893 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001894 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001895
1896 # Test for accessing a member on a null object, at script level
1897 lines =<< trim END
1898 vim9script
1899 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001900 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001901 endclass
1902
1903 var obj: A
1904 echo obj.val
1905 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001906 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001907
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001908 # Test for no space before or after the '=' when initializing a member
1909 # variable
1910 lines =<< trim END
1911 vim9script
1912 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001913 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001914 endclass
1915 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001916 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001917 lines =<< trim END
1918 vim9script
1919 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001920 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001921 endclass
1922 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001923 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001924
1925 # Access a non-existing member
1926 lines =<< trim END
1927 vim9script
1928 class A
1929 endclass
1930 var a = A.new()
1931 var v = a.bar
1932 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001933 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001934enddef
1935
Ernie Raele6c9aa52023-10-06 19:55:52 +02001936" These messages should show the defining class of the variable (base class),
1937" not the class that did the reference (super class)
1938def Test_defining_class_message()
1939 var lines =<< trim END
1940 vim9script
1941
1942 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001943 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001944 endclass
1945
1946 class Child extends Base
1947 endclass
1948
1949 var o = Child.new()
1950 var x = o._v1
1951 END
Ernie Rael03042a22023-11-11 08:53:32 +01001952 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001953 lines =<< trim END
1954 vim9script
1955
1956 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001957 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001958 endclass
1959
1960 class Child extends Base
1961 endclass
1962
1963 def F()
1964 var o = Child.new()
1965 var x = o._v1
1966 enddef
1967 F()
1968 END
Ernie Rael03042a22023-11-11 08:53:32 +01001969 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001970 lines =<< trim END
1971 vim9script
1972
1973 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001974 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001975 endclass
1976
1977 class Child extends Base
1978 endclass
1979
1980 var o = Child.new()
1981 o.v1 = []
1982 END
1983 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1984 lines =<< trim END
1985 vim9script
1986
1987 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001988 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001989 endclass
1990
1991 class Child extends Base
1992 endclass
1993
1994 def F()
1995 var o = Child.new()
1996 o.v1 = []
1997 enddef
1998 F()
1999 END
2000
Ernie Rael03042a22023-11-11 08:53:32 +01002001 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02002002 # of the class hierarchy.
2003 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
2004 lines =<< trim END
2005 vim9script
2006
2007 class Base0
2008 endclass
2009
2010 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01002011 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002012 endclass
2013
2014 class Child extends Base
2015 endclass
2016
2017 def F()
2018 var o = Child.new()
2019 var x = o._v1
2020 enddef
2021 F()
2022 END
Ernie Rael03042a22023-11-11 08:53:32 +01002023 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002024
Ernie Rael03042a22023-11-11 08:53:32 +01002025 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02002026 # of the class hierarchy.
2027 lines =<< trim END
2028 vim9script
2029
2030 class Base0
2031 endclass
2032
2033 class Base extends Base0
2034 endclass
2035
2036 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002037 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02002038 endclass
2039
2040 def F()
2041 var o = Child.new()
2042 var x = o._v1
2043 enddef
2044 F()
2045 END
Ernie Rael03042a22023-11-11 08:53:32 +01002046 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02002047enddef
2048
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002049func Test_class_garbagecollect()
2050 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002051 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002053 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002054 var p = [2, 3]
2055 static var pl = ['a', 'b']
2056 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002057 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002058
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002059 echo Point.pl Point.pd
2060 call test_garbagecollect_now()
2061 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002062 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002063 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002064
2065 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002066 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002067
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002068 interface View
2069 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002070
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002071 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002072 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002074
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002075 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002076 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002077
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002078 def new()
2079 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002080 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002081 enddef
2082 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002084 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002085
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002086 # overwrite "view", will be garbage-collected next
2087 view = MyView.new()
2088 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002089 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002090 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002091endfunc
2092
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002093" Test interface garbage collection
2094func Test_interface_garbagecollect()
2095 let lines =<< trim END
2096 vim9script
2097
2098 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002099 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002100
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002101 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002102 endinterface
2103
2104 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002105 static var ro_class_var: number = 10
2106 public static var rw_class_var: number = 20
2107 static var _priv_class_var: number = 30
2108 var ro_obj_var: number = 40
2109 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002110
2111 static def _ClassBar(): number
2112 return _priv_class_var
2113 enddef
2114
2115 static def ClassFoo(): number
2116 return ro_class_var + rw_class_var + A._ClassBar()
2117 enddef
2118
2119 def _ObjBar(): number
2120 return this._priv_obj_var
2121 enddef
2122
2123 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002124 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002125 enddef
2126 endclass
2127
2128 assert_equal(60, A.ClassFoo())
2129 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002130 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002131 test_garbagecollect_now()
2132 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002133 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002134 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002135 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002136endfunc
2137
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002138def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002139 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002140 vim9script
2141 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002142 var value = 0
2143 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002144
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002145 def new(v: number)
2146 this.value = v
2147 ++objects
2148 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 static def GetCount(): number
2151 return objects
2152 enddef
2153 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002155 assert_equal(0, Value.GetCount())
2156 var v1 = Value.new(2)
2157 assert_equal(1, Value.GetCount())
2158 var v2 = Value.new(7)
2159 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002161 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002162
2163 # Test for cleaning up after a class definition failure when using class
2164 # functions.
2165 lines =<< trim END
2166 vim9script
2167 class A
2168 static def Foo()
2169 enddef
2170 aaa
2171 endclass
2172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002173 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002174
2175 # Test for calling a class method from another class method without the class
2176 # name prefix.
2177 lines =<< trim END
2178 vim9script
2179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002180 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002181 static def Foo(n: number)
2182 myList->add(n)
2183 enddef
2184 static def Bar()
2185 Foo(2)
2186 enddef
2187 def Baz()
2188 Foo(3)
2189 enddef
2190 endclass
2191 A.Bar()
2192 var a = A.new()
2193 a.Baz()
2194 assert_equal([1, 2, 3], A.myList)
2195 END
2196 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002197enddef
2198
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002199def Test_class_defcompile()
2200 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 class C
2204 def Fo(i: number): string
2205 return i
2206 enddef
2207 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002210 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002212
2213 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002214 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002215
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 class C
2217 static def Fc(): number
2218 return 'x'
2219 enddef
2220 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002221
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002224 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002225
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002227 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002229 class C
2230 static def new()
2231 enddef
2232 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002233
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002234 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002235 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002236 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002237
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002238 # Trying to compile a function using a non-existing class variable
2239 lines =<< trim END
2240 vim9script
2241 defcompile x.Foo()
2242 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002244
2245 # Trying to compile a function using a variable which is not a class
2246 lines =<< trim END
2247 vim9script
2248 var x: number
2249 defcompile x.Foo()
2250 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002252
2253 # Trying to compile a function without specifying the name
2254 lines =<< trim END
2255 vim9script
2256 class A
2257 endclass
2258 defcompile A.
2259 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002260 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002261
2262 # Trying to compile a non-existing class object member function
2263 lines =<< trim END
2264 vim9script
2265 class A
2266 endclass
2267 var a = A.new()
2268 defcompile a.Foo()
2269 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002270 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002271enddef
2272
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002273def Test_class_object_to_string()
2274 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002275 vim9script
2276 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002277 var lnum = 1
2278 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002279 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002280
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002282
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002283 var pos = TextPosition.new()
2284 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002286 v9.CheckSourceSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +02002287
2288 # check string() with object nesting
2289 lines =<< trim END
2290 vim9script
2291 class C
2292 var nest1: C
2293 var nest2: C
2294 def Init(n1: C, n2: C)
2295 this.nest1 = n1
2296 this.nest2 = n2
2297 enddef
2298 endclass
2299
2300 var o1 = C.new()
2301 var o2 = C.new()
2302 o1.Init(o1, o2)
2303 o2.Init(o2, o1)
2304
2305 # The following previously put's vim into an infinite loop.
2306
2307 var expect = "object of C {nest1: object of C {...}, nest2: object of C {nest1: object of C {...}, nest2: object of C {...}}}"
2308 assert_equal(expect, string(o1))
2309 END
2310 v9.CheckSourceSuccess(lines)
2311
2312 lines =<< trim END
2313 vim9script
2314
2315 class B
2316 endclass
2317
2318 class C
2319 var b: B
2320 var c: C
2321 endclass
2322
2323 var o1 = C.new(B.new(), C.new(B.new()))
2324 var expect = "object of C {b: object of B {}, c: object of C {b: object of B {}, c: object of [unknown]}}"
2325 assert_equal(expect, string(o1))
2326 END
2327 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002328enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002329
Bram Moolenaar554d0312023-01-05 19:59:18 +00002330def Test_interface_basics()
2331 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 vim9script
2333 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002334 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002335 def GetCount(): number
2336 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002337 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002338 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002339
2340 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002341 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002342 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002344 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002345 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002346
2347 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002348 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002351 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 def Method(value: number)
2353 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002354 END
h-east61378a12023-04-18 19:07:29 +01002355 # The argument name and the object member name are the same, but this is not a
2356 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002357 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002358
2359 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002360 vim9script
2361 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002362 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002363 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002364 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002365 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002366
2367 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002368 vim9script
2369 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002370 var value: string
2371 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 def GetCount(): number
2373 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002375 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002376
2377 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 vim9script
2379 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002380 var value: string
2381 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 def GetCount(): number
2383 return 5
2384 enddef
2385 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002388
h-eastaa979c72025-01-03 10:19:45 +01002389 # Test for "interface" cannot be abbreviated
2390 lines =<< trim END
2391 vim9script
2392 inte Something
2393 endinterface
2394 END
2395 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: inte Something', 2)
2396
2397 # Test for "endinterface" cannot be abbreviated
2398 lines =<< trim END
2399 vim9script
2400 interface Something
2401 endin
2402 END
2403 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endin', 3)
2404
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002405 # Additional commands after "interface name"
2406 lines =<< trim END
2407 vim9script
2408 interface Something | var x = 10 | var y = 20
2409 endinterface
2410 END
2411 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2412
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002413 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002414 vim9script
2415 export interface EnterExit
2416 def Enter(): void
2417 def Exit(): void
2418 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002419 END
2420 writefile(lines, 'XdefIntf.vim', 'D')
2421
2422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002423 vim9script
2424 import './XdefIntf.vim' as defIntf
2425 export def With(ee: defIntf.EnterExit, F: func)
2426 ee.Enter()
2427 try
2428 F()
2429 finally
2430 ee.Exit()
2431 endtry
2432 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002433 END
2434 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002435
2436 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002437 vim9script
2438 export abstract class EnterExit
2439 def Enter(): void
2440 enddef
2441 def Exit(): void
2442 enddef
2443 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002444 END
2445 writefile(imported, 'XdefIntf2.vim', 'D')
2446
2447 lines[1] = " import './XdefIntf2.vim' as defIntf"
2448 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002449enddef
2450
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002451" Test for using string() with an interface
2452def Test_interface_to_string()
2453 var lines =<< trim END
2454 vim9script
2455 interface Intf
2456 def Method(nr: number)
2457 endinterface
2458 assert_equal("interface Intf", string(Intf))
2459 END
2460 v9.CheckSourceSuccess(lines)
2461enddef
2462
Bram Moolenaar94674f22023-01-06 18:42:20 +00002463def Test_class_implements_interface()
2464 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002465 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002466
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002468 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002469 def Method(nr: number)
2470 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002471
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002472 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002473 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002474 def Method(nr: number)
2475 echo nr
2476 enddef
2477 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002478
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002479 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002480 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002481 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002483 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002484 var member = 'abc'
2485 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002486 def Method(nr: number)
2487 echo nr
2488 enddef
2489 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002490 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002491 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002492
2493 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002494 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002495
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002496 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002497 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002498 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002499
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002500 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002501 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002502 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002503 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002505
2506 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002507 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002508
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002509 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002510 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002511 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002513 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002514 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002515 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002517 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002518
2519 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002522 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002523 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002524 def Method(nr: number)
2525 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002526
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002527 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002528 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002529 def Method(nr: number)
2530 echo nr
2531 enddef
2532 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002533 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002535
2536 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002537 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002538
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002539 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002540 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002541 def Methods(nr: number)
2542 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002543
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002544 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002545 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002546 def Method(nr: number)
2547 echo nr
2548 enddef
2549 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002551 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002552
2553 # Check different order of members in class and interface works.
2554 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002555 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002556
2557 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002558 var label: string
2559 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002560 endinterface
2561
2562 # order of members is opposite of interface
2563 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002564 public var lnum: number = 5
2565 var errpos: number = 42
2566 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002567 endclass
2568
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 def Test()
2570 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002571
2572 assert_equal('label', result.label)
2573 assert_equal(42, result.errpos)
2574 enddef
2575
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002576 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002577 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002578 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002579
2580 # Interface name after "extends" doesn't end in a space or NUL character
2581 lines =<< trim END
2582 vim9script
2583 interface A
2584 endinterface
2585 class B extends A"
2586 endclass
2587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002589
2590 # Trailing characters after a class name
2591 lines =<< trim END
2592 vim9script
2593 class A bbb
2594 endclass
2595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002596 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002597
2598 # using "implements" with a non-existing class
2599 lines =<< trim END
2600 vim9script
2601 class A implements B
2602 endclass
2603 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002604 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002605
2606 # using "implements" with a regular class
2607 lines =<< trim END
2608 vim9script
2609 class A
2610 endclass
2611 class B implements A
2612 endclass
2613 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002614 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002615
2616 # using "implements" with a variable
2617 lines =<< trim END
2618 vim9script
2619 var T: number = 10
2620 class A implements T
2621 endclass
2622 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002623 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002624
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002625 # implements should be followed by a white space
2626 lines =<< trim END
2627 vim9script
2628 interface A
2629 endinterface
2630 class B implements A;
2631 endclass
2632 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002633 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002634
LemonBoyc5d27442023-08-19 13:02:35 +02002635 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002636 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002637
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002638 interface One
2639 def IsEven(nr: number): bool
2640 endinterface
2641 class Two implements One
2642 def IsEven(nr: number): string
2643 enddef
2644 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002645 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002646 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002647
2648 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002649 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002650
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002651 interface One
2652 def IsEven(nr: number): bool
2653 endinterface
2654 class Two implements One
2655 def IsEven(nr: bool): bool
2656 enddef
2657 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002658 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002659 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002660
2661 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002662 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002663
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002664 interface One
2665 def IsEven(nr: number): bool
2666 endinterface
2667 class Two implements One
2668 def IsEven(nr: number, ...extra: list<number>): bool
2669 enddef
2670 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002671 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002672 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool', 9)
Ernie Raelcf138d42023-09-06 20:45:03 +02002673
2674 # access superclass interface members from subclass, mix variable order
2675 lines =<< trim END
2676 vim9script
2677
2678 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002679 var mvar1: number
2680 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002681 endinterface
2682
2683 # NOTE: the order is swapped
2684 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002685 var mvar2: number
2686 var mvar1: number
2687 public static var svar2: number
2688 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002689 def new()
2690 svar1 = 11
2691 svar2 = 12
2692 this.mvar1 = 111
2693 this.mvar2 = 112
2694 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002695 endclass
2696
2697 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002698 def new()
2699 this.mvar1 = 121
2700 this.mvar2 = 122
2701 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002702 endclass
2703
2704 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002705 def new()
2706 this.mvar1 = 131
2707 this.mvar2 = 132
2708 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002709 endclass
2710
Ernie Raelcf138d42023-09-06 20:45:03 +02002711 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002712 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002713 enddef
2714
2715 var oa = A.new()
2716 var ob = B.new()
2717 var oc = C.new()
2718
Ernie Raelcf138d42023-09-06 20:45:03 +02002719 assert_equal([111, 112], F2(oa))
2720 assert_equal([121, 122], F2(ob))
2721 assert_equal([131, 132], F2(oc))
2722 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002723 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002724
2725 # Access superclass interface members from subclass, mix variable order.
2726 # Two interfaces, one on A, one on B; each has both kinds of variables
2727 lines =<< trim END
2728 vim9script
2729
2730 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002731 var mvar1: number
2732 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002733 endinterface
2734
2735 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002736 var mvar3: number
2737 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002738 endinterface
2739
2740 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002741 public static var svar1: number
2742 public static var svar2: number
2743 var mvar1: number
2744 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002745 def new()
2746 svar1 = 11
2747 svar2 = 12
2748 this.mvar1 = 111
2749 this.mvar2 = 112
2750 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002751 endclass
2752
2753 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002754 static var svar3: number
2755 static var svar4: number
2756 var mvar3: number
2757 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002758 def new()
2759 svar3 = 23
2760 svar4 = 24
2761 this.mvar1 = 121
2762 this.mvar2 = 122
2763 this.mvar3 = 123
2764 this.mvar4 = 124
2765 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002766 endclass
2767
2768 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002769 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002770 def new()
2771 svar5 = 1001
2772 this.mvar1 = 131
2773 this.mvar2 = 132
2774 this.mvar3 = 133
2775 this.mvar4 = 134
2776 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002777 endclass
2778
Ernie Raelcf138d42023-09-06 20:45:03 +02002779 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002780 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002781 enddef
2782
Ernie Raelcf138d42023-09-06 20:45:03 +02002783 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002785 enddef
2786
Ernie Raelcf138d42023-09-06 20:45:03 +02002787 var oa = A.new()
2788 var ob = B.new()
2789 var oc = C.new()
2790
Ernie Raelcf138d42023-09-06 20:45:03 +02002791 assert_equal([[111, 112]], [F2(oa)])
2792 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2793 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002794 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002795 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002796
2797 # Using two interface names without a space after the ","
2798 lines =<< trim END
2799 vim9script
2800 interface A
2801 endinterface
2802 interface B
2803 endinterface
2804 class C implements A,B
2805 endclass
2806 END
2807 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2808
2809 # No interface name after a comma
2810 lines =<< trim END
2811 vim9script
2812 interface A
2813 endinterface
2814 class B implements A,
2815 endclass
2816 END
2817 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2818
2819 # No interface name after implements
2820 lines =<< trim END
2821 vim9script
2822 class A implements
2823 endclass
2824 END
2825 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002826enddef
2827
Bram Moolenaard0200c82023-01-28 15:19:40 +00002828def Test_call_interface_method()
2829 var lines =<< trim END
2830 vim9script
2831 interface Base
2832 def Enter(): void
2833 endinterface
2834
2835 class Child implements Base
2836 def Enter(): void
2837 g:result ..= 'child'
2838 enddef
2839 endclass
2840
2841 def F(obj: Base)
2842 obj.Enter()
2843 enddef
2844
2845 g:result = ''
2846 F(Child.new())
2847 assert_equal('child', g:result)
2848 unlet g:result
2849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002850 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002851
2852 lines =<< trim END
2853 vim9script
2854 class Base
2855 def Enter(): void
2856 g:result ..= 'base'
2857 enddef
2858 endclass
2859
2860 class Child extends Base
2861 def Enter(): void
2862 g:result ..= 'child'
2863 enddef
2864 endclass
2865
2866 def F(obj: Base)
2867 obj.Enter()
2868 enddef
2869
2870 g:result = ''
2871 F(Child.new())
2872 assert_equal('child', g:result)
2873 unlet g:result
2874 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002875 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002876
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002877 # method of interface returns a value
2878 lines =<< trim END
2879 vim9script
2880 interface Base
2881 def Enter(): string
2882 endinterface
2883
2884 class Child implements Base
2885 def Enter(): string
2886 g:result ..= 'child'
2887 return "/resource"
2888 enddef
2889 endclass
2890
2891 def F(obj: Base)
2892 var r = obj.Enter()
2893 g:result ..= r
2894 enddef
2895
2896 g:result = ''
2897 F(Child.new())
2898 assert_equal('child/resource', g:result)
2899 unlet g:result
2900 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002901 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002902
2903 lines =<< trim END
2904 vim9script
2905 class Base
2906 def Enter(): string
2907 return null_string
2908 enddef
2909 endclass
2910
2911 class Child extends Base
2912 def Enter(): string
2913 g:result ..= 'child'
2914 return "/resource"
2915 enddef
2916 endclass
2917
2918 def F(obj: Base)
2919 var r = obj.Enter()
2920 g:result ..= r
2921 enddef
2922
2923 g:result = ''
2924 F(Child.new())
2925 assert_equal('child/resource', g:result)
2926 unlet g:result
2927 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002928 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002929
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002930 # No class that implements the interface.
2931 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002932 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002933
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002934 interface IWithEE
2935 def Enter(): any
2936 def Exit(): void
2937 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002939 def With1(ee: IWithEE, F: func)
2940 var r = ee.Enter()
2941 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002942
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002943 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002944 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002945 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002946enddef
2947
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002948def Test_class_used_as_type()
2949 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002951
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002952 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002953 var x = 0
2954 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002955 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002956
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002957 var p: Point
2958 p = Point.new(2, 33)
2959 assert_equal(2, p.x)
2960 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002961 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002962 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002963
2964 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002965 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002967 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002968 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002969 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002970
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002971 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002972 var x = 0
2973 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002974 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002975
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002976 var p: Point
2977 p = Point.new(2, 33)
2978 var hx = p
2979 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002980 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002981 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002982
2983 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002984 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002986 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002987 var x = 0
2988 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002990
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002991 var p: Point
2992 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002993 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002994 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002995enddef
2996
Bram Moolenaar83677162023-01-08 19:54:10 +00002997def Test_class_extends()
2998 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002999 vim9script
3000 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003001 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003002 def GetOne(): number
3003 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00003004 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003005 endclass
3006 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003007 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003008 def GetTotal(): number
3009 return this.one + this.two
3010 enddef
3011 endclass
3012 var o = Child.new()
3013 assert_equal(1, o.one)
3014 assert_equal(2, o.two)
3015 assert_equal(1, o.GetOne())
3016 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00003017 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003018 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003019
3020 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 vim9script
3022 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003023 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003024 endclass
3025 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003026 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003027 endclass
3028 var o = Child.new(3, 44)
3029 assert_equal(3, o.one)
3030 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00003031 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003032 v9.CheckSourceSuccess(lines)
3033
3034 lines =<< trim END
3035 vim9script
3036 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003037 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003038 endclass
3039 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003040 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003041 endclass
3042 END
3043 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
3044
3045 lines =<< trim END
3046 vim9script
3047 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01003048 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 endclass
3050 END
3051 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
3052
3053 lines =<< trim END
3054 vim9script
3055 var SomeVar = 99
3056 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01003057 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003058 endclass
3059 END
3060 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
3061
3062 lines =<< trim END
3063 vim9script
3064 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003065 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003066 def ToString(): string
3067 return this.name
3068 enddef
3069 endclass
3070
3071 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003072 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003073 def ToString(): string
3074 return super.ToString() .. ': ' .. this.age
3075 enddef
3076 endclass
3077
3078 var o = Child.new('John', 42)
3079 assert_equal('John: 42', o.ToString())
3080 END
3081 v9.CheckSourceSuccess(lines)
3082
3083 lines =<< trim END
3084 vim9script
3085 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003086 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 def ToString(): number
3088 return this.age
3089 enddef
3090 def ToString(): string
3091 return this.age
3092 enddef
3093 endclass
3094 END
3095 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
3096
3097 lines =<< trim END
3098 vim9script
3099 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003100 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003101 def ToString(): string
3102 return super .ToString() .. ': ' .. this.age
3103 enddef
3104 endclass
3105 var o = Child.new(42)
3106 echo o.ToString()
3107 END
3108 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
3109
3110 lines =<< trim END
3111 vim9script
3112 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003113 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003114 def ToString(): string
3115 return this.name
3116 enddef
3117 endclass
3118
3119 var age = 42
3120 def ToString(): string
3121 return super.ToString() .. ': ' .. age
3122 enddef
3123 echo ToString()
3124 END
3125 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
3126
3127 lines =<< trim END
3128 vim9script
3129 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003130 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 def ToString(): string
3132 return super.ToString() .. ': ' .. this.age
3133 enddef
3134 endclass
3135 var o = Child.new(42)
3136 echo o.ToString()
3137 END
3138 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3139
3140 lines =<< trim END
3141 vim9script
3142 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003143 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003144 static def ToString(): string
3145 return 'Base class'
3146 enddef
3147 endclass
3148
3149 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003150 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003151 def ToString(): string
3152 return Base.ToString() .. ': ' .. this.age
3153 enddef
3154 endclass
3155
3156 var o = Child.new('John', 42)
3157 assert_equal('Base class: 42', o.ToString())
3158 END
3159 v9.CheckSourceSuccess(lines)
3160
3161 lines =<< trim END
3162 vim9script
3163 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003164 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003165 def new(init: number)
3166 this.value = number + 1
3167 enddef
3168 endclass
3169 class Child extends Base
3170 def new()
3171 this.new(3)
3172 enddef
3173 endclass
3174 var c = Child.new()
3175 END
3176 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003177
3178 # base class with more than one object member
3179 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003180 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003181
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003182 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003183 var success: bool
3184 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003185 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003186
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003187 class Success extends Result
3188 def new(this.value = v:none)
3189 this.success = true
3190 enddef
3191 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003192
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003193 var v = Success.new('asdf')
3194 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003195 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003196 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003197
3198 # class name after "extends" doesn't end in a space or NUL character
3199 lines =<< trim END
3200 vim9script
3201 class A
3202 endclass
3203 class B extends A"
3204 endclass
3205 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003206 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003207enddef
3208
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003209def Test_using_base_class()
3210 var lines =<< trim END
3211 vim9script
3212
3213 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003214 def Enter(): any
3215 return null
3216 enddef
3217 def Exit(resource: any): void
3218 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003219 endclass
3220
3221 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003222 def Enter(): any
3223 return 42
3224 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003225
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003226 def Exit(resource: number): void
3227 g:result ..= '/exit'
3228 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003229 endclass
3230
3231 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003232 var r = ee.Enter()
3233 try
3234 g:result ..= r
3235 finally
3236 g:result ..= '/finally'
3237 ee.Exit(r)
3238 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003239 enddef
3240
3241 g:result = ''
3242 With(ChildEE.new())
3243 assert_equal('42/finally/exit', g:result)
3244 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003245 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003246 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003247
3248 # Using super, Child invokes Base method which has optional arg. #12471
3249 lines =<< trim END
3250 vim9script
3251
3252 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003253 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003254 def Method(arg = 0)
3255 this.success = true
3256 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003257 endclass
3258
3259 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003260 def new()
3261 super.Method()
3262 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003263 endclass
3264
3265 var obj = Child.new()
3266 assert_equal(true, obj.success)
3267 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003268 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003269enddef
3270
Ernie Rael58c95792024-08-13 23:27:22 +02003271def Test_super_dispatch()
3272 # See #15448 and #15463
3273 var lines =<< trim END
3274 vim9script
3275
3276 class A
3277 def String(): string
3278 return 'A'
3279 enddef
3280 endclass
3281
3282 class B extends A
3283 def String(): string
3284 return super.String()
3285 enddef
3286 endclass
3287
3288 class C extends B
3289 endclass
3290
3291 assert_equal('A', C.new().String())
3292 END
3293 v9.CheckSourceSuccess(lines)
3294
3295 lines =<< trim END
3296 vim9script
3297
3298 class A
3299 def F(): string
3300 return 'AA'
3301 enddef
3302 endclass
3303
3304 class B extends A
3305 def F(): string
3306 return 'BB'
3307 enddef
3308 def S(): string
3309 return super.F()
3310 enddef
3311 def S0(): string
3312 return this.S()
3313 enddef
3314 endclass
3315
3316 class C extends B
3317 def F(): string
3318 return 'CC'
3319 enddef
3320 def ToB(): string
3321 return super.F()
3322 enddef
3323 endclass
3324
3325 assert_equal('AA', B.new().S())
3326 assert_equal('AA', C.new().S())
3327 assert_equal('AA', B.new().S0())
3328 assert_equal('AA', C.new().S0())
3329
3330 assert_equal('BB', C.new().ToB())
3331
3332 assert_equal('CC', C.new().F())
3333 assert_equal('BB', B.new().F())
3334 assert_equal('AA', A.new().F())
3335 END
3336 v9.CheckSourceSuccess(lines)
3337
3338 lines =<< trim END
3339 vim9script
3340
3341 var call_chain: list<string>
3342
3343 abstract class A
3344 abstract def _G(): string
3345
3346 def F(): string
3347 call_chain->add('A.F()')
3348 return this._G()
3349 enddef
3350 def _H(): string
3351 call_chain->add('A._H()')
3352 return this.F()
3353 enddef
3354 endclass
3355
3356 class B extends A
3357 def _G(): string
3358 call_chain->add('B.G()')
3359 return 'BBB'
3360 enddef
3361 def SF(): string
3362 call_chain->add('B.SF()')
3363 return super._H()
3364 enddef
3365 endclass
3366
3367 class C extends B
3368 endclass
3369
3370 class D extends C
3371 def SF(): string
3372 call_chain->add('D.SF()')
3373 return super.SF()
3374 enddef
3375 endclass
3376
3377 class E extends D
3378 def SF(): string
3379 call_chain->add('E.SF()')
3380 return super.SF()
3381 enddef
3382 endclass
3383
3384 class F extends E
3385 def _G(): string
3386 call_chain->add('F._G()')
3387 return 'FFF'
3388 enddef
3389 endclass
3390
3391 # E.new() -> A.F() -> B._G()
3392 call_chain = []
3393 var o1 = E.new()
3394 assert_equal('BBB', o1.F())
3395 assert_equal(['A.F()', 'B.G()'], call_chain)
3396
3397 # F.new() -> E.SF() -> D.SF() -> B.SF() -> A._H() -> A.F() -> F._G()
3398 call_chain = []
3399 var o2 = F.new()
3400 assert_equal('FFF', o2.SF())
3401 assert_equal(['E.SF()', 'D.SF()', 'B.SF()', 'A._H()', 'A.F()', 'F._G()'], call_chain)
3402 END
3403 v9.CheckSourceSuccess(lines)
3404enddef
3405
Bram Moolenaara86655a2023-01-12 17:06:27 +00003406def Test_class_import()
3407 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003408 vim9script
3409 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003410 var kind: string
3411 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003412 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003413 END
3414 writefile(lines, 'Xanimal.vim', 'D')
3415
3416 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003417 vim9script
3418 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003419
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003420 var a: animal.Animal
3421 a = animal.Animal.new('fish', 'Eric')
3422 assert_equal('fish', a.kind)
3423 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003425 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3426 assert_equal('cat', b.kind)
3427 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003428 END
3429 v9.CheckScriptSuccess(lines)
3430enddef
3431
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003432" Test for importing a class into a legacy script and calling the class method
3433def Test_class_method_from_legacy_script()
3434 var lines =<< trim END
3435 vim9script
3436 export class A
3437 static var name: string = 'a'
3438 static def SetName(n: string)
3439 name = n
3440 enddef
3441 endclass
3442 END
3443 writefile(lines, 'Xvim9export.vim', 'D')
3444
3445 lines =<< trim END
3446 import './Xvim9export.vim' as vim9
3447
3448 call s:vim9.A.SetName('b')
3449 call assert_equal('b', s:vim9.A.name)
3450 END
3451 v9.CheckScriptSuccess(lines)
3452enddef
3453
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003454" Test for implementing an imported interface
3455def Test_implement_imported_interface()
3456 var lines =<< trim END
3457 vim9script
3458 export interface Imp_Intf1
3459 def Fn1(): number
3460 endinterface
3461 export interface Imp_Intf2
3462 def Fn2(): number
3463 endinterface
3464 END
3465 writefile(lines, 'Ximportinterface.vim', 'D')
3466
3467 lines =<< trim END
3468 vim9script
3469 import './Ximportinterface.vim' as Xintf
3470
3471 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3472 def Fn1(): number
3473 return 10
3474 enddef
3475 def Fn2(): number
3476 return 20
3477 enddef
3478 endclass
3479 var a = A.new()
3480 assert_equal(10, a.Fn1())
3481 assert_equal(20, a.Fn2())
3482 END
3483 v9.CheckScriptSuccess(lines)
3484enddef
3485
3486" Test for extending an imported class
3487def Test_extend_imported_class()
3488 var lines =<< trim END
3489 vim9script
3490 export class Imp_C1
3491 def Fn1(): number
3492 return 5
3493 enddef
3494 endclass
3495 END
3496 writefile(lines, 'Xextendimportclass.vim', 'D')
3497
3498 lines =<< trim END
3499 vim9script
3500 import './Xextendimportclass.vim' as XClass
3501
3502 class A extends XClass.Imp_C1
3503 endclass
3504 var a = A.new()
3505 assert_equal(5, a.Fn1())
3506 END
3507 v9.CheckScriptSuccess(lines)
3508enddef
3509
Hirohito Higashi57f01192025-01-14 17:21:42 +01003510" Test for multi level import
3511def Test_multi_level_import_normal()
3512 var lines =<< trim END
3513 vim9script
3514 export class Property
3515 public var value: string
3516 endclass
3517 END
3518 writefile(lines, 'aa.vim', 'D')
3519
3520 lines =<< trim END
3521 vim9script
3522 import './aa.vim'
3523 export class View
3524 var content = aa.Property.new('')
3525 endclass
3526 END
3527 writefile(lines, 'bb.vim', 'D')
3528
3529 lines =<< trim END
3530 vim9script
3531 import './bb.vim'
3532 class MyView extends bb.View
3533 def new(value: string)
3534 this.content.value = value
3535 enddef
3536 endclass
3537 var myView = MyView.new('This should be ok')
3538 END
3539 v9.CheckScriptSuccess(lines)
3540enddef
3541
3542" Test for multi level import
3543def Test_multi_level_import_nest_over()
3544 var lines =<< trim END
3545 vim9script
3546 import './xbb.vim'
3547 export class Property
3548 public var value: string
3549 endclass
3550 END
3551 writefile(lines, 'xaa.vim', 'D')
3552
3553 lines =<< trim END
3554 vim9script
3555 import './xaa.vim'
3556 export class View
3557 var content = aa.Property.new('')
3558 endclass
3559 END
3560 writefile(lines, 'xbb.vim', 'D')
3561
3562 lines =<< trim END
3563 vim9script
3564 set maxfuncdepth=100
3565 import './xbb.vim'
3566 class MyView extends bb.View
3567 def new(value: string)
3568 this.content.value = value
3569 enddef
3570 endclass
3571 var myView = MyView.new('This should be ok')
3572 END
3573 v9.CheckSourceFailure(lines, 'E1045: Import nesting too deep', 3)
3574enddef
3575
3576def Test_abtstract_class()
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003577 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003578 vim9script
3579 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003580 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003581 endclass
3582 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003583 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003584 endclass
3585 var p: Base = Person.new('Peter', 42)
3586 assert_equal('Peter', p.name)
3587 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003588 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003589 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003590
3591 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003592 vim9script
3593 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003594 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003595 endclass
3596 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003597 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003598 endclass
3599 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003600 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003601 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003602
3603 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003604 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003605 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003606 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003607 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003608 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003609
h-eastaa979c72025-01-03 10:19:45 +01003610 # Test for "abstract" cannot be abbreviated
3611 lines =<< trim END
3612 vim9script
3613 abs class A
3614 endclass
3615 END
3616 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs class A', 2)
3617
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003618 # Additional commands after "abstract class"
3619 lines =<< trim END
3620 vim9script
3621 abstract class Something | var x = []
3622 endclass
3623 END
3624 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3625
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003626 # Abstract class cannot have a "new" function
3627 lines =<< trim END
3628 vim9script
3629 abstract class Base
3630 def new()
3631 enddef
3632 endclass
3633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003634 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003635
3636 # extending an abstract class with class methods and variables
3637 lines =<< trim END
3638 vim9script
3639 abstract class A
3640 static var s: string = 'vim'
3641 static def Fn(): list<number>
3642 return [10]
3643 enddef
3644 endclass
3645 class B extends A
3646 endclass
3647 var b = B.new()
3648 assert_equal('vim', A.s)
3649 assert_equal([10], A.Fn())
3650 END
3651 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003652enddef
3653
Bram Moolenaar486fc252023-01-18 14:51:07 +00003654def Test_closure_in_class()
3655 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003656 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003657
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003658 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003659 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003660
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003661 def new()
3662 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3663 enddef
3664 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003665
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003666 Foo.new()
3667 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003668 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003669 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003670enddef
3671
Ernie Rael9ed53752023-12-11 17:40:46 +01003672def Test_construct_object_from_legacy()
3673 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003674 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003675 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003676
Ernie Rael9ed53752023-12-11 17:40:46 +01003677 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003679 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003680 def new(arg: string)
3681 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003682 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003683 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003684
Ernie Rael9ed53752023-12-11 17:40:46 +01003685 export def CreateA(...args: list<any>): A
3686 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003687 enddef
3688
Ernie Rael9ed53752023-12-11 17:40:46 +01003689 g:P = CreateA
3690 legacy call g:P('some_arg')
3691 assert_equal(true, newCalled)
3692 unlet g:P
3693 END
3694 v9.CheckSourceSuccess(lines)
3695
3696 lines =<< trim END
3697 vim9script
3698
3699 var newCalled = false
3700
3701 class A
3702 static def CreateA(options = {}): any
3703 return A.new()
3704 enddef
3705 def new()
3706 newCalled = true
3707 enddef
3708 endclass
3709
3710 g:P = A.CreateA
3711 legacy call g:P()
3712 assert_equal(true, newCalled)
3713 unlet g:P
3714 END
3715 v9.CheckSourceSuccess(lines)
3716
3717 # This also tests invoking "new()" with "call"
3718 lines =<< trim END
3719 vim9script
3720
3721 var createdObject: any
3722
3723 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003724 var val1: number
3725 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003726 static def CreateA(...args: list<any>): any
3727 createdObject = call(A.new, args)
3728 return createdObject
3729 enddef
3730 endclass
3731
3732 g:P = A.CreateA
3733 legacy call g:P(3, 5)
3734 assert_equal(3, createdObject.val1)
3735 assert_equal(5, createdObject.val2)
3736 legacy call g:P()
3737 assert_equal(0, createdObject.val1)
3738 assert_equal(0, createdObject.val2)
3739 legacy call g:P(7)
3740 assert_equal(7, createdObject.val1)
3741 assert_equal(0, createdObject.val2)
3742 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003743 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003744 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003745enddef
3746
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003747def Test_defer_with_object()
3748 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003749 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003751 class CWithEE
3752 def Enter()
3753 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003754 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003755 def Exit()
3756 g:result ..= "exited"
3757 enddef
3758 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003760 def With(ee: CWithEE, F: func)
3761 ee.Enter()
3762 defer ee.Exit()
3763 F()
3764 enddef
3765
3766 g:result = ''
3767 var obj = CWithEE.new()
3768 obj->With(() => {
3769 g:result ..= "called/"
3770 })
3771 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003772 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003773 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003774 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003775
3776 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003777 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003778
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003779 class BaseWithEE
3780 def Enter()
3781 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003782 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003783 def Exit()
3784 g:result ..= "exited-base"
3785 enddef
3786 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003787
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003788 class CWithEE extends BaseWithEE
3789 def Enter()
3790 g:result ..= "entered-child/"
3791 enddef
3792 def Exit()
3793 g:result ..= "exited-child"
3794 enddef
3795 endclass
3796
3797 def With(ee: BaseWithEE, F: func)
3798 ee.Enter()
3799 defer ee.Exit()
3800 F()
3801 enddef
3802
3803 g:result = ''
3804 var obj = CWithEE.new()
3805 obj->With(() => {
3806 g:result ..= "called/"
3807 })
3808 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003809 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003810 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003811 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003812enddef
3813
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003814" The following test used to crash Vim (Github issue #12676)
3815def Test_extends_method_crashes_vim()
3816 var lines =<< trim END
3817 vim9script
3818
3819 class Observer
3820 endclass
3821
3822 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003823 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003824
3825 def Set(v: any)
3826 if v != this.value
3827 this.value = v
3828 endif
3829 enddef
3830
3831 def Register(observer: Observer)
3832 enddef
3833 endclass
3834
3835 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003836 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003837 endclass
3838
3839 def Observe(obj: Property, who: Observer)
3840 obj.Register(who)
3841 enddef
3842
3843 var p = Bool.new(false)
3844 var myObserver = Observer.new()
3845
3846 Observe(p, myObserver)
3847
3848 p.Set(true)
3849 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003850 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003851enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003852
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003853" Test for calling a method in a class that is extended
3854def Test_call_method_in_extended_class()
3855 var lines =<< trim END
3856 vim9script
3857
3858 var prop_init_called = false
3859 var prop_register_called = false
3860
3861 class Property
3862 def Init()
3863 prop_init_called = true
3864 enddef
3865
3866 def Register()
3867 prop_register_called = true
3868 enddef
3869 endclass
3870
3871 class Bool extends Property
3872 endclass
3873
3874 def Observe(obj: Property)
3875 obj.Register()
3876 enddef
3877
3878 var p = Property.new()
3879 Observe(p)
3880
3881 p.Init()
3882 assert_true(prop_init_called)
3883 assert_true(prop_register_called)
3884 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003885 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003886enddef
3887
LemonBoyafe04662023-08-23 21:08:11 +02003888def Test_instanceof()
3889 var lines =<< trim END
3890 vim9script
3891
3892 class Base1
3893 endclass
3894
3895 class Base2 extends Base1
3896 endclass
3897
3898 interface Intf1
3899 endinterface
3900
3901 class Mix1 implements Intf1
3902 endclass
3903
3904 class Base3 extends Mix1
3905 endclass
3906
Ernie Rael2025af12023-12-12 16:58:00 +01003907 type AliasBase1 = Base1
3908 type AliasBase2 = Base2
3909 type AliasIntf1 = Intf1
3910 type AliasMix1 = Mix1
3911
LemonBoyafe04662023-08-23 21:08:11 +02003912 var b1 = Base1.new()
3913 var b2 = Base2.new()
3914 var b3 = Base3.new()
3915
3916 assert_true(instanceof(b1, Base1))
3917 assert_true(instanceof(b2, Base1))
3918 assert_false(instanceof(b1, Base2))
3919 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003920 assert_true(instanceof(b3, Base1, Base2, Intf1))
3921
3922 assert_true(instanceof(b1, AliasBase1))
3923 assert_true(instanceof(b2, AliasBase1))
3924 assert_false(instanceof(b1, AliasBase2))
3925 assert_true(instanceof(b3, AliasMix1))
3926 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003927
3928 def Foo()
3929 var a1 = Base1.new()
3930 var a2 = Base2.new()
3931 var a3 = Base3.new()
3932
3933 assert_true(instanceof(a1, Base1))
3934 assert_true(instanceof(a2, Base1))
3935 assert_false(instanceof(a1, Base2))
3936 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003937 assert_true(instanceof(a3, Base1, Base2, Intf1))
3938
3939 assert_true(instanceof(a1, AliasBase1))
3940 assert_true(instanceof(a2, AliasBase1))
3941 assert_false(instanceof(a1, AliasBase2))
3942 assert_true(instanceof(a3, AliasMix1))
3943 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003944 enddef
3945 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003946
3947 var o_null: Base1
3948 assert_false(instanceof(o_null, Base1))
3949
LemonBoyafe04662023-08-23 21:08:11 +02003950 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003951 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003952
3953 lines =<< trim END
3954 vim9script
3955
3956 class Base1
3957 endclass
3958 instanceof(Base1.new())
3959 END
3960 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3961
3962 lines =<< trim END
3963 vim9script
3964
3965 class Base1
3966 endclass
3967 def F()
3968 instanceof(Base1.new())
3969 enddef
3970 F()
3971 END
3972 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3973
3974 lines =<< trim END
3975 vim9script
3976
3977 class Base1
3978 endclass
3979
3980 class Base2
3981 endclass
3982
3983 var o = Base2.new()
3984 instanceof(o, Base1, Base2, 3)
3985 END
3986 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3987
3988 lines =<< trim END
3989 vim9script
3990
3991 class Base1
3992 endclass
3993
3994 class Base2
3995 endclass
3996
3997 def F()
3998 var o = Base2.new()
3999 instanceof(o, Base1, Base2, 3)
4000 enddef
4001 F()
4002 END
4003 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02004004enddef
4005
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004006" Test for calling a method in the parent class that is extended partially.
4007" This used to fail with the 'E118: Too many arguments for function: Text' error
4008" message (Github issue #12524).
4009def Test_call_method_in_parent_class()
4010 var lines =<< trim END
4011 vim9script
4012
4013 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01004014 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004015
4016 def SetY(lnum: number)
4017 this._lnum = lnum
4018 enddef
4019
4020 def Text(): string
4021 return ''
4022 enddef
4023 endclass
4024
4025 class Foo extends Widget
4026 def Text(): string
4027 return '<Foo>'
4028 enddef
4029 endclass
4030
4031 def Stack(w1: Widget, w2: Widget): list<Widget>
4032 w1.SetY(1)
4033 w2.SetY(2)
4034 return [w1, w2]
4035 enddef
4036
4037 var foo1 = Foo.new()
4038 var foo2 = Foo.new()
4039 var l = Stack(foo1, foo2)
4040 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004041 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02004042enddef
4043
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004044" Test for calling methods from three levels of classes
4045def Test_multi_level_method_call()
4046 var lines =<< trim END
4047 vim9script
4048
4049 var A_func1: number = 0
4050 var A_func2: number = 0
4051 var A_func3: number = 0
4052 var B_func2: number = 0
4053 var B_func3: number = 0
4054 var C_func3: number = 0
4055
4056 class A
4057 def Func1()
4058 A_func1 += 1
4059 enddef
4060
4061 def Func2()
4062 A_func2 += 1
4063 enddef
4064
4065 def Func3()
4066 A_func3 += 1
4067 enddef
4068 endclass
4069
4070 class B extends A
4071 def Func2()
4072 B_func2 += 1
4073 enddef
4074
4075 def Func3()
4076 B_func3 += 1
4077 enddef
4078 endclass
4079
4080 class C extends B
4081 def Func3()
4082 C_func3 += 1
4083 enddef
4084 endclass
4085
4086 def A_CallFuncs(a: A)
4087 a.Func1()
4088 a.Func2()
4089 a.Func3()
4090 enddef
4091
4092 def B_CallFuncs(b: B)
4093 b.Func1()
4094 b.Func2()
4095 b.Func3()
4096 enddef
4097
4098 def C_CallFuncs(c: C)
4099 c.Func1()
4100 c.Func2()
4101 c.Func3()
4102 enddef
4103
4104 var cobj = C.new()
4105 A_CallFuncs(cobj)
4106 B_CallFuncs(cobj)
4107 C_CallFuncs(cobj)
4108 assert_equal(3, A_func1)
4109 assert_equal(0, A_func2)
4110 assert_equal(0, A_func3)
4111 assert_equal(3, B_func2)
4112 assert_equal(0, B_func3)
4113 assert_equal(3, C_func3)
4114 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004115 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004116enddef
4117
4118" Test for using members from three levels of classes
4119def Test_multi_level_member_access()
4120 var lines =<< trim END
4121 vim9script
4122
4123 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004124 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004125 endclass
4126
4127 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01004128 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004129 endclass
4130
4131 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01004132 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004133 endclass
4134
4135 def A_members(a: A)
4136 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004137 enddef
4138
4139 def B_members(b: B)
4140 b.val1 += 1
4141 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004142 enddef
4143
4144 def C_members(c: C)
4145 c.val1 += 1
4146 c.val2 += 1
4147 c.val3 += 1
4148 enddef
4149
4150 var cobj = C.new()
4151 A_members(cobj)
4152 B_members(cobj)
4153 C_members(cobj)
4154 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004155 assert_equal(2, cobj.val2)
4156 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004157 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004158 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02004159enddef
4160
LemonBoy0ffc17a2023-08-20 18:09:11 +02004161" Test expansion of <stack> with class methods.
4162def Test_stack_expansion_with_methods()
4163 var lines =<< trim END
4164 vim9script
4165
4166 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004167 def M1()
4168 F0()
4169 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02004170 endclass
4171
4172 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02004173 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02004174 enddef
4175
4176 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004177 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02004178 enddef
4179
4180 F()
4181 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004182 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02004183enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004184
4185" Test the return type of the new() constructor
4186def Test_new_return_type()
4187 # new() uses the default return type and there is no return statement
4188 var lines =<< trim END
4189 vim9script
4190
4191 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004192 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004193
4194 def new(this._bufnr)
4195 if !bufexists(this._bufnr)
4196 this._bufnr = -1
4197 endif
4198 enddef
4199 endclass
4200
4201 var c = C.new(12345)
4202 assert_equal('object<C>', typename(c))
4203
4204 var v1: C
4205 v1 = C.new(12345)
4206 assert_equal('object<C>', typename(v1))
4207
4208 def F()
4209 var v2: C
4210 v2 = C.new(12345)
4211 assert_equal('object<C>', typename(v2))
4212 enddef
4213 F()
4214 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004215 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004216
4217 # new() uses the default return type and an empty 'return' statement
4218 lines =<< trim END
4219 vim9script
4220
4221 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004222 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004223
4224 def new(this._bufnr)
4225 if !bufexists(this._bufnr)
4226 this._bufnr = -1
4227 return
4228 endif
4229 enddef
4230 endclass
4231
4232 var c = C.new(12345)
4233 assert_equal('object<C>', typename(c))
4234
4235 var v1: C
4236 v1 = C.new(12345)
4237 assert_equal('object<C>', typename(v1))
4238
4239 def F()
4240 var v2: C
4241 v2 = C.new(12345)
4242 assert_equal('object<C>', typename(v2))
4243 enddef
4244 F()
4245 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004246 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004247
4248 # new() uses "any" return type and returns "this"
4249 lines =<< trim END
4250 vim9script
4251
4252 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004253 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004254
4255 def new(this._bufnr): any
4256 if !bufexists(this._bufnr)
4257 this._bufnr = -1
4258 return this
4259 endif
4260 enddef
4261 endclass
4262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004263 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004264
4265 # new() uses 'Dict' return type and returns a Dict
4266 lines =<< trim END
4267 vim9script
4268
4269 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004270 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004271
4272 def new(): dict<any>
4273 this._state = {}
4274 return this._state
4275 enddef
4276 endclass
4277
4278 var c = C.new()
4279 assert_equal('object<C>', typename(c))
4280 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004281 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02004282enddef
4283
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004284" Test for checking a member initialization type at run time.
4285def Test_runtime_type_check_for_member_init()
4286 var lines =<< trim END
4287 vim9script
4288
4289 var retnum: bool = false
4290
4291 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004292 retnum = !retnum
4293 if retnum
4294 return 1
4295 else
4296 return "hello"
4297 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004298 enddef
4299
4300 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004301 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004302 endclass
4303
4304 var c1 = C.new()
4305 var c2 = C.new()
4306 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004307 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004308enddef
4309
4310" Test for locking a variable referring to an object and reassigning to another
4311" object.
Ernie Raelee865f32023-09-29 19:53:55 +02004312def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004313 var lines =<< trim END
4314 vim9script
4315
4316 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004317 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004318 def new(this.val)
4319 enddef
4320 endclass
4321
4322 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
4323 lockvar 2 some_dict
4324
4325 var current: C
4326 current = some_dict['c']
4327 assert_equal(3, current.val)
4328 current = some_dict['b']
4329 assert_equal(2, current.val)
4330
4331 def F()
4332 current = some_dict['c']
4333 enddef
4334
4335 def G()
4336 current = some_dict['b']
4337 enddef
4338
4339 F()
4340 assert_equal(3, current.val)
4341 G()
4342 assert_equal(2, current.val)
4343 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004344 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004345enddef
4346
Ernie Raelee865f32023-09-29 19:53:55 +02004347" Test trying to lock an object variable from various places
4348def Test_lockvar_object_variable()
4349 # An object variable lockvar has several cases:
4350 # object method, scriptlevel, scriplevel from :def, :def arg
4351 # method arg, static method arg.
4352 # Also different depths
4353
Ernie Raelee865f32023-09-29 19:53:55 +02004354 #
4355 # lockvar of read-only object variable
4356 #
4357
4358 # read-only lockvar from object method
4359 var lines =<< trim END
4360 vim9script
4361
4362 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004363 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004364 def Lock()
4365 lockvar this.val1
4366 enddef
4367 endclass
4368 var o = C.new(3)
4369 o.Lock()
4370 END
Ernie Rael64885642023-10-04 20:16:22 +02004371 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004372
4373 # read-only lockvar from scriptlevel
4374 lines =<< trim END
4375 vim9script
4376
4377 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004378 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004379 endclass
4380 var o = C.new(3)
4381 lockvar o.val2
4382 END
4383 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4384
4385 # read-only lockvar of scriptlevel variable from def
4386 lines =<< trim END
4387 vim9script
4388
4389 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004390 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004391 endclass
4392 var o = C.new(3)
4393 def Lock()
4394 lockvar o.val3
4395 enddef
4396 Lock()
4397 END
4398 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4399
4400 # read-only lockvar of def argument variable
4401 lines =<< trim END
4402 vim9script
4403
4404 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004405 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004406 endclass
4407 def Lock(o: C)
4408 lockvar o.val4
4409 enddef
4410 Lock(C.new(3))
4411 END
4412 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4413
Ernie Raelee865f32023-09-29 19:53:55 +02004414 # read-only lockvar from object method arg
4415 lines =<< trim END
4416 vim9script
4417
4418 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004419 var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004420 def Lock(c: C)
4421 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004422 enddef
4423 endclass
4424 var o = C.new(3)
4425 o.Lock(C.new(5))
4426 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004427 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004428
4429 # read-only lockvar from class method arg
4430 lines =<< trim END
4431 vim9script
4432
4433 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004434 var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004435 static def Lock(c: C)
4436 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004437 enddef
4438 endclass
4439 var o = C.new(3)
4440 C.Lock(o)
4441 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004442 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004443
4444 #
4445 # lockvar of public object variable
4446 #
4447
4448 # lockvar from object method
4449 lines =<< trim END
4450 vim9script
4451
4452 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004453 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004454 def Lock()
4455 lockvar this.val1
4456 enddef
4457 endclass
4458 var o = C.new(3)
4459 o.Lock()
4460 END
4461 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4462
4463 # lockvar from scriptlevel
4464 lines =<< trim END
4465 vim9script
4466
4467 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004468 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004469 endclass
4470 var o = C.new(3)
4471 lockvar o.val2
4472 END
4473 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4474
4475 # lockvar of scriptlevel variable from def
4476 lines =<< trim END
4477 vim9script
4478
4479 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004480 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004481 endclass
4482 var o = C.new(3)
4483 def Lock()
4484 lockvar o.val3
4485 enddef
4486 Lock()
4487 END
4488 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4489
4490 # lockvar of def argument variable
4491 lines =<< trim END
4492 vim9script
4493
4494 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004495 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004496 endclass
4497 def Lock(o: C)
4498 lockvar o.val4
4499 enddef
4500 Lock(C.new(3))
4501 END
4502 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4503
4504 # lockvar from object method arg
4505 lines =<< trim END
4506 vim9script
4507
4508 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004509 public var val5: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004510 def Lock(c: C)
4511 lockvar c.val5
Ernie Raelee865f32023-09-29 19:53:55 +02004512 enddef
4513 endclass
4514 var o = C.new(3)
4515 o.Lock(C.new(5))
4516 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004517 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val5" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004518
4519 # lockvar from class method arg
4520 lines =<< trim END
4521 vim9script
4522
4523 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004524 public var val6: number
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004525 static def Lock(c: C)
4526 lockvar c.val6
Ernie Raelee865f32023-09-29 19:53:55 +02004527 enddef
4528 endclass
4529 var o = C.new(3)
4530 C.Lock(o)
4531 END
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004532 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "c.val6" in class "C"', 1)
Ernie Raelee865f32023-09-29 19:53:55 +02004533enddef
4534
4535" Test trying to lock a class variable from various places
4536def Test_lockvar_class_variable()
4537
4538 # lockvar bare static from object method
4539 var lines =<< trim END
4540 vim9script
4541
4542 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004543 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004544 def Lock()
4545 lockvar sval1
4546 enddef
4547 endclass
4548 var o = C.new()
4549 o.Lock()
4550 END
4551 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4552
4553 # lockvar C.static from object method
4554 lines =<< trim END
4555 vim9script
4556
4557 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004558 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004559 def Lock()
4560 lockvar C.sval2
4561 enddef
4562 endclass
4563 var o = C.new()
4564 o.Lock()
4565 END
4566 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4567
4568 # lockvar bare static from class method
4569 lines =<< trim END
4570 vim9script
4571
4572 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004573 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004574 static def Lock()
4575 lockvar sval3
4576 enddef
4577 endclass
4578 C.Lock()
4579 END
4580 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4581
4582 # lockvar C.static from class method
4583 lines =<< trim END
4584 vim9script
4585
4586 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004587 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004588 static def Lock()
4589 lockvar C.sval4
4590 enddef
4591 endclass
4592 C.Lock()
4593 END
4594 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4595
4596 # lockvar C.static from script level
4597 lines =<< trim END
4598 vim9script
4599
4600 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004601 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004602 endclass
4603 lockvar C.sval5
4604 END
4605 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4606
4607 # lockvar o.static from script level
4608 lines =<< trim END
4609 vim9script
4610
4611 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004612 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004613 endclass
4614 var o = C.new()
4615 lockvar o.sval6
4616 END
4617 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4618enddef
4619
4620" Test locking an argument to :def
4621def Test_lockvar_argument()
4622 # Lockvar a function arg
4623 var lines =<< trim END
4624 vim9script
4625
4626 def Lock(val: any)
4627 lockvar val
4628 enddef
4629
4630 var d = {a: 1, b: 2}
4631 Lock(d)
4632
4633 d->extend({c: 3})
4634 END
4635 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4636
4637 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4638 # class member in "C". This tests lval_root_is_arg.
4639 lines =<< trim END
4640 vim9script
4641
4642 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004643 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004644 endclass
4645
4646 def Lock2(sval: any)
4647 lockvar sval
4648 enddef
4649
4650 var o = C.new()
4651 Lock2(o)
4652 END
4653 v9.CheckSourceSuccess(lines)
4654
4655 # Lock a class.
4656 lines =<< trim END
4657 vim9script
4658
4659 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004660 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004661 endclass
4662
4663 def Lock2(sval: any)
4664 lockvar sval
4665 enddef
4666
4667 Lock2(C)
4668 END
Ernie Raelb077b582023-12-14 20:11:44 +01004669 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004670
4671 # Lock an object.
4672 lines =<< trim END
4673 vim9script
4674
4675 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004676 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004677 endclass
4678
4679 def Lock2(sval: any)
4680 lockvar sval
4681 enddef
4682
4683 Lock2(C.new())
4684 END
4685 v9.CheckSourceSuccess(lines)
4686
4687 # In this case (unlike previous) "lockvar sval" is a class member.
4688 lines =<< trim END
4689 vim9script
4690
4691 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004692 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004693 def Lock2()
4694 lockvar sval
4695 enddef
4696 endclass
4697
4698
4699 var o = C.new()
4700 o.Lock2()
4701 END
4702 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4703enddef
4704
4705" Test that this can be locked without error
4706def Test_lockvar_this()
4707 # lockvar this
4708 var lines =<< trim END
4709 vim9script
4710 class C
4711 def TLock()
4712 lockvar this
4713 enddef
4714 endclass
4715 var o = C.new()
4716 o.TLock()
4717 END
4718 v9.CheckSourceSuccess(lines)
4719
4720 # lockvar four (four letter word, but not this)
4721 lines =<< trim END
4722 vim9script
4723 class C
4724 def TLock4()
4725 var four: number
4726 lockvar four
4727 enddef
4728 endclass
4729 var o = C.new()
4730 o.TLock4()
4731 END
4732 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4733
4734 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4735 lines =<< trim END
4736 vim9script
4737 class C
4738 def TLock5()
4739 var this5: number
4740 lockvar this5
4741 enddef
4742 endclass
4743 var o = C.new()
4744 o.TLock5()
4745 END
4746 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4747enddef
4748
4749" Test some general lockvar cases
4750def Test_lockvar_general()
4751 # lockvar an object and a class. It does nothing
4752 var lines =<< trim END
4753 vim9script
4754 class C
4755 endclass
4756 var o = C.new()
4757 lockvar o
4758 lockvar C
4759 END
4760 v9.CheckSourceSuccess(lines)
4761
4762 # Lock a list element that's nested in an object variable from a :def
4763 lines =<< trim END
4764 vim9script
4765
4766 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004767 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004768 endclass
4769 def Lock2(obj: any)
4770 lockvar obj.val[1]
4771 enddef
4772
4773 var o = C.new()
4774 Lock2(o)
4775 o.val[0] = [9]
4776 assert_equal([ [9], [2], [3] ], o.val)
4777 try
4778 o.val[1] = [999]
4779 call assert_false(true, 'assign should have failed')
4780 catch
4781 assert_exception('E741:')
4782 endtry
4783 o.val[2] = [8]
4784 assert_equal([ [9], [2], [8] ], o.val)
4785 END
4786 v9.CheckSourceSuccess(lines)
4787
4788 # Lock a list element that's nested in an object variable from scriptlevel
4789 lines =<< trim END
4790 vim9script
4791
4792 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004793 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004794 endclass
4795
4796 var o = C.new()
4797 lockvar o.val[1]
4798 o.val[0] = [9]
4799 assert_equal([ [9], [2], [3] ], o.val)
4800 try
4801 o.val[1] = [999]
4802 call assert_false(true, 'assign should have failed')
4803 catch
4804 assert_exception('E741:')
4805 endtry
4806 o.val[2] = [8]
4807 assert_equal([ [9], [2], [8] ], o.val)
4808 END
4809 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004810
4811 # lock a script level variable from an object method
4812 lines =<< trim END
4813 vim9script
4814
4815 class C
4816 def Lock()
4817 lockvar l
4818 enddef
4819 endclass
4820
4821 var l = [1]
4822 C.new().Lock()
4823 l[0] = 11
4824 END
4825 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4826
Ernie Rael03042a22023-11-11 08:53:32 +01004827 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004828 # in an object fetched via a script level list
4829 lines =<< trim END
4830 vim9script
4831
4832 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004833 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004834 def Lock()
4835 lockvar lc[0]._v1[1]
4836 enddef
4837 endclass
4838
4839 var l = [[1], [2], [3]]
4840 var o = C.new(l)
4841 var lc: list<C> = [ o ]
4842
4843 o.Lock()
4844 l[0] = [22]
4845 l[1] = [33]
4846 END
4847 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4848
4849 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004850 # in a class that does not own the protected variable.
4851 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004852 # the same name.
4853 lines =<< trim END
4854 vim9script
4855
4856 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004857 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004858 def Lock(obj: any)
4859 lockvar lc[0]._v1[1]
4860 enddef
4861 endclass
4862
4863 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004864 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004865 endclass
4866
4867 var l = [[1], [2], [3]]
4868 var o = C.new(l)
4869 var lc: list<C> = [ o ]
4870
4871 var o2 = C2.new()
4872 o2.Lock(o)
4873 END
Ernie Rael03042a22023-11-11 08:53:32 +01004874 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004875enddef
4876
Ernie Rael9771b2a2023-10-07 22:05:40 +02004877" Test builtin islocked()
4878def Test_lockvar_islocked()
4879 # Can't lock class/object variable
4880 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004881 # Lock item of variable's value (a list item)
4882 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004883 var lines =<< trim END
4884 vim9script
4885
4886 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004887 var o0: list<list<number>> = [ [0], [1], [2]]
4888 var o1: list<list<number>> = [[10], [11], [12]]
4889 static var c0: list<list<number>> = [[20], [21], [22]]
4890 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004891 endclass
4892
4893 def LockIt(arg: any)
4894 lockvar arg
4895 enddef
4896
4897 def UnlockIt(arg: any)
4898 unlockvar arg
4899 enddef
4900
4901 var obj = C.new()
4902 #lockvar obj.o1 # can't lock something you can't write to
4903
4904 try
4905 lockvar obj.o1 # can't lock something you can't write to
4906 call assert_false(1, '"lockvar obj.o1" should have failed')
4907 catch
4908 call assert_exception('E1335:')
4909 endtry
4910
4911 LockIt(obj.o1) # but can lock it's value
4912 assert_equal(1, islocked("obj.o1"))
4913 assert_equal(1, islocked("obj.o1[0]"))
4914 assert_equal(1, islocked("obj.o1[1]"))
4915 UnlockIt(obj.o1)
4916 assert_equal(0, islocked("obj.o1"))
4917 assert_equal(0, islocked("obj.o1[0]"))
4918
4919 lockvar obj.o1[0]
4920 assert_equal(0, islocked("obj.o1"))
4921 assert_equal(1, islocked("obj.o1[0]"))
4922 assert_equal(0, islocked("obj.o1[1]"))
4923 unlockvar obj.o1[0]
4924 assert_equal(0, islocked("obj.o1"))
4925 assert_equal(0, islocked("obj.o1[0]"))
4926
4927 # Same thing, but with a static
4928
4929 try
4930 lockvar C.c1 # can't lock something you can't write to
4931 call assert_false(1, '"lockvar C.c1" should have failed')
4932 catch
4933 call assert_exception('E1335:')
4934 endtry
4935
4936 LockIt(C.c1) # but can lock it's value
4937 assert_equal(1, islocked("C.c1"))
4938 assert_equal(1, islocked("C.c1[0]"))
4939 assert_equal(1, islocked("C.c1[1]"))
4940 UnlockIt(C.c1)
4941 assert_equal(0, islocked("C.c1"))
4942 assert_equal(0, islocked("C.c1[0]"))
4943
4944 lockvar C.c1[0]
4945 assert_equal(0, islocked("C.c1"))
4946 assert_equal(1, islocked("C.c1[0]"))
4947 assert_equal(0, islocked("C.c1[1]"))
4948 unlockvar C.c1[0]
4949 assert_equal(0, islocked("C.c1"))
4950 assert_equal(0, islocked("C.c1[0]"))
4951 END
4952 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004953
4954 # Do islocked() from an object method
4955 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004956 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004957 vim9script
4958
4959 var l0o0 = [ [0], [1], [2]]
4960 var l0o1 = [ [10], [11], [12]]
4961 var l0c0 = [[120], [121], [122]]
4962 var l0c1 = [[130], [131], [132]]
4963
4964 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004965 var o0: list<list<number>> = l0o0
4966 var o1: list<list<number>> = l0o1
4967 static var c0: list<list<number>> = l0c0
4968 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004969 def Islocked(arg: string): number
4970 return islocked(arg)
4971 enddef
4972 static def SIslocked(arg: string): number
4973 return islocked(arg)
4974 enddef
4975 endclass
4976
4977 var l2o0 = [[20000], [20001], [20002]]
4978 var l2o1 = [[20010], [20011], [20012]]
4979 var l2c0 = [[20120], [20121], [20122]]
4980 var l2c1 = [[20130], [20131], [20132]]
4981
4982 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004983 var o0: list<list<number>> = l2o0
4984 var o1: list<list<number>> = l2o1
4985 static var c0: list<list<number>> = l2c0
4986 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004987 def Islocked(arg: string): number
4988 return islocked(arg)
4989 enddef
4990 static def SIslocked(arg: string): number
4991 return islocked(arg)
4992 enddef
4993 endclass
4994
4995 var obj0 = C0.new()
4996 var obj2 = C2.new()
4997
4998 var l = [ obj0, null_object, obj2 ]
4999
5000 # lock list, object func access through script var expr
5001 assert_equal(0, obj0.Islocked("l[0].o0"))
5002 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
5003 lockvar l0o0
5004 assert_equal(1, obj0.Islocked("l[0].o0"))
5005 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
5006
5007 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
5008
5009 # lock list element, object func access through script var expr
5010 lockvar l0o1[1]
5011 assert_equal(0, obj0.Islocked("this.o1[0]"))
5012 assert_equal(1, obj0.Islocked("this.o1[1]"))
5013
5014 assert_equal(0, obj0.Islocked("this.o1"))
5015 lockvar l0o1
5016 assert_equal(1, obj0.Islocked("this.o1"))
5017 unlockvar l0o1
5018
5019 lockvar l0c1[1]
5020
5021 # static by class name member expr from same class
5022 assert_equal(0, obj0.Islocked("C0.c1[0]"))
5023 assert_equal(1, obj0.Islocked("C0.c1[1]"))
5024 # static by bare name member expr from same class
5025 assert_equal(0, obj0.Islocked("c1[0]"))
5026 assert_equal(1, obj0.Islocked("c1[1]"))
5027
5028 # static by class name member expr from other class
5029 assert_equal(0, obj2.Islocked("C0.c1[0]"))
5030 assert_equal(1, obj2.Islocked("C0.c1[1]"))
5031 # static by bare name member expr from other class
5032 assert_equal(0, obj2.Islocked("c1[0]"))
5033 assert_equal(0, obj2.Islocked("c1[1]"))
5034
5035
5036 # static by bare name in same class
5037 assert_equal(0, obj0.Islocked("c0"))
5038 lockvar l0c0
5039 assert_equal(1, obj0.Islocked("c0"))
5040
5041 #
5042 # similar stuff, but use static method
5043 #
5044
5045 unlockvar l0o0
5046
5047 # lock list, object func access through script var expr
5048 assert_equal(0, C0.SIslocked("l[0].o0"))
5049 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
5050 lockvar l0o0
5051 assert_equal(1, C0.SIslocked("l[0].o0"))
5052 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
5053
5054 unlockvar l0o1
5055
5056 # can't access "this" from class method
5057 try
5058 C0.SIslocked("this.o1[0]")
5059 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
5060 catch
5061 call assert_exception('E121: Undefined variable: this')
5062 endtry
5063
5064 lockvar l0c1[1]
5065
5066 # static by class name member expr from same class
5067 assert_equal(0, C0.SIslocked("C0.c1[0]"))
5068 assert_equal(1, C0.SIslocked("C0.c1[1]"))
5069 # static by bare name member expr from same class
5070 assert_equal(0, C0.SIslocked("c1[0]"))
5071 assert_equal(1, C0.SIslocked("c1[1]"))
5072
5073 # static by class name member expr from other class
5074 assert_equal(0, C2.SIslocked("C0.c1[0]"))
5075 assert_equal(1, C2.SIslocked("C0.c1[1]"))
5076 # static by bare name member expr from other class
5077 assert_equal(0, C2.SIslocked("c1[0]"))
5078 assert_equal(0, C2.SIslocked("c1[1]"))
5079
5080
5081 # static by bare name in same class
5082 unlockvar l0c0
5083 assert_equal(0, C0.SIslocked("c0"))
5084 lockvar l0c0
5085 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02005086 END
Ernie Rael4c8da022023-10-11 21:35:11 +02005087 v9.CheckSourceSuccess(lines)
5088
5089 # Check islocked class/object from various places.
5090 lines =<< trim END
5091 vim9script
5092
5093 class C
5094 def Islocked(arg: string): number
5095 return islocked(arg)
5096 enddef
5097 static def SIslocked(arg: string): number
5098 return islocked(arg)
5099 enddef
5100 endclass
5101 var obj = C.new()
5102
5103 # object method
5104 assert_equal(0, obj.Islocked("this"))
5105 assert_equal(0, obj.Islocked("C"))
5106
5107 # class method
5108 ### assert_equal(0, C.SIslocked("this"))
5109 assert_equal(0, C.SIslocked("C"))
5110
5111 #script level
5112 var v: number
5113 v = islocked("C")
5114 assert_equal(0, v)
5115 v = islocked("obj")
5116 assert_equal(0, v)
5117 END
5118 v9.CheckSourceSuccess(lines)
5119enddef
5120
5121def Test_lockvar_islocked_notfound()
5122 # Try non-existent things
5123 var lines =<< trim END
5124 vim9script
5125
5126 class C
5127 def Islocked(arg: string): number
5128 return islocked(arg)
5129 enddef
5130 static def SIslocked(arg: string): number
5131 return islocked(arg)
5132 enddef
5133 endclass
5134 var obj = C.new()
5135 assert_equal(-1, obj.Islocked("anywhere"))
5136 assert_equal(-1, C.SIslocked("notanywhere"))
5137 END
5138 v9.CheckSourceSuccess(lines)
5139
5140 # Something not found of the form "name1.name2" is an error
5141 lines =<< trim END
5142 vim9script
5143
5144 islocked("one.two")
5145 END
5146 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
5147
5148 lines =<< trim END
5149 vim9script
5150
5151 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005152 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02005153 def Islocked(arg: string): number
5154 return islocked(arg)
5155 enddef
5156 endclass
5157 var obj = C.new()
5158 obj.Islocked("this.val.not_there"))
5159 END
5160 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
5161
5162 lines =<< trim END
5163 vim9script
5164
5165 class C
5166 def Islocked(arg: string): number
5167 return islocked(arg)
5168 enddef
5169 endclass
5170 var obj = C.new()
5171 obj.Islocked("this.notobjmember")
5172 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005173 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02005174
5175 # access a script variable through methods
5176 lines =<< trim END
5177 vim9script
5178
5179 var l = [1]
5180 class C
5181 def Islocked(arg: string): number
5182 return islocked(arg)
5183 enddef
5184 static def SIslocked(arg: string): number
5185 return islocked(arg)
5186 enddef
5187 endclass
5188 var obj = C.new()
5189 assert_equal(0, obj.Islocked("l"))
5190 assert_equal(0, C.SIslocked("l"))
5191 lockvar l
5192 assert_equal(1, obj.Islocked("l"))
5193 assert_equal(1, C.SIslocked("l"))
5194 END
5195 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02005196enddef
5197
Ernie Rael03042a22023-11-11 08:53:32 +01005198" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005199def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005200 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005201 var lines =<< trim END
5202 vim9script
5203
5204 class A
5205 def _Foo(): number
5206 return 1234
5207 enddef
5208 endclass
5209 var a = A.new()
5210 a._Foo()
5211 END
Ernie Rael03042a22023-11-11 08:53:32 +01005212 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005213
Ernie Rael03042a22023-11-11 08:53:32 +01005214 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005215 lines =<< trim END
5216 vim9script
5217
5218 class A
5219 def _Foo(): number
5220 return 1234
5221 enddef
5222 endclass
5223 def T()
5224 var a = A.new()
5225 a._Foo()
5226 enddef
5227 T()
5228 END
Ernie Rael03042a22023-11-11 08:53:32 +01005229 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005230
Ernie Rael03042a22023-11-11 08:53:32 +01005231 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005232 lines =<< trim END
5233 vim9script
5234
5235 class A
5236 def _Foo(): number
5237 return 1234
5238 enddef
5239 def Bar(): number
5240 return this._Foo()
5241 enddef
5242 endclass
5243 var a = A.new()
5244 assert_equal(1234, a.Bar())
5245 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005246 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005247
Ernie Rael03042a22023-11-11 08:53:32 +01005248 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005249 lines =<< trim END
5250 vim9script
5251
5252 class A
5253 def _Foo(): number
5254 return 1234
5255 enddef
5256 def Bar(): number
5257 return this._Foo()
5258 enddef
5259 endclass
5260 def T()
5261 var a = A.new()
5262 assert_equal(1234, a.Bar())
5263 enddef
5264 T()
5265 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005266 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005267
Ernie Rael03042a22023-11-11 08:53:32 +01005268 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005269 lines =<< trim END
5270 vim9script
5271
5272 class A
5273 def _Foo(): number
5274 return 1234
5275 enddef
5276 def Bar(): number
5277 return _Foo()
5278 enddef
5279 endclass
5280 var a = A.new()
5281 a.Bar()
5282 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005283 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005284
Ernie Rael03042a22023-11-11 08:53:32 +01005285 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005286 lines =<< trim END
5287 vim9script
5288
5289 class A
5290 def _Foo(): number
5291 return 1234
5292 enddef
5293 endclass
5294 A._Foo()
5295 END
Ernie Rael03042a22023-11-11 08:53:32 +01005296 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005297
Ernie Rael03042a22023-11-11 08:53:32 +01005298 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005299 lines =<< trim END
5300 vim9script
5301
5302 class A
5303 def _Foo()
5304 enddef
5305 def _Foo()
5306 enddef
5307 endclass
5308 var a = A.new()
5309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005310 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005311
Ernie Rael03042a22023-11-11 08:53:32 +01005312 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005313 lines =<< trim END
5314 vim9script
5315
5316 class A
5317 def _Foo()
5318 enddef
5319 def Foo()
5320 enddef
5321 endclass
5322 var a = A.new()
5323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005324 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005325
Ernie Rael03042a22023-11-11 08:53:32 +01005326 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005327 lines =<< trim END
5328 vim9script
5329
5330 class A
5331 def Foo()
5332 enddef
5333 def _Foo()
5334 enddef
5335 endclass
5336 var a = A.new()
5337 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005338 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005339
Ernie Rael03042a22023-11-11 08:53:32 +01005340 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005341 lines =<< trim END
5342 vim9script
5343
5344 class A
5345 def Foo(): number
5346 return 100
5347 enddef
5348 def _Bar(): number
5349 return 200
5350 enddef
5351 def _Baz()
5352 assert_equal(100, this.Foo())
5353 assert_equal(200, this._Bar())
5354 enddef
5355 def T()
5356 this._Baz()
5357 enddef
5358 endclass
5359 var a = A.new()
5360 a.T()
5361 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005362 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005363
Ernie Rael03042a22023-11-11 08:53:32 +01005364 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005365 lines =<< trim END
5366 vim9script
5367
5368 class A
5369 def _Foo(): number
5370 return 100
5371 enddef
5372 endclass
5373 class B
5374 def Foo(): number
5375 var a = A.new()
5376 a._Foo()
5377 enddef
5378 endclass
5379 var b = B.new()
5380 b.Foo()
5381 END
Ernie Rael03042a22023-11-11 08:53:32 +01005382 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005383
Ernie Rael03042a22023-11-11 08:53:32 +01005384 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005385 lines =<< trim END
5386 vim9script
5387 class A
5388 def _Foo(): number
5389 return 1234
5390 enddef
5391 endclass
5392 class B extends A
5393 def Bar()
5394 enddef
5395 endclass
5396 class C extends B
5397 def Baz(): number
5398 return this._Foo()
5399 enddef
5400 endclass
5401 var c = C.new()
5402 assert_equal(1234, c.Baz())
5403 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005404 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005405
Ernie Rael03042a22023-11-11 08:53:32 +01005406 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005407 lines =<< trim END
5408 vim9script
5409 class A
5410 def _Foo(): number
5411 return 1234
5412 enddef
5413 endclass
5414 class B extends A
5415 def Bar()
5416 enddef
5417 endclass
5418 class C extends B
5419 def Baz(): number
5420 enddef
5421 endclass
5422 var c = C.new()
5423 assert_equal(1234, c._Foo())
5424 END
Ernie Rael03042a22023-11-11 08:53:32 +01005425 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005426
5427 # Using "_" prefix in a method name should fail outside of a class
5428 lines =<< trim END
5429 vim9script
5430 def _Foo(): number
5431 return 1234
5432 enddef
5433 var a = _Foo()
5434 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005435 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005436enddef
5437
Ernie Rael03042a22023-11-11 08:53:32 +01005438" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005439def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005440 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005441 var lines =<< trim END
5442 vim9script
5443
5444 class A
5445 static def _Foo(): number
5446 return 1234
5447 enddef
5448 endclass
5449 A._Foo()
5450 END
Ernie Rael03042a22023-11-11 08:53:32 +01005451 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005452
Ernie Rael03042a22023-11-11 08:53:32 +01005453 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005454 lines =<< trim END
5455 vim9script
5456
5457 class A
5458 static def _Foo(): number
5459 return 1234
5460 enddef
5461 endclass
5462 def T()
5463 A._Foo()
5464 enddef
5465 T()
5466 END
Ernie Rael03042a22023-11-11 08:53:32 +01005467 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005468
Ernie Rael03042a22023-11-11 08:53:32 +01005469 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005470 lines =<< trim END
5471 vim9script
5472
5473 class A
5474 static def _Foo(): number
5475 return 1234
5476 enddef
5477 endclass
5478 var a = A.new()
5479 a._Foo()
5480 END
Ernie Rael03042a22023-11-11 08:53:32 +01005481 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005482
Ernie Rael03042a22023-11-11 08:53:32 +01005483 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005484 lines =<< trim END
5485 vim9script
5486
5487 class A
5488 static def _Foo(): number
5489 return 1234
5490 enddef
5491 endclass
5492 def T()
5493 var a = A.new()
5494 a._Foo()
5495 enddef
5496 T()
5497 END
Ernie Rael03042a22023-11-11 08:53:32 +01005498 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005499
Ernie Rael03042a22023-11-11 08:53:32 +01005500 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005501 lines =<< trim END
5502 vim9script
5503
5504 class A
5505 static def _Foo(): number
5506 return 1234
5507 enddef
5508 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005509 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005510 enddef
5511 endclass
5512 var a = A.new()
5513 a.Bar()
5514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005516
Ernie Rael03042a22023-11-11 08:53:32 +01005517 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005518 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005519 lines =<< trim END
5520 vim9script
5521
5522 class A
5523 static def _Foo1(): number
5524 return 1234
5525 enddef
5526 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005527 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005528 enddef
5529 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005530 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005531 enddef
5532 endclass
5533 var a = A.new()
5534 a.Bar()
5535 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005536 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005537
Ernie Rael03042a22023-11-11 08:53:32 +01005538 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005539 lines =<< trim END
5540 vim9script
5541
5542 class A
5543 static def _Foo()
5544 enddef
5545 static def Foo()
5546 enddef
5547 endclass
5548 var a = A.new()
5549 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005550 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005551
Ernie Rael03042a22023-11-11 08:53:32 +01005552 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005553 lines =<< trim END
5554 vim9script
5555
5556 class A
5557 static def _Foo(): number
5558 return 1234
5559 enddef
5560 endclass
5561 class B
5562 def Foo(): number
5563 return A._Foo()
5564 enddef
5565 endclass
5566 var b = B.new()
5567 assert_equal(1234, b.Foo())
5568 END
Ernie Rael03042a22023-11-11 08:53:32 +01005569 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005570
Ernie Rael03042a22023-11-11 08:53:32 +01005571 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005572 lines =<< trim END
5573 vim9script
5574 class A
5575 static def _Foo(): number
5576 return 1234
5577 enddef
5578 endclass
5579 class B extends A
5580 def Bar()
5581 enddef
5582 endclass
5583 class C extends B
5584 def Baz(): number
5585 return A._Foo()
5586 enddef
5587 endclass
5588 var c = C.new()
5589 assert_equal(1234, c.Baz())
5590 END
Ernie Rael03042a22023-11-11 08:53:32 +01005591 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005592
Ernie Rael03042a22023-11-11 08:53:32 +01005593 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005594 lines =<< trim END
5595 vim9script
5596 class A
5597 static def _Foo(): number
5598 return 1234
5599 enddef
5600 endclass
5601 class B extends A
5602 def Bar()
5603 enddef
5604 endclass
5605 class C extends B
5606 static def Baz(): number
5607 return A._Foo()
5608 enddef
5609 endclass
5610 assert_equal(1234, C.Baz())
5611 END
Ernie Rael03042a22023-11-11 08:53:32 +01005612 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005613
Ernie Rael03042a22023-11-11 08:53:32 +01005614 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005615 lines =<< trim END
5616 vim9script
5617 class A
5618 static def _Foo(): number
5619 return 1234
5620 enddef
5621 endclass
5622 class B extends A
5623 def Bar()
5624 enddef
5625 endclass
5626 class C extends B
5627 def Baz(): number
5628 enddef
5629 endclass
5630 var c = C.new()
5631 assert_equal(1234, C._Foo())
5632 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005633 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005634enddef
5635
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005636" Test for using the return value of a class/object method as a function
5637" argument.
5638def Test_objmethod_funcarg()
5639 var lines =<< trim END
5640 vim9script
5641
5642 class C
5643 def Foo(): string
5644 return 'foo'
5645 enddef
5646 endclass
5647
5648 def Bar(a: number, s: string): string
5649 return s
5650 enddef
5651
5652 def Baz(c: C)
5653 assert_equal('foo', Bar(10, c.Foo()))
5654 enddef
5655
5656 var t = C.new()
5657 Baz(t)
5658 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005659 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005660
5661 lines =<< trim END
5662 vim9script
5663
5664 class C
5665 static def Foo(): string
5666 return 'foo'
5667 enddef
5668 endclass
5669
5670 def Bar(a: number, s: string): string
5671 return s
5672 enddef
5673
5674 def Baz()
5675 assert_equal('foo', Bar(10, C.Foo()))
5676 enddef
5677
5678 Baz()
5679 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005680 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005681enddef
5682
Ernie Raelcf138d42023-09-06 20:45:03 +02005683def Test_static_inheritence()
5684 # subclasses get their own static copy
5685 var lines =<< trim END
5686 vim9script
5687
5688 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005689 static var _svar: number
5690 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005691 def new()
5692 _svar = 1
5693 this._mvar = 101
5694 enddef
5695 def AccessObject(): number
5696 return this._mvar
5697 enddef
5698 def AccessStaticThroughObject(): number
5699 return _svar
5700 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005701 endclass
5702
5703 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005704 def new()
5705 this._mvar = 102
5706 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005707 endclass
5708
5709 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005710 def new()
5711 this._mvar = 103
5712 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005713
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005714 def AccessPrivateStaticThroughClassName(): number
5715 assert_equal(1, A._svar)
5716 return 444
5717 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005718 endclass
5719
5720 var oa = A.new()
5721 var ob = B.new()
5722 var oc = C.new()
5723 assert_equal(101, oa.AccessObject())
5724 assert_equal(102, ob.AccessObject())
5725 assert_equal(103, oc.AccessObject())
5726
Ernie Rael03042a22023-11-11 08:53:32 +01005727 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005728
5729 # verify object properly resolves to correct static
5730 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005731 assert_equal(1, ob.AccessStaticThroughObject())
5732 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005733 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005734 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005735enddef
5736
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005737" Test for declaring duplicate object and class members
5738def Test_dup_member_variable()
5739 # Duplicate member variable
5740 var lines =<< trim END
5741 vim9script
5742 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005743 var val = 10
5744 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005745 endclass
5746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005747 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005748
Ernie Rael03042a22023-11-11 08:53:32 +01005749 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005750 lines =<< trim END
5751 vim9script
5752 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005753 var _val = 10
5754 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005755 endclass
5756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005757 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005758
5759 # Duplicate public member variable
5760 lines =<< trim END
5761 vim9script
5762 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005763 public var val = 10
5764 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005765 endclass
5766 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005767 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005768
Ernie Rael03042a22023-11-11 08:53:32 +01005769 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005770 lines =<< trim END
5771 vim9script
5772 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005773 var val = 10
5774 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005775 endclass
5776 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005777 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005778
Ernie Rael03042a22023-11-11 08:53:32 +01005779 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005780 lines =<< trim END
5781 vim9script
5782 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005783 var _val = 20
5784 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005785 endclass
5786 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005787 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005788
5789 # Duplicate class member variable
5790 lines =<< trim END
5791 vim9script
5792 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005793 static var s: string = "abc"
5794 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005795 endclass
5796 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005797 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005798
Ernie Rael03042a22023-11-11 08:53:32 +01005799 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005800 lines =<< trim END
5801 vim9script
5802 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005803 public static var s: string = "abc"
5804 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005805 endclass
5806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005807 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005808
5809 # Duplicate class and object member variable
5810 lines =<< trim END
5811 vim9script
5812 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005813 static var val = 10
5814 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005815 def new()
5816 enddef
5817 endclass
5818 var c = C.new()
5819 assert_equal(10, C.val)
5820 assert_equal(20, c.val)
5821 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005822 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005823
5824 # Duplicate object member variable in a derived class
5825 lines =<< trim END
5826 vim9script
5827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005828 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005829 endclass
5830 class B extends A
5831 endclass
5832 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005833 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005834 endclass
5835 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005836 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005837
Ernie Rael03042a22023-11-11 08:53:32 +01005838 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005839 lines =<< trim END
5840 vim9script
5841 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005842 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005843 endclass
5844 class B extends A
5845 endclass
5846 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005847 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005848 endclass
5849 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005850 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005851
Ernie Rael03042a22023-11-11 08:53:32 +01005852 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005853 lines =<< trim END
5854 vim9script
5855 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005856 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005857 endclass
5858 class B extends A
5859 endclass
5860 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005861 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005862 endclass
5863 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005864 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005865
5866 # Duplicate object member variable in a derived class
5867 lines =<< trim END
5868 vim9script
5869 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005870 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005871 endclass
5872 class B extends A
5873 endclass
5874 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005875 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005876 endclass
5877 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005878 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005879
5880 # Two member variables with a common prefix
5881 lines =<< trim END
5882 vim9script
5883 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005884 public static var svar2: number
5885 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005886 endclass
5887 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005888 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005889enddef
5890
Ernie Rael03042a22023-11-11 08:53:32 +01005891" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005892def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005893 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005894 var lines =<< trim END
5895 vim9script
5896 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005897 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005898 def GetVal(): number
5899 return this._val
5900 enddef
5901 endclass
5902 def T()
5903 var a = A.new()
5904 a._val = 20
5905 enddef
5906 T()
5907 END
Ernie Rael03042a22023-11-11 08:53:32 +01005908 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005909
Ernie Rael03042a22023-11-11 08:53:32 +01005910 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005911 lines =<< trim END
5912 vim9script
5913 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005914 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005915 endclass
5916 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005917 var a = A.new()
5918 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005919 enddef
5920 T()
5921 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005922 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005923
Ernie Rael03042a22023-11-11 08:53:32 +01005924 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005925 lines =<< trim END
5926 vim9script
5927 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005928 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005929 endclass
5930 def T()
5931 var a = A.new()
5932 var x = a._val
5933 enddef
5934 T()
5935 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005936 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005937
Ernie Rael03042a22023-11-11 08:53:32 +01005938 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005939 lines =<< trim END
5940 vim9script
5941 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005942 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005943 endclass
5944 def T()
5945 var a = A.new()
5946 a._val = 3
5947 enddef
5948 T()
5949 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005950 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005951
Ernie Rael03042a22023-11-11 08:53:32 +01005952 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005953 lines =<< trim END
5954 vim9script
5955 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005956 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005957 endclass
5958 def T()
5959 var x = A._val
5960 enddef
5961 T()
5962 END
Ernie Rael03042a22023-11-11 08:53:32 +01005963 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005964
Ernie Rael03042a22023-11-11 08:53:32 +01005965 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005966 lines =<< trim END
5967 vim9script
5968 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005969 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005970 endclass
5971 def T()
5972 A._val = 3
5973 enddef
5974 T()
5975 END
Ernie Rael03042a22023-11-11 08:53:32 +01005976 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005977enddef
5978
5979" Test for changing the member access of an interface in a implementation class
5980def Test_change_interface_member_access()
5981 var lines =<< trim END
5982 vim9script
5983 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005984 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005985 endinterface
5986 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005987 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005988 endclass
5989 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005990 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005991
5992 lines =<< trim END
5993 vim9script
5994 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005995 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005996 endinterface
5997 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005998 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005999 endclass
6000 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006001 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02006002enddef
6003
6004" Test for trying to change a readonly member from a def function
6005def Test_readonly_member_change_in_def_func()
6006 var lines =<< trim END
6007 vim9script
6008 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006009 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02006010 endclass
6011 def T()
6012 var a = A.new()
6013 a.val = 20
6014 enddef
6015 T()
6016 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006017 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02006018enddef
6019
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006020" Test for reading and writing a class member from a def function
6021def Test_modify_class_member_from_def_function()
6022 var lines =<< trim END
6023 vim9script
6024 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006025 var var1: number = 10
6026 public static var var2: list<number> = [1, 2]
6027 public static var var3: dict<number> = {a: 1, b: 2}
6028 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006029 endclass
6030 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02006031 assert_equal([1, 2], A.var2)
6032 assert_equal({a: 1, b: 2}, A.var3)
6033 A.var2 = [3, 4]
6034 A.var3 = {c: 3, d: 4}
6035 assert_equal([3, 4], A.var2)
6036 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01006037 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006038 enddef
6039 T()
6040 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006041 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02006042enddef
6043
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006044" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006045def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006046 var lines =<< trim END
6047 vim9script
6048 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006049 public static var svar1: list<number> = [1]
6050 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006051 endclass
6052
6053 A.svar1->add(3)
6054 A.svar2->add(4)
6055 assert_equal([1, 3], A.svar1)
6056 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006057
6058 def Foo()
6059 A.svar1->add(7)
6060 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006061 assert_equal([1, 3, 7], A.svar1)
6062 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006063 enddef
6064 Foo()
6065 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006066 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006067
6068 # Cannot read from a class variable using an object in script context
6069 lines =<< trim END
6070 vim9script
6071 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006072 public var var1: number
6073 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006074 endclass
6075
6076 var a = A.new()
6077 echo a.svar2
6078 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006079 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006080
6081 # Cannot write to a class variable using an object in script context
6082 lines =<< trim END
6083 vim9script
6084 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006085 public var var1: number
6086 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006087 endclass
6088
6089 var a = A.new()
6090 a.svar2 = [2]
6091 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006092 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006093
6094 # Cannot read from a class variable using an object in def method context
6095 lines =<< trim END
6096 vim9script
6097 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006098 public var var1: number
6099 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006100 endclass
6101
6102 def T()
6103 var a = A.new()
6104 echo a.svar2
6105 enddef
6106 T()
6107 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006108 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006109
6110 # Cannot write to a class variable using an object in def method context
6111 lines =<< trim END
6112 vim9script
6113 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006114 public var var1: number
6115 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02006116 endclass
6117
6118 def T()
6119 var a = A.new()
6120 a.svar2 = [2]
6121 enddef
6122 T()
6123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006124 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02006125enddef
6126
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006127" Test for using a interface method using a child object
6128def Test_interface_method_from_child()
6129 var lines =<< trim END
6130 vim9script
6131
6132 interface A
6133 def Foo(): string
6134 endinterface
6135
6136 class B implements A
6137 def Foo(): string
6138 return 'foo'
6139 enddef
6140 endclass
6141
6142 class C extends B
6143 def Bar(): string
6144 return 'bar'
6145 enddef
6146 endclass
6147
6148 def T1(a: A)
6149 assert_equal('foo', a.Foo())
6150 enddef
6151
6152 def T2(b: B)
6153 assert_equal('foo', b.Foo())
6154 enddef
6155
6156 var c = C.new()
6157 T1(c)
6158 T2(c)
6159 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006160 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006161enddef
6162
6163" Test for using an interface method using a child object when it is overridden
6164" by the child class.
Yegappan Lakshmanan8e92db42025-01-13 07:30:11 +01006165def Test_interface_overridden_method_from_child()
6166 var lines =<< trim END
6167 vim9script
6168
6169 interface A
6170 def Foo(): string
6171 endinterface
6172
6173 class B implements A
6174 def Foo(): string
6175 return 'b-foo'
6176 enddef
6177 endclass
6178
6179 class C extends B
6180 def Bar(): string
6181 return 'bar'
6182 enddef
6183 def Foo(): string
6184 return 'c-foo'
6185 enddef
6186 endclass
6187
6188 def T1(a: A)
6189 assert_equal('c-foo', a.Foo())
6190 enddef
6191
6192 def T2(b: B)
6193 assert_equal('c-foo', b.Foo())
6194 enddef
6195
6196 var c = C.new()
6197 T1(c)
6198 T2(c)
6199 END
6200 v9.CheckSourceSuccess(lines)
6201enddef
6202
6203" Test for interface inheritance
6204def Test_interface_inheritance()
6205 var lines =<< trim END
6206 vim9script
6207
6208 interface A
6209 def A_Fn(): string
6210 endinterface
6211
6212 interface B
6213 def B_Fn(): string
6214 endinterface
6215
6216 interface C
6217 def C_Fn(): string
6218 endinterface
6219
6220 class C1 implements A
6221 def A_Fn(): string
6222 return 'c1-a'
6223 enddef
6224 endclass
6225
6226 class C2 extends C1 implements B
6227 def B_Fn(): string
6228 return 'c2-b'
6229 enddef
6230 def A_Fn(): string
6231 return 'c2-a'
6232 enddef
6233 endclass
6234
6235 class C3 extends C2 implements C
6236 def C_Fn(): string
6237 return 'c3-c'
6238 enddef
6239 def A_Fn(): string
6240 return 'c3-a'
6241 enddef
6242 def B_Fn(): string
6243 return 'c3-b'
6244 enddef
6245 endclass
6246
6247 def T1(a: A, s: string)
6248 assert_equal(s, a.A_Fn())
6249 enddef
6250
6251 def T2(b: B, s: string)
6252 assert_equal(s, b.B_Fn())
6253 enddef
6254
6255 def T3(c: C, s: string)
6256 assert_equal(s, c.C_Fn())
6257 enddef
6258
6259 def T4(c1: C1)
6260 T1(c1, 'c3-a')
6261 enddef
6262
6263 def T5(c2: C2)
6264 T1(c2, 'c3-a')
6265 T2(c2, 'c3-b')
6266 enddef
6267
6268 def T6(c3: C3)
6269 T1(c3, 'c3-a')
6270 T2(c3, 'c3-b')
6271 T3(c3, 'c3-c')
6272 enddef
6273
6274 var o3 = C3.new()
6275 T4(o3)
6276 T5(o3)
6277 T6(o3)
6278 END
6279 v9.CheckSourceSuccess(lines)
6280
6281 # Both the parent and child classes implement the same interface
6282 lines =<< trim END
6283 vim9script
6284
6285 interface I
6286 def Foo(): string
6287 endinterface
6288
6289 class A implements I
6290 def Foo(): string
6291 return 'A-foo'
6292 enddef
6293 endclass
6294
6295 class B implements I
6296 def Foo(): string
6297 return 'B-foo'
6298 enddef
6299 endclass
6300
6301 def Bar(i1: I): string
6302 return i1.Foo()
6303 enddef
6304
6305 var b = B.new()
6306 assert_equal('B-foo', Bar(b))
6307 END
6308 v9.CheckSourceSuccess(lines)
6309enddef
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02006310
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006311" Test for abstract methods
6312def Test_abstract_method()
6313 # Use two abstract methods
6314 var lines =<< trim END
6315 vim9script
6316 abstract class A
6317 def M1(): number
6318 return 10
6319 enddef
6320 abstract def M2(): number
6321 abstract def M3(): number
6322 endclass
6323 class B extends A
6324 def M2(): number
6325 return 20
6326 enddef
6327 def M3(): number
6328 return 30
6329 enddef
6330 endclass
6331 var b = B.new()
6332 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
6333 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006334 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006335
6336 # Don't define an abstract method
6337 lines =<< trim END
6338 vim9script
6339 abstract class A
6340 abstract def Foo()
6341 endclass
6342 class B extends A
6343 endclass
6344 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006345 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006346
6347 # Use abstract method in a concrete class
6348 lines =<< trim END
6349 vim9script
6350 class A
6351 abstract def Foo()
6352 endclass
6353 class B extends A
6354 endclass
6355 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006356 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006357
6358 # Use abstract method in an interface
6359 lines =<< trim END
6360 vim9script
6361 interface A
6362 abstract def Foo()
6363 endinterface
6364 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006365 def Foo()
6366 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006367 endclass
6368 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01006369 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6370
6371 # Use abstract static method in an interface
6372 lines =<< trim END
6373 vim9script
6374 interface A
6375 abstract static def Foo()
6376 enddef
6377 endinterface
6378 END
6379 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
6380
6381 # Use abstract static variable in an interface
6382 lines =<< trim END
6383 vim9script
6384 interface A
6385 abstract static foo: number = 10
6386 endinterface
6387 END
6388 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006389
6390 # Abbreviate the "abstract" keyword
6391 lines =<< trim END
6392 vim9script
6393 class A
6394 abs def Foo()
6395 endclass
6396 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006397 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006398
6399 # Use "abstract" with a member variable
6400 lines =<< trim END
6401 vim9script
6402 abstract class A
6403 abstract this.val = 10
6404 endclass
6405 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006406 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006407
6408 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01006409 lines =<< trim END
6410 vim9script
6411 abstract class A
6412 abstract static def Foo(): number
6413 endclass
6414 END
6415 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006416
6417 # Type mismatch between abstract method and concrete method
6418 lines =<< trim END
6419 vim9script
6420 abstract class A
6421 abstract def Foo(a: string, b: number): list<number>
6422 endclass
6423 class B extends A
6424 def Foo(a: number, b: string): list<string>
6425 return []
6426 enddef
6427 endclass
6428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006429 v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>', 9)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006430
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006431 # Invoke an abstract method from a def function
6432 lines =<< trim END
6433 vim9script
6434 abstract class A
6435 abstract def Foo(): list<number>
6436 endclass
6437 class B extends A
6438 def Foo(): list<number>
6439 return [3, 5]
6440 enddef
6441 endclass
6442 def Bar(c: B)
6443 assert_equal([3, 5], c.Foo())
6444 enddef
6445 var b = B.new()
6446 Bar(b)
6447 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006448 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006449
6450 # Use a static method in an abstract class
6451 lines =<< trim END
6452 vim9script
6453 abstract class A
6454 static def Foo(): string
6455 return 'foo'
6456 enddef
6457 endclass
6458 assert_equal('foo', A.Foo())
6459 END
6460 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006461enddef
6462
6463" Test for calling a class method from a subclass
6464def Test_class_method_call_from_subclass()
6465 # class method call from a subclass
6466 var lines =<< trim END
6467 vim9script
6468
6469 class A
6470 static def Foo()
6471 echo "foo"
6472 enddef
6473 endclass
6474
6475 class B extends A
6476 def Bar()
6477 Foo()
6478 enddef
6479 endclass
6480
6481 var b = B.new()
6482 b.Bar()
6483 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006484 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006485enddef
6486
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006487" Test for calling a class method using an object in a def function context and
6488" script context.
6489def Test_class_method_call_using_object()
6490 # script context
6491 var lines =<< trim END
6492 vim9script
6493 class A
6494 static def Foo(): list<string>
6495 return ['a', 'b']
6496 enddef
6497 def Bar()
6498 assert_equal(['a', 'b'], A.Foo())
6499 assert_equal(['a', 'b'], Foo())
6500 enddef
6501 endclass
6502
6503 def T()
6504 assert_equal(['a', 'b'], A.Foo())
6505 var t_a = A.new()
6506 t_a.Bar()
6507 enddef
6508
6509 assert_equal(['a', 'b'], A.Foo())
6510 var a = A.new()
6511 a.Bar()
6512 T()
6513 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006514 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006515
6516 # script context
6517 lines =<< trim END
6518 vim9script
6519 class A
6520 static def Foo(): string
6521 return 'foo'
6522 enddef
6523 endclass
6524
6525 var a = A.new()
6526 assert_equal('foo', a.Foo())
6527 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006528 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006529
6530 # def function context
6531 lines =<< trim END
6532 vim9script
6533 class A
6534 static def Foo(): string
6535 return 'foo'
6536 enddef
6537 endclass
6538
6539 def T()
6540 var a = A.new()
6541 assert_equal('foo', a.Foo())
6542 enddef
6543 T()
6544 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006545 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006546enddef
6547
6548def Test_class_variable()
6549 var lines =<< trim END
6550 vim9script
6551
6552 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006553 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006554 static def ClassFunc()
6555 assert_equal(10, val)
6556 enddef
6557 def ObjFunc()
6558 assert_equal(10, val)
6559 enddef
6560 endclass
6561
6562 class B extends A
6563 endclass
6564
6565 assert_equal(10, A.val)
6566 A.ClassFunc()
6567 var a = A.new()
6568 a.ObjFunc()
6569 var b = B.new()
6570 b.ObjFunc()
6571
6572 def T1(a1: A)
6573 a1.ObjFunc()
6574 A.ClassFunc()
6575 enddef
6576 T1(b)
6577
6578 A.val = 20
6579 assert_equal(20, A.val)
6580 END
6581 v9.CheckSourceSuccess(lines)
6582
6583 # Modifying a parent class variable from a child class method
6584 lines =<< trim END
6585 vim9script
6586
6587 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006588 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006589 endclass
6590
6591 class B extends A
6592 static def ClassFunc()
6593 val = 20
6594 enddef
6595 endclass
6596 B.ClassFunc()
6597 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006598 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006599
6600 # Reading a parent class variable from a child class method
6601 lines =<< trim END
6602 vim9script
6603
6604 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006605 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006606 endclass
6607
6608 class B extends A
6609 static def ClassFunc()
6610 var i = val
6611 enddef
6612 endclass
6613 B.ClassFunc()
6614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006615 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006616
6617 # Modifying a parent class variable from a child object method
6618 lines =<< trim END
6619 vim9script
6620
6621 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006622 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006623 endclass
6624
6625 class B extends A
6626 def ObjFunc()
6627 val = 20
6628 enddef
6629 endclass
6630 var b = B.new()
6631 b.ObjFunc()
6632 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006633 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006634
6635 # Reading a parent class variable from a child object method
6636 lines =<< trim END
6637 vim9script
6638
6639 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006640 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006641 endclass
6642
6643 class B extends A
6644 def ObjFunc()
6645 var i = val
6646 enddef
6647 endclass
6648 var b = B.new()
6649 b.ObjFunc()
6650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006651 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006652
6653 # Modifying a class variable using an object at script level
6654 lines =<< trim END
6655 vim9script
6656
6657 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006658 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006659 endclass
6660 var a = A.new()
6661 a.val = 20
6662 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006663 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006664
6665 # Reading a class variable using an object at script level
6666 lines =<< trim END
6667 vim9script
6668
6669 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006670 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006671 endclass
6672 var a = A.new()
6673 var i = a.val
6674 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006675 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006676
6677 # Modifying a class variable using an object at function level
6678 lines =<< trim END
6679 vim9script
6680
6681 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006682 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006683 endclass
6684
6685 def T()
6686 var a = A.new()
6687 a.val = 20
6688 enddef
6689 T()
6690 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006691 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006692
6693 # Reading a class variable using an object at function level
6694 lines =<< trim END
6695 vim9script
6696
6697 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006698 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006699 endclass
6700 def T()
6701 var a = A.new()
6702 var i = a.val
6703 enddef
6704 T()
6705 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006706 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006707
6708 # Use old implicit var declaration syntax (without initialization)
6709 lines =<< trim END
6710 vim9script
6711
6712 class A
6713 static val: number
6714 endclass
6715 END
6716 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6717
6718 # Use old implicit var declaration syntax (with initialization)
6719 lines =<< trim END
6720 vim9script
6721
6722 class A
6723 static val: number = 10
6724 endclass
6725 END
6726 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6727
6728 # Use old implicit var declaration syntax (type inferred)
6729 lines =<< trim END
6730 vim9script
6731
6732 class A
6733 static val = 10
6734 endclass
6735 END
6736 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6737
6738 # Missing ":var" in "var" class variable declaration (without initialization)
6739 lines =<< trim END
6740 vim9script
6741
6742 class A
6743 static var: number
6744 endclass
6745 END
6746 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6747
6748 # Missing ":var" in "var" class variable declaration (with initialization)
6749 lines =<< trim END
6750 vim9script
6751
6752 class A
6753 static var: number = 10
6754 endclass
6755 END
6756 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6757
6758 # Missing ":var" in "var" class variable declaration (type inferred)
6759 lines =<< trim END
6760 vim9script
6761
6762 class A
6763 static var = 10
6764 endclass
6765 END
6766 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6767
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006768enddef
6769
6770" Test for using a duplicate class method and class variable in a child class
6771def Test_dup_class_member()
6772 # duplicate class variable, class method and overridden object method
6773 var lines =<< trim END
6774 vim9script
6775 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006776 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006777 static def Check()
6778 assert_equal(100, sval)
6779 enddef
6780 def GetVal(): number
6781 return sval
6782 enddef
6783 endclass
6784
6785 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006786 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006787 static def Check()
6788 assert_equal(200, sval)
6789 enddef
6790 def GetVal(): number
6791 return sval
6792 enddef
6793 endclass
6794
6795 def T1(aa: A): number
6796 return aa.GetVal()
6797 enddef
6798
6799 def T2(bb: B): number
6800 return bb.GetVal()
6801 enddef
6802
6803 assert_equal(100, A.sval)
6804 assert_equal(200, B.sval)
6805 var a = A.new()
6806 assert_equal(100, a.GetVal())
6807 var b = B.new()
6808 assert_equal(200, b.GetVal())
6809 assert_equal(200, T1(b))
6810 assert_equal(200, T2(b))
6811 END
6812 v9.CheckSourceSuccess(lines)
6813
6814 # duplicate class variable and class method
6815 lines =<< trim END
6816 vim9script
6817 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006818 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006819 static def Check()
6820 assert_equal(100, sval)
6821 enddef
6822 def GetVal(): number
6823 return sval
6824 enddef
6825 endclass
6826
6827 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006828 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006829 static def Check()
6830 assert_equal(200, sval)
6831 enddef
6832 endclass
6833
6834 def T1(aa: A): number
6835 return aa.GetVal()
6836 enddef
6837
6838 def T2(bb: B): number
6839 return bb.GetVal()
6840 enddef
6841
6842 assert_equal(100, A.sval)
6843 assert_equal(200, B.sval)
6844 var a = A.new()
6845 assert_equal(100, a.GetVal())
6846 var b = B.new()
6847 assert_equal(100, b.GetVal())
6848 assert_equal(100, T1(b))
6849 assert_equal(100, T2(b))
6850 END
6851 v9.CheckSourceSuccess(lines)
6852enddef
6853
6854" Test for calling an instance method using the class
6855def Test_instance_method_call_using_class()
6856 # Invoke an object method using a class in script context
6857 var lines =<< trim END
6858 vim9script
6859 class A
6860 def Foo()
6861 echo "foo"
6862 enddef
6863 endclass
6864 A.Foo()
6865 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006866 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006867
6868 # Invoke an object method using a class in def function context
6869 lines =<< trim END
6870 vim9script
6871 class A
6872 def Foo()
6873 echo "foo"
6874 enddef
6875 endclass
6876 def T()
6877 A.Foo()
6878 enddef
6879 T()
6880 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006881 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006882enddef
6883
6884" Test for duplicate class method and instance method
6885def Test_dup_classmethod_objmethod()
6886 # Duplicate instance method
6887 var lines =<< trim END
6888 vim9script
6889 class A
6890 static def Foo()
6891 enddef
6892 def Foo()
6893 enddef
6894 endclass
6895 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006896 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006897
Ernie Rael03042a22023-11-11 08:53:32 +01006898 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006899 lines =<< trim END
6900 vim9script
6901 class A
6902 static def Foo()
6903 enddef
6904 def _Foo()
6905 enddef
6906 endclass
6907 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006908 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006909
6910 # Duplicate class method
6911 lines =<< trim END
6912 vim9script
6913 class A
6914 def Foo()
6915 enddef
6916 static def Foo()
6917 enddef
6918 endclass
6919 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006920 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006921
Ernie Rael03042a22023-11-11 08:53:32 +01006922 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006923 lines =<< trim END
6924 vim9script
6925 class A
6926 def Foo()
6927 enddef
6928 static def _Foo()
6929 enddef
6930 endclass
6931 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006932 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006933
Ernie Rael03042a22023-11-11 08:53:32 +01006934 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006935 lines =<< trim END
6936 vim9script
6937 class A
6938 def _Foo()
6939 enddef
6940 static def _Foo()
6941 enddef
6942 endclass
6943 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006944 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006945enddef
6946
6947" Test for an instance method access level comparison with parent instance
6948" methods.
6949def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006950 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006951 var lines =<< trim END
6952 vim9script
6953 class A
6954 def Foo()
6955 enddef
6956 endclass
6957 class B extends A
6958 endclass
6959 class C extends B
6960 def _Foo()
6961 enddef
6962 endclass
6963 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006964 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006965
6966 # Public method in subclass
6967 lines =<< trim END
6968 vim9script
6969 class A
6970 def _Foo()
6971 enddef
6972 endclass
6973 class B extends A
6974 endclass
6975 class C extends B
6976 def Foo()
6977 enddef
6978 endclass
6979 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006980 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006981enddef
6982
6983def Test_extend_empty_class()
6984 var lines =<< trim END
6985 vim9script
6986 class A
6987 endclass
6988 class B extends A
6989 endclass
6990 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006991 public static var rw_class_var = 1
6992 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006993 static def ClassMethod(): number
6994 return 3
6995 enddef
6996 def ObjMethod(): number
6997 return 4
6998 enddef
6999 endclass
7000 assert_equal(1, C.rw_class_var)
7001 assert_equal(3, C.ClassMethod())
7002 var c = C.new()
7003 assert_equal(2, c.rw_obj_var)
7004 assert_equal(4, c.ObjMethod())
7005 END
7006 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02007007enddef
7008
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007009" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01007010" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007011def Test_interface_with_unsupported_members()
7012 var lines =<< trim END
7013 vim9script
7014 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007015 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007016 endinterface
7017 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007018 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007019
7020 lines =<< trim END
7021 vim9script
7022 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007023 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007024 endinterface
7025 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007026 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007027
7028 lines =<< trim END
7029 vim9script
7030 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007031 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007032 endinterface
7033 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02007034 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007035
7036 lines =<< trim END
7037 vim9script
7038 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007039 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02007040 endinterface
7041 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02007042 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02007043
7044 lines =<< trim END
7045 vim9script
7046 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007047 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007048 endinterface
7049 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007050 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007051
7052 lines =<< trim END
7053 vim9script
7054 interface A
7055 static def Foo(d: dict<any>): list<string>
7056 endinterface
7057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007058 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007059
7060 lines =<< trim END
7061 vim9script
7062 interface A
7063 static def _Foo(d: dict<any>): list<string>
7064 endinterface
7065 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007066 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007067
7068 lines =<< trim END
7069 vim9script
7070 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007071 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007072 endinterface
7073 END
Ernie Rael03042a22023-11-11 08:53:32 +01007074 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007075
7076 lines =<< trim END
7077 vim9script
7078 interface A
7079 def _Foo(d: dict<any>): list<string>
7080 endinterface
7081 END
Ernie Rael03042a22023-11-11 08:53:32 +01007082 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007083enddef
7084
7085" Test for extending an interface
7086def Test_extend_interface()
7087 var lines =<< trim END
7088 vim9script
7089 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007090 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007091 def Foo()
7092 endinterface
7093 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007094 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007095 def Bar()
7096 endinterface
7097 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007098 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007099 def Foo()
7100 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007101 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007102 def Bar()
7103 enddef
7104 endclass
7105 END
7106 v9.CheckSourceSuccess(lines)
7107
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007108 # extending empty interface
7109 lines =<< trim END
7110 vim9script
7111 interface A
7112 endinterface
7113 interface B extends A
7114 endinterface
7115 class C implements B
7116 endclass
7117 END
7118 v9.CheckSourceSuccess(lines)
7119
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007120 lines =<< trim END
7121 vim9script
7122 interface A
7123 def Foo()
7124 endinterface
7125 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007126 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007127 endinterface
7128 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007129 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007130 endclass
7131 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007132 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007133
7134 lines =<< trim END
7135 vim9script
7136 interface A
7137 def Foo()
7138 endinterface
7139 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007140 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007141 endinterface
7142 class C implements A, B
7143 def Foo()
7144 enddef
7145 endclass
7146 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007147 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007148
7149 # interface cannot extend a class
7150 lines =<< trim END
7151 vim9script
7152 class A
7153 endclass
7154 interface B extends A
7155 endinterface
7156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007157 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007158
7159 # class cannot extend an interface
7160 lines =<< trim END
7161 vim9script
7162 interface A
7163 endinterface
7164 class B extends A
7165 endclass
7166 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007167 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007168
7169 # interface cannot implement another interface
7170 lines =<< trim END
7171 vim9script
7172 interface A
7173 endinterface
7174 interface B implements A
7175 endinterface
7176 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007177 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007178
7179 # interface cannot extend multiple interfaces
7180 lines =<< trim END
7181 vim9script
7182 interface A
7183 endinterface
7184 interface B
7185 endinterface
7186 interface C extends A, B
7187 endinterface
7188 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007189 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007190
7191 # Variable type in an extended interface is of different type
7192 lines =<< trim END
7193 vim9script
7194 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007195 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007196 endinterface
7197 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007198 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007199 endinterface
7200 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007201 var val1: string
7202 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007203 endinterface
7204 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007205 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007206enddef
7207
7208" Test for a child class implementing an interface when some of the methods are
7209" defined in the parent class.
7210def Test_child_class_implements_interface()
7211 var lines =<< trim END
7212 vim9script
7213
7214 interface Intf
7215 def F1(): list<list<number>>
7216 def F2(): list<list<number>>
7217 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01007218 var var1: list<dict<number>>
7219 var var2: list<dict<number>>
7220 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007221 endinterface
7222
7223 class A
7224 def A1()
7225 enddef
7226 def F3(): list<list<number>>
7227 return [[3]]
7228 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007229 var v1: list<list<number>> = [[0]]
7230 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007231 endclass
7232
7233 class B extends A
7234 def B1()
7235 enddef
7236 def F2(): list<list<number>>
7237 return [[2]]
7238 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007239 var v2: list<list<number>> = [[0]]
7240 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007241 endclass
7242
7243 class C extends B implements Intf
7244 def C1()
7245 enddef
7246 def F1(): list<list<number>>
7247 return [[1]]
7248 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01007249 var v3: list<list<number>> = [[0]]
7250 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007251 endclass
7252
7253 def T(if: Intf)
7254 assert_equal([[1]], if.F1())
7255 assert_equal([[2]], if.F2())
7256 assert_equal([[3]], if.F3())
7257 assert_equal([{a: 10}], if.var1)
7258 assert_equal([{b: 20}], if.var2)
7259 assert_equal([{c: 30}], if.var3)
7260 enddef
7261
7262 var c = C.new()
7263 T(c)
7264 assert_equal([[1]], c.F1())
7265 assert_equal([[2]], c.F2())
7266 assert_equal([[3]], c.F3())
7267 assert_equal([{a: 10}], c.var1)
7268 assert_equal([{b: 20}], c.var2)
7269 assert_equal([{c: 30}], c.var3)
7270 END
7271 v9.CheckSourceSuccess(lines)
7272
7273 # One of the interface methods is not found
7274 lines =<< trim END
7275 vim9script
7276
7277 interface Intf
7278 def F1()
7279 def F2()
7280 def F3()
7281 endinterface
7282
7283 class A
7284 def A1()
7285 enddef
7286 endclass
7287
7288 class B extends A
7289 def B1()
7290 enddef
7291 def F2()
7292 enddef
7293 endclass
7294
7295 class C extends B implements Intf
7296 def C1()
7297 enddef
7298 def F1()
7299 enddef
7300 endclass
7301 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007302 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007303
7304 # One of the interface methods is of different type
7305 lines =<< trim END
7306 vim9script
7307
7308 interface Intf
7309 def F1()
7310 def F2()
7311 def F3()
7312 endinterface
7313
7314 class A
7315 def F3(): number
7316 return 0
7317 enddef
7318 def A1()
7319 enddef
7320 endclass
7321
7322 class B extends A
7323 def B1()
7324 enddef
7325 def F2()
7326 enddef
7327 endclass
7328
7329 class C extends B implements Intf
7330 def C1()
7331 enddef
7332 def F1()
7333 enddef
7334 endclass
7335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007336 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007337
7338 # One of the interface variables is not present
7339 lines =<< trim END
7340 vim9script
7341
7342 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007343 var var1: list<dict<number>>
7344 var var2: list<dict<number>>
7345 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007346 endinterface
7347
7348 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007349 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007350 endclass
7351
7352 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007353 var v2: list<list<number>> = [[0]]
7354 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007355 endclass
7356
7357 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007358 var v3: list<list<number>> = [[0]]
7359 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007360 endclass
7361 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007362 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007363
7364 # One of the interface variables is of different type
7365 lines =<< trim END
7366 vim9script
7367
7368 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007369 var var1: list<dict<number>>
7370 var var2: list<dict<number>>
7371 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007372 endinterface
7373
7374 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007375 var v1: list<list<number>> = [[0]]
7376 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007377 endclass
7378
7379 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007380 var v2: list<list<number>> = [[0]]
7381 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007382 endclass
7383
7384 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01007385 var v3: list<list<number>> = [[0]]
7386 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007387 endclass
7388 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007389 v9.CheckSourceFailure(lines, 'E1382: Variable "var3": type mismatch, expected list<dict<number>> but got list<dict<string>>', 22)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007390enddef
7391
7392" Test for extending an interface with duplicate variables and methods
7393def Test_interface_extends_with_dup_members()
7394 var lines =<< trim END
7395 vim9script
7396 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007397 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007398 def Foo1(): number
7399 endinterface
7400 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007401 var n2: number
7402 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007403 def Foo2(): number
7404 def Foo1(): number
7405 endinterface
7406 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007407 var n1 = 10
7408 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007409 def Foo1(): number
7410 return 30
7411 enddef
7412 def Foo2(): number
7413 return 40
7414 enddef
7415 endclass
7416 def T1(a: A)
7417 assert_equal(10, a.n1)
7418 assert_equal(30, a.Foo1())
7419 enddef
7420 def T2(b: B)
7421 assert_equal(10, b.n1)
7422 assert_equal(20, b.n2)
7423 assert_equal(30, b.Foo1())
7424 assert_equal(40, b.Foo2())
7425 enddef
7426 var c = C.new()
7427 T1(c)
7428 T2(c)
7429 END
7430 v9.CheckSourceSuccess(lines)
7431enddef
7432
Yegappan Lakshmananc10342d2025-01-11 09:39:01 +01007433" Test for implementing an interface with different ordering for the interface
7434" member variables.
7435def Test_implement_interface_with_different_variable_order()
7436 var lines =<< trim END
7437 vim9script
7438
7439 interface IX
7440 var F: func(): string
7441 endinterface
7442
7443 class X implements IX
7444 var x: number
7445 var F: func(): string = () => 'ok'
7446 endclass
7447
7448 def Foo(ix: IX): string
7449 return ix.F()
7450 enddef
7451
7452 var x0 = X.new(0)
7453 assert_equal('ok', Foo(x0))
7454 END
7455 v9.CheckSourceSuccess(lines)
7456enddef
7457
Yegappan Lakshmanan8e92db42025-01-13 07:30:11 +01007458" Test for inheriting interfaces from an imported super class
7459def Test_interface_inheritance_with_imported_super()
7460 var lines =<< trim END
7461 vim9script
7462
7463 export interface I
7464 def F(): string
7465 endinterface
7466
7467 export class A implements I
7468 def F(): string
7469 return 'A'
7470 enddef
7471 endclass
7472 END
7473 writefile(lines, 'Xinheritintfimportclass.vim', 'D')
7474
7475 lines =<< trim END
7476 vim9script
7477
7478 import './Xinheritintfimportclass.vim' as i_imp
7479
7480 # class C extends i_imp.A
7481 class C extends i_imp.A implements i_imp.I
7482 def F(): string
7483 return 'C'
7484 enddef
7485 endclass
7486
7487 def TestI(i: i_imp.I): string
7488 return i.F()
7489 enddef
7490
7491 assert_equal('C', TestI(C.new()))
7492 END
7493 v9.CheckSourceSuccess(lines)
7494enddef
7495
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007496" Test for using "any" type for a variable in a sub-class while it has a
7497" concrete type in the interface
7498def Test_implements_using_var_type_any()
7499 var lines =<< trim END
7500 vim9script
7501 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007502 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007503 endinterface
7504 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007505 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007506 endclass
7507 var b = B.new()
7508 assert_equal([{a: '1'}, {b: '2'}], b.val)
7509 END
7510 v9.CheckSourceSuccess(lines)
7511
7512 # initialize instance variable using a different type
7513 lines =<< trim END
7514 vim9script
7515 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007516 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007517 endinterface
7518 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007519 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007520 endclass
7521 var b = B.new()
7522 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007523 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007524enddef
7525
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007526" Test for assigning to a member variable in a nested class
7527def Test_nested_object_assignment()
7528 var lines =<< trim END
7529 vim9script
7530
7531 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007532 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007533 endclass
7534
7535 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007536 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007537 endclass
7538
7539 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007540 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007541 endclass
7542
7543 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007544 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007545 endclass
7546
7547 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007548 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007549 enddef
7550
7551 var d = D.new()
7552 T(d)
7553 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007554 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007555enddef
7556
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007557" Test for calling methods using a null object
7558def Test_null_object_method_call()
7559 # Calling a object method using a null object in script context
7560 var lines =<< trim END
7561 vim9script
7562
7563 class C
7564 def Foo()
7565 assert_report('This method should not be executed')
7566 enddef
7567 endclass
7568
7569 var o: C
7570 o.Foo()
7571 END
7572 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7573
7574 # Calling a object method using a null object in def function context
7575 lines =<< trim END
7576 vim9script
7577
7578 class C
7579 def Foo()
7580 assert_report('This method should not be executed')
7581 enddef
7582 endclass
7583
7584 def T()
7585 var o: C
7586 o.Foo()
7587 enddef
7588 T()
7589 END
7590 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7591
7592 # Calling a object method through another class method using a null object in
7593 # script context
7594 lines =<< trim END
7595 vim9script
7596
7597 class C
7598 def Foo()
7599 assert_report('This method should not be executed')
7600 enddef
7601
7602 static def Bar(o_any: any)
7603 var o_typed: C = o_any
7604 o_typed.Foo()
7605 enddef
7606 endclass
7607
7608 var o: C
7609 C.Bar(o)
7610 END
7611 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7612
7613 # Calling a object method through another class method using a null object in
7614 # def function context
7615 lines =<< trim END
7616 vim9script
7617
7618 class C
7619 def Foo()
7620 assert_report('This method should not be executed')
7621 enddef
7622
7623 static def Bar(o_any: any)
7624 var o_typed: C = o_any
7625 o_typed.Foo()
7626 enddef
7627 endclass
7628
7629 def T()
7630 var o: C
7631 C.Bar(o)
7632 enddef
7633 T()
7634 END
7635 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Ernie Raelbe828252024-07-26 18:37:02 +02007636
7637 # Calling an object method defined in a class that is extended. This differs
7638 # from the previous by invoking ISN_METHODCALL instead of ISN_DCALL.
7639 lines =<< trim END
7640 vim9script
7641
7642 class C0
7643 def F()
7644 enddef
7645 endclass
7646
7647 class C extends C0
7648 endclass
7649
7650 def X()
7651 var o: C0 = null_object
7652 o.F()
7653 enddef
7654 X()
7655 END
7656 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7657
7658 # Getting a function ref an object method.
7659 lines =<< trim END
7660 vim9script
7661
7662 class C0
7663 def F()
7664 enddef
7665 endclass
7666
7667 class C extends C0
7668 endclass
7669
7670 def X()
7671 var o: C0 = null_object
7672 var XXX = o.F
7673 enddef
7674 X()
7675 END
7676 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007677enddef
7678
7679" Test for using a dict as an object member
7680def Test_dict_object_member()
7681 var lines =<< trim END
7682 vim9script
7683
7684 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007685 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007686 def GetState(): dict<number>
7687 return this.state
7688 enddef
7689 endclass
7690
7691 var ctx = Context.new()
7692 ctx.state->extend({a: 1})
7693 ctx.state['b'] = 2
7694 assert_equal({a: 1, b: 2}, ctx.GetState())
7695
7696 def F()
7697 ctx.state['c'] = 3
7698 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7699 enddef
7700 F()
7701 assert_equal(3, ctx.state.c)
7702 ctx.state.c = 4
7703 assert_equal(4, ctx.state.c)
7704 END
7705 v9.CheckSourceSuccess(lines)
7706enddef
7707
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007708" The following test was failing after 9.0.1914. This was caused by using a
7709" freed object from a previous method call.
7710def Test_freed_object_from_previous_method_call()
7711 var lines =<< trim END
7712 vim9script
7713
7714 class Context
7715 endclass
7716
7717 class Result
7718 endclass
7719
7720 def Failure(): Result
7721 return Result.new()
7722 enddef
7723
7724 def GetResult(ctx: Context): Result
7725 return Failure()
7726 enddef
7727
7728 def Test_GetResult()
7729 var ctx = Context.new()
7730 var result = GetResult(ctx)
7731 enddef
7732
7733 Test_GetResult()
7734 END
7735 v9.CheckSourceSuccess(lines)
7736enddef
7737
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007738" Test for duplicate object and class variable
7739def Test_duplicate_variable()
7740 # Object variable name is same as the class variable name
7741 var lines =<< trim END
7742 vim9script
7743 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007744 public static var sval: number
7745 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007746 endclass
7747 var a = A.new()
7748 END
7749 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7750
7751 # Duplicate variable name and calling a class method
7752 lines =<< trim END
7753 vim9script
7754 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007755 public static var sval: number
7756 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007757 def F1()
7758 echo this.sval
7759 enddef
7760 static def F2()
7761 echo sval
7762 enddef
7763 endclass
7764 A.F2()
7765 END
7766 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7767
7768 # Duplicate variable with an empty constructor
7769 lines =<< trim END
7770 vim9script
7771 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007772 public static var sval: number
7773 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007774 def new()
7775 enddef
7776 endclass
7777 var a = A.new()
7778 END
7779 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7780enddef
7781
7782" Test for using a reserved keyword as a variable name
7783def Test_reserved_varname()
7784 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7785 'null_function', 'null_list', 'null_partial', 'null_string',
7786 'null_channel', 'null_job', 'super', 'this']
7787
7788 var lines =<< trim eval END
7789 vim9script
7790 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007791 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007792 endclass
7793 var o = C.new()
7794 END
7795 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7796
7797 lines =<< trim eval END
7798 vim9script
7799 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007800 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007801 def new()
7802 enddef
7803 endclass
7804 var o = C.new()
7805 END
7806 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7807
7808 lines =<< trim eval END
7809 vim9script
7810 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007811 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007812 def new()
7813 enddef
7814 def F()
7815 echo this.{kword}
7816 enddef
7817 endclass
7818 var o = C.new()
7819 o.F()
7820 END
7821 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007822
7823 # class variable name
7824 if kword != 'this'
7825 lines =<< trim eval END
7826 vim9script
7827 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007828 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007829 endclass
7830 END
7831 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7832 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007833 endfor
7834enddef
7835
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007836" Test for checking the type of the arguments and the return value of a object
7837" method in an extended class.
7838def Test_extended_obj_method_type_check()
7839 var lines =<< trim END
7840 vim9script
7841
7842 class A
7843 endclass
7844 class B extends A
7845 endclass
7846 class C extends B
7847 endclass
7848
7849 class Foo
7850 def Doit(p: B): B
7851 return B.new()
7852 enddef
7853 endclass
7854
7855 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007856 def Doit(p: C): B
7857 return B.new()
7858 enddef
7859 endclass
7860 END
7861 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7862
7863 lines =<< trim END
7864 vim9script
7865
7866 class A
7867 endclass
7868 class B extends A
7869 endclass
7870 class C extends B
7871 endclass
7872
7873 class Foo
7874 def Doit(p: B): B
7875 return B.new()
7876 enddef
7877 endclass
7878
7879 class Bar extends Foo
7880 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007881 return C.new()
7882 enddef
7883 endclass
7884 END
7885 v9.CheckSourceSuccess(lines)
7886
7887 lines =<< trim END
7888 vim9script
7889
7890 class A
7891 endclass
7892 class B extends A
7893 endclass
7894 class C extends B
7895 endclass
7896
7897 class Foo
7898 def Doit(p: B): B
7899 return B.new()
7900 enddef
7901 endclass
7902
7903 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007904 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007905 return B.new()
7906 enddef
7907 endclass
7908 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007909 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<A>): object<B>', 20)
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007910
7911 lines =<< trim END
7912 vim9script
7913
7914 class A
7915 endclass
7916 class B extends A
7917 endclass
7918 class C extends B
7919 endclass
7920
7921 class Foo
7922 def Doit(p: B): B
7923 return B.new()
7924 enddef
7925 endclass
7926
7927 class Bar extends Foo
7928 def Doit(p: B): A
7929 return A.new()
7930 enddef
7931 endclass
7932 END
7933 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
Ernie Rael96952b22023-10-17 18:15:01 +02007934
7935 # check varargs type mismatch
7936 lines =<< trim END
7937 vim9script
7938
7939 class B
7940 def F(...xxx: list<any>)
7941 enddef
7942 endclass
7943 class C extends B
7944 def F(xxx: list<any>)
7945 enddef
7946 endclass
7947 END
7948 v9.CheckSourceFailure(lines, 'E1383: Method "F": type mismatch, expected func(...list<any>) but got func(list<any>)', 10)
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007949enddef
7950
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007951" Test type checking for class variable in assignments
7952func Test_class_variable_complex_type_check()
7953 " class variable with a specific type. Try assigning a different type at
7954 " script level.
7955 let lines =<< trim END
7956 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007957 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007958 return {}
7959 enddef
7960 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007961 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007962 endclass
7963 test_garbagecollect_now()
7964 A.Fn = "abc"
7965 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007966 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007967
7968 " class variable with a specific type. Try assigning a different type at
7969 " class def method level.
7970 let lines =<< trim END
7971 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007972 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007973 return {}
7974 enddef
7975 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007976 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007977 def Bar()
7978 Fn = "abc"
7979 enddef
7980 endclass
7981 var a = A.new()
7982 test_garbagecollect_now()
7983 a.Bar()
7984 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007985 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007986
7987 " class variable with a specific type. Try assigning a different type at
7988 " script def method level.
7989 let lines =<< trim END
7990 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007991 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007992 return {}
7993 enddef
7994 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007995 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007996 endclass
7997 def Bar()
7998 A.Fn = "abc"
7999 enddef
8000 test_garbagecollect_now()
8001 Bar()
8002 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008003 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008004
8005 " class variable without any type. Should be set to the initialization
8006 " expression type. Try assigning a different type from script level.
8007 let lines =<< trim END
8008 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008009 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008010 return {}
8011 enddef
8012 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008013 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008014 endclass
8015 test_garbagecollect_now()
8016 A.Fn = "abc"
8017 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008018 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008019
8020 " class variable without any type. Should be set to the initialization
8021 " expression type. Try assigning a different type at class def level.
8022 let lines =<< trim END
8023 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008024 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008025 return {}
8026 enddef
8027 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008028 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008029 def Bar()
8030 Fn = "abc"
8031 enddef
8032 endclass
8033 var a = A.new()
8034 test_garbagecollect_now()
8035 a.Bar()
8036 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008037 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008038
8039 " class variable without any type. Should be set to the initialization
8040 " expression type. Try assigning a different type at script def level.
8041 let lines =<< trim END
8042 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008043 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008044 return {}
8045 enddef
8046 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008047 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008048 endclass
8049 def Bar()
8050 A.Fn = "abc"
8051 enddef
8052 test_garbagecollect_now()
8053 Bar()
8054 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008055 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008056
8057 " class variable with 'any" type. Can be assigned different types.
8058 let lines =<< trim END
8059 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008060 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008061 return {}
8062 enddef
8063 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008064 public static var Fn: any = Foo
8065 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008066 endclass
8067 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008068 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008069 A.Fn = "abc"
8070 test_garbagecollect_now()
8071 assert_equal('string', typename(A.Fn))
8072 A.Fn2 = Foo
8073 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008074 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008075 A.Fn2 = "xyz"
8076 test_garbagecollect_now()
8077 assert_equal('string', typename(A.Fn2))
8078 END
8079 call v9.CheckSourceSuccess(lines)
8080
8081 " class variable with 'any" type. Can be assigned different types.
8082 let lines =<< trim END
8083 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008084 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008085 return {}
8086 enddef
8087 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008088 public static var Fn: any = Foo
8089 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008090
8091 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008092 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008093 Fn = "abc"
8094 assert_equal('string', typename(Fn))
8095 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008096 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008097 Fn2 = "xyz"
8098 assert_equal('string', typename(Fn2))
8099 enddef
8100 endclass
8101 var a = A.new()
8102 test_garbagecollect_now()
8103 a.Bar()
8104 test_garbagecollect_now()
8105 A.Fn = Foo
8106 a.Bar()
8107 END
8108 call v9.CheckSourceSuccess(lines)
8109
8110 " class variable with 'any" type. Can be assigned different types.
8111 let lines =<< trim END
8112 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008113 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008114 return {}
8115 enddef
8116 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008117 public static var Fn: any = Foo
8118 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008119 endclass
8120
8121 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008122 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008123 A.Fn = "abc"
8124 assert_equal('string', typename(A.Fn))
8125 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008126 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008127 A.Fn2 = "xyz"
8128 assert_equal('string', typename(A.Fn2))
8129 enddef
8130 Bar()
8131 test_garbagecollect_now()
8132 A.Fn = Foo
8133 Bar()
8134 END
8135 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008136
8137 let lines =<< trim END
8138 vim9script
8139 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008140 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008141 endclass
8142 assert_equal([0z10, 0z20], A.foo)
8143 A.foo = [0z30]
8144 assert_equal([0z30], A.foo)
8145 var a = A.foo
8146 assert_equal([0z30], a)
8147 END
8148 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008149endfunc
8150
8151" Test type checking for object variable in assignments
8152func Test_object_variable_complex_type_check()
8153 " object variable with a specific type. Try assigning a different type at
8154 " script level.
8155 let lines =<< trim END
8156 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008157 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008158 return {}
8159 enddef
8160 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008161 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008162 endclass
8163 var a = A.new()
8164 test_garbagecollect_now()
8165 a.Fn = "abc"
8166 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008167 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008168
8169 " object variable with a specific type. Try assigning a different type at
8170 " object def method level.
8171 let lines =<< trim END
8172 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008173 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008174 return {}
8175 enddef
8176 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008177 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008178 def Bar()
8179 this.Fn = "abc"
8180 this.Fn = Foo
8181 enddef
8182 endclass
8183 var a = A.new()
8184 test_garbagecollect_now()
8185 a.Bar()
8186 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008187 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008188
8189 " object variable with a specific type. Try assigning a different type at
8190 " script def method level.
8191 let lines =<< trim END
8192 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008193 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008194 return {}
8195 enddef
8196 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008197 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008198 endclass
8199 def Bar()
8200 var a = A.new()
8201 a.Fn = "abc"
8202 a.Fn = Foo
8203 enddef
8204 test_garbagecollect_now()
8205 Bar()
8206 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008207 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008208
8209 " object variable without any type. Should be set to the initialization
8210 " expression type. Try assigning a different type from script level.
8211 let lines =<< trim END
8212 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008213 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008214 return {}
8215 enddef
8216 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008217 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008218 endclass
8219 var a = A.new()
8220 test_garbagecollect_now()
8221 a.Fn = "abc"
8222 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008223 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008224
8225 " object variable without any type. Should be set to the initialization
8226 " expression type. Try assigning a different type at object def level.
8227 let lines =<< trim END
8228 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008229 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008230 return {}
8231 enddef
8232 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008233 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008234 def Bar()
8235 this.Fn = "abc"
8236 this.Fn = Foo
8237 enddef
8238 endclass
8239 var a = A.new()
8240 test_garbagecollect_now()
8241 a.Bar()
8242 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008243 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008244
8245 " object variable without any type. Should be set to the initialization
8246 " expression type. Try assigning a different type at script def level.
8247 let lines =<< trim END
8248 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008249 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008250 return {}
8251 enddef
8252 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008253 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008254 endclass
8255 def Bar()
8256 var a = A.new()
8257 a.Fn = "abc"
8258 a.Fn = Foo
8259 enddef
8260 test_garbagecollect_now()
8261 Bar()
8262 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008263 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008264
8265 " object variable with 'any" type. Can be assigned different types.
8266 let lines =<< trim END
8267 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008268 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008269 return {}
8270 enddef
8271 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008272 public var Fn: any = Foo
8273 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008274 endclass
8275
8276 var a = A.new()
8277 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008278 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008279 a.Fn = "abc"
8280 test_garbagecollect_now()
8281 assert_equal('string', typename(a.Fn))
8282 a.Fn2 = Foo
8283 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008284 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008285 a.Fn2 = "xyz"
8286 test_garbagecollect_now()
8287 assert_equal('string', typename(a.Fn2))
8288 END
8289 call v9.CheckSourceSuccess(lines)
8290
8291 " object variable with 'any" type. Can be assigned different types.
8292 let lines =<< trim END
8293 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008294 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008295 return {}
8296 enddef
8297 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008298 public var Fn: any = Foo
8299 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008300
8301 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008302 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008303 this.Fn = "abc"
8304 assert_equal('string', typename(this.Fn))
8305 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008306 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008307 this.Fn2 = "xyz"
8308 assert_equal('string', typename(this.Fn2))
8309 enddef
8310 endclass
8311
8312 var a = A.new()
8313 test_garbagecollect_now()
8314 a.Bar()
8315 test_garbagecollect_now()
8316 a.Fn = Foo
8317 a.Bar()
8318 END
8319 call v9.CheckSourceSuccess(lines)
8320
8321 " object variable with 'any" type. Can be assigned different types.
8322 let lines =<< trim END
8323 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008324 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008325 return {}
8326 enddef
8327 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008328 public var Fn: any = Foo
8329 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008330 endclass
8331
8332 def Bar()
8333 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008334 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008335 a.Fn = "abc"
8336 assert_equal('string', typename(a.Fn))
8337 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02008338 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02008339 a.Fn2 = "xyz"
8340 assert_equal('string', typename(a.Fn2))
8341 enddef
8342 test_garbagecollect_now()
8343 Bar()
8344 test_garbagecollect_now()
8345 Bar()
8346 END
8347 call v9.CheckSourceSuccess(lines)
8348endfunc
8349
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008350" Test for recursively calling an object method. This used to cause an
8351" use-after-free error.
8352def Test_recursive_object_method_call()
8353 var lines =<< trim END
8354 vim9script
8355 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008356 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008357 def Foo(): number
8358 if this.val >= 90
8359 return this.val
8360 endif
8361 this.val += 1
8362 return this.Foo()
8363 enddef
8364 endclass
8365 var a = A.new()
8366 assert_equal(90, a.Foo())
8367 END
8368 v9.CheckSourceSuccess(lines)
8369enddef
8370
8371" Test for recursively calling a class method.
8372def Test_recursive_class_method_call()
8373 var lines =<< trim END
8374 vim9script
8375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008376 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02008377 static def Foo(): number
8378 if val >= 90
8379 return val
8380 endif
8381 val += 1
8382 return Foo()
8383 enddef
8384 endclass
8385 assert_equal(90, A.Foo())
8386 END
8387 v9.CheckSourceSuccess(lines)
8388enddef
8389
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02008390" Test for checking the argument types and the return type when assigning a
8391" funcref to make sure the invariant class type is used.
8392def Test_funcref_argtype_returntype_check()
8393 var lines =<< trim END
8394 vim9script
8395 class A
8396 endclass
8397 class B extends A
8398 endclass
8399
8400 def Foo(p: B): B
8401 return B.new()
8402 enddef
8403
8404 var Bar: func(A): A = Foo
8405 END
8406 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
8407
8408 lines =<< trim END
8409 vim9script
8410 class A
8411 endclass
8412 class B extends A
8413 endclass
8414
8415 def Foo(p: B): B
8416 return B.new()
8417 enddef
8418
8419 def Baz()
8420 var Bar: func(A): A = Foo
8421 enddef
8422 Baz()
8423 END
8424 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
8425enddef
8426
Ernie Rael96952b22023-10-17 18:15:01 +02008427def Test_funcref_argtype_invariance_check()
8428 var lines =<< trim END
8429 vim9script
8430
8431 class A
8432 endclass
8433 class B extends A
8434 endclass
8435 class C extends B
8436 endclass
8437
8438 var Func: func(B): number
8439 Func = (o: B): number => 3
8440 assert_equal(3, Func(B.new()))
8441 END
8442 v9.CheckSourceSuccess(lines)
8443
8444 lines =<< trim END
8445 vim9script
8446
8447 class A
8448 endclass
8449 class B extends A
8450 endclass
8451 class C extends B
8452 endclass
8453
8454 var Func: func(B): number
8455 Func = (o: A): number => 3
8456 END
8457 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
8458
8459 lines =<< trim END
8460 vim9script
8461
8462 class A
8463 endclass
8464 class B extends A
8465 endclass
8466 class C extends B
8467 endclass
8468
8469 var Func: func(B): number
8470 Func = (o: C): number => 3
8471 END
8472 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
8473enddef
8474
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008475" Test for using an operator (e.g. +) with an assignment
8476def Test_op_and_assignment()
8477 # Using += with a class variable
8478 var lines =<< trim END
8479 vim9script
8480 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008481 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008482 static def Foo(): list<number>
8483 val += [1]
8484 return val
8485 enddef
8486 endclass
8487 def Bar(): list<number>
8488 A.val += [2]
8489 return A.val
8490 enddef
8491 assert_equal([1], A.Foo())
8492 assert_equal([1, 2], Bar())
8493 A.val += [3]
8494 assert_equal([1, 2, 3], A.val)
8495 END
8496 v9.CheckSourceSuccess(lines)
8497
8498 # Using += with an object variable
8499 lines =<< trim END
8500 vim9script
8501 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008502 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02008503 def Foo(): list<number>
8504 this.val += [1]
8505 return this.val
8506 enddef
8507 endclass
8508 def Bar(bar_a: A): list<number>
8509 bar_a.val += [2]
8510 return bar_a.val
8511 enddef
8512 var a = A.new()
8513 assert_equal([1], a.Foo())
8514 assert_equal([1, 2], Bar(a))
8515 a.val += [3]
8516 assert_equal([1, 2, 3], a.val)
8517 END
8518 v9.CheckSourceSuccess(lines)
8519enddef
8520
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008521" Test for using an object method as a funcref
8522def Test_object_funcref()
8523 # Using object method funcref from a def function
8524 var lines =<< trim END
8525 vim9script
8526 class A
8527 def Foo(): list<number>
8528 return [3, 2, 1]
8529 enddef
8530 endclass
8531 def Bar()
8532 var a = A.new()
8533 var Fn = a.Foo
8534 assert_equal([3, 2, 1], Fn())
8535 enddef
8536 Bar()
8537 END
8538 v9.CheckSourceSuccess(lines)
8539
8540 # Using object method funcref at the script level
8541 lines =<< trim END
8542 vim9script
8543 class A
8544 def Foo(): dict<number>
8545 return {a: 1, b: 2}
8546 enddef
8547 endclass
8548 var a = A.new()
8549 var Fn = a.Foo
8550 assert_equal({a: 1, b: 2}, Fn())
8551 END
8552 v9.CheckSourceSuccess(lines)
8553
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008554 # Using object method funcref at the script level
8555 lines =<< trim END
8556 vim9script
8557 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008558 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008559 def Foo(): number
8560 return this.val
8561 enddef
8562 endclass
8563 var a = A.new(345)
8564 var Fn = a.Foo
8565 assert_equal(345, Fn())
8566 END
8567 v9.CheckSourceSuccess(lines)
8568
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008569 # Using object method funcref from another object method
8570 lines =<< trim END
8571 vim9script
8572 class A
8573 def Foo(): list<number>
8574 return [3, 2, 1]
8575 enddef
8576 def Bar()
8577 var Fn = this.Foo
8578 assert_equal([3, 2, 1], Fn())
8579 enddef
8580 endclass
8581 var a = A.new()
8582 a.Bar()
8583 END
8584 v9.CheckSourceSuccess(lines)
8585
8586 # Using function() to get a object method funcref
8587 lines =<< trim END
8588 vim9script
8589 class A
8590 def Foo(l: list<any>): list<any>
8591 return l
8592 enddef
8593 endclass
8594 var a = A.new()
8595 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8596 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8597 END
8598 v9.CheckSourceSuccess(lines)
8599
8600 # Use an object method with a function returning a funcref and then call the
8601 # funcref.
8602 lines =<< trim END
8603 vim9script
8604
8605 def Map(F: func(number): number): func(number): number
8606 return (n: number) => F(n)
8607 enddef
8608
8609 class Math
8610 def Double(n: number): number
8611 return 2 * n
8612 enddef
8613 endclass
8614
8615 const math = Math.new()
8616 assert_equal(48, Map(math.Double)(24))
8617 END
8618 v9.CheckSourceSuccess(lines)
8619
Ernie Rael03042a22023-11-11 08:53:32 +01008620 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008621 lines =<< trim END
8622 vim9script
8623 class A
8624 def _Foo()
8625 enddef
8626 endclass
8627 def Bar()
8628 var a = A.new()
8629 var Fn = a._Foo
8630 enddef
8631 Bar()
8632 END
Ernie Rael03042a22023-11-11 08:53:32 +01008633 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008634
Ernie Rael03042a22023-11-11 08:53:32 +01008635 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008636 lines =<< trim END
8637 vim9script
8638 class A
8639 def _Foo()
8640 enddef
8641 endclass
8642 var a = A.new()
8643 var Fn = a._Foo
8644 END
Ernie Rael03042a22023-11-11 08:53:32 +01008645 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008646
Ernie Rael03042a22023-11-11 08:53:32 +01008647 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008648 lines =<< trim END
8649 vim9script
8650 class A
8651 def _Foo(): list<number>
8652 return [3, 2, 1]
8653 enddef
8654 def Bar()
8655 var Fn = this._Foo
8656 assert_equal([3, 2, 1], Fn())
8657 enddef
8658 endclass
8659 var a = A.new()
8660 a.Bar()
8661 END
8662 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008663
8664 # Using object method funcref using call()
8665 lines =<< trim END
8666 vim9script
8667 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008668 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008669 def Foo(): number
8670 return this.val
8671 enddef
8672 endclass
8673
8674 def Bar(obj: A)
8675 assert_equal(123, call(obj.Foo, []))
8676 enddef
8677
8678 var a = A.new(123)
8679 Bar(a)
8680 assert_equal(123, call(a.Foo, []))
8681 END
8682 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008683enddef
8684
8685" Test for using a class method as a funcref
8686def Test_class_funcref()
8687 # Using class method funcref in a def function
8688 var lines =<< trim END
8689 vim9script
8690 class A
8691 static def Foo(): list<number>
8692 return [3, 2, 1]
8693 enddef
8694 endclass
8695 def Bar()
8696 var Fn = A.Foo
8697 assert_equal([3, 2, 1], Fn())
8698 enddef
8699 Bar()
8700 END
8701 v9.CheckSourceSuccess(lines)
8702
8703 # Using class method funcref at script level
8704 lines =<< trim END
8705 vim9script
8706 class A
8707 static def Foo(): dict<number>
8708 return {a: 1, b: 2}
8709 enddef
8710 endclass
8711 var Fn = A.Foo
8712 assert_equal({a: 1, b: 2}, Fn())
8713 END
8714 v9.CheckSourceSuccess(lines)
8715
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008716 # Using class method funcref at the script level
8717 lines =<< trim END
8718 vim9script
8719 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008720 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008721 static def Foo(): number
8722 return val
8723 enddef
8724 endclass
8725 A.val = 567
8726 var Fn = A.Foo
8727 assert_equal(567, Fn())
8728 END
8729 v9.CheckSourceSuccess(lines)
8730
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008731 # Using function() to get a class method funcref
8732 lines =<< trim END
8733 vim9script
8734 class A
8735 static def Foo(l: list<any>): list<any>
8736 return l
8737 enddef
8738 endclass
8739 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8740 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8741 END
8742 v9.CheckSourceSuccess(lines)
8743
8744 # Using a class method funcref from another class method
8745 lines =<< trim END
8746 vim9script
8747 class A
8748 static def Foo(): list<number>
8749 return [3, 2, 1]
8750 enddef
8751 static def Bar()
8752 var Fn = Foo
8753 assert_equal([3, 2, 1], Fn())
8754 enddef
8755 endclass
8756 A.Bar()
8757 END
8758 v9.CheckSourceSuccess(lines)
8759
8760 # Use a class method with a function returning a funcref and then call the
8761 # funcref.
8762 lines =<< trim END
8763 vim9script
8764
8765 def Map(F: func(number): number): func(number): number
8766 return (n: number) => F(n)
8767 enddef
8768
8769 class Math
8770 static def StaticDouble(n: number): number
8771 return 2 * n
8772 enddef
8773 endclass
8774
8775 assert_equal(48, Map(Math.StaticDouble)(24))
8776 END
8777 v9.CheckSourceSuccess(lines)
8778
Ernie Rael03042a22023-11-11 08:53:32 +01008779 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008780 lines =<< trim END
8781 vim9script
8782 class A
8783 static def _Foo()
8784 enddef
8785 endclass
8786 def Bar()
8787 var Fn = A._Foo
8788 enddef
8789 Bar()
8790 END
Ernie Rael03042a22023-11-11 08:53:32 +01008791 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008792
Ernie Rael03042a22023-11-11 08:53:32 +01008793 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008794 lines =<< trim END
8795 vim9script
8796 class A
8797 static def _Foo()
8798 enddef
8799 endclass
8800 var Fn = A._Foo
8801 END
Ernie Rael03042a22023-11-11 08:53:32 +01008802 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008803
Ernie Rael03042a22023-11-11 08:53:32 +01008804 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008805 lines =<< trim END
8806 vim9script
8807 class A
8808 static def _Foo(): list<number>
8809 return [3, 2, 1]
8810 enddef
8811 static def Bar()
8812 var Fn = _Foo
8813 assert_equal([3, 2, 1], Fn())
8814 enddef
8815 endclass
8816 A.Bar()
8817 END
8818 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008819
8820 # Using class method funcref using call()
8821 lines =<< trim END
8822 vim9script
8823 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008824 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008825 static def Foo(): number
8826 return val
8827 enddef
8828 endclass
8829
8830 def Bar()
8831 A.val = 468
8832 assert_equal(468, call(A.Foo, []))
8833 enddef
8834 Bar()
8835 assert_equal(468, call(A.Foo, []))
8836 END
8837 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008838enddef
8839
8840" Test for using an object member as a funcref
8841def Test_object_member_funcref()
8842 # Using a funcref object variable in an object method
8843 var lines =<< trim END
8844 vim9script
8845 def Foo(n: number): number
8846 return n * 10
8847 enddef
8848
8849 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008850 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008851 def Bar()
8852 assert_equal(200, this.Cb(20))
8853 enddef
8854 endclass
8855
8856 var a = A.new()
8857 a.Bar()
8858 END
8859 v9.CheckSourceSuccess(lines)
8860
8861 # Using a funcref object variable in a def method
8862 lines =<< trim END
8863 vim9script
8864 def Foo(n: number): number
8865 return n * 10
8866 enddef
8867
8868 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008869 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008870 endclass
8871
8872 def Bar()
8873 var a = A.new()
8874 assert_equal(200, a.Cb(20))
8875 enddef
8876 Bar()
8877 END
8878 v9.CheckSourceSuccess(lines)
8879
8880 # Using a funcref object variable at script level
8881 lines =<< trim END
8882 vim9script
8883 def Foo(n: number): number
8884 return n * 10
8885 enddef
8886
8887 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008888 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008889 endclass
8890
8891 var a = A.new()
8892 assert_equal(200, a.Cb(20))
8893 END
8894 v9.CheckSourceSuccess(lines)
8895
8896 # Using a funcref object variable pointing to an object method in an object
8897 # method.
8898 lines =<< trim END
8899 vim9script
8900 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008901 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008902 def Foo(n: number): number
8903 return n * 10
8904 enddef
8905 def Bar()
8906 assert_equal(200, this.Cb(20))
8907 enddef
8908 endclass
8909
8910 var a = A.new()
8911 a.Bar()
8912 END
8913 v9.CheckSourceSuccess(lines)
8914
8915 # Using a funcref object variable pointing to an object method in a def
8916 # method.
8917 lines =<< trim END
8918 vim9script
8919 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008920 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008921 def Foo(n: number): number
8922 return n * 10
8923 enddef
8924 endclass
8925
8926 def Bar()
8927 var a = A.new()
8928 assert_equal(200, a.Cb(20))
8929 enddef
8930 Bar()
8931 END
8932 v9.CheckSourceSuccess(lines)
8933
8934 # Using a funcref object variable pointing to an object method at script
8935 # level.
8936 lines =<< trim END
8937 vim9script
8938 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008939 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008940 def Foo(n: number): number
8941 return n * 10
8942 enddef
8943 endclass
8944
8945 var a = A.new()
8946 assert_equal(200, a.Cb(20))
8947 END
8948 v9.CheckSourceSuccess(lines)
8949enddef
8950
8951" Test for using a class member as a funcref
8952def Test_class_member_funcref()
8953 # Using a funcref class variable in a class method
8954 var lines =<< trim END
8955 vim9script
8956 def Foo(n: number): number
8957 return n * 10
8958 enddef
8959
8960 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008961 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008962 static def Bar()
8963 assert_equal(200, Cb(20))
8964 enddef
8965 endclass
8966
8967 A.Bar()
8968 END
8969 v9.CheckSourceSuccess(lines)
8970
8971 # Using a funcref class variable in a def method
8972 lines =<< trim END
8973 vim9script
8974 def Foo(n: number): number
8975 return n * 10
8976 enddef
8977
8978 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008979 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008980 endclass
8981
8982 def Bar()
8983 assert_equal(200, A.Cb(20))
8984 enddef
8985 Bar()
8986 END
8987 v9.CheckSourceSuccess(lines)
8988
8989 # Using a funcref class variable at script level
8990 lines =<< trim END
8991 vim9script
8992 def Foo(n: number): number
8993 return n * 10
8994 enddef
8995
8996 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008997 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008998 endclass
8999
9000 assert_equal(200, A.Cb(20))
9001 END
9002 v9.CheckSourceSuccess(lines)
9003
9004 # Using a funcref class variable pointing to a class method in a class
9005 # method.
9006 lines =<< trim END
9007 vim9script
9008 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009009 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009010 static def Foo(n: number): number
9011 return n * 10
9012 enddef
9013 static def Init()
9014 Cb = Foo
9015 enddef
9016 static def Bar()
9017 assert_equal(200, Cb(20))
9018 enddef
9019 endclass
9020
9021 A.Init()
9022 A.Bar()
9023 END
9024 v9.CheckSourceSuccess(lines)
9025
9026 # Using a funcref class variable pointing to a class method in a def method.
9027 lines =<< trim END
9028 vim9script
9029 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009030 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009031 static def Foo(n: number): number
9032 return n * 10
9033 enddef
9034 static def Init()
9035 Cb = Foo
9036 enddef
9037 endclass
9038
9039 def Bar()
9040 A.Init()
9041 assert_equal(200, A.Cb(20))
9042 enddef
9043 Bar()
9044 END
9045 v9.CheckSourceSuccess(lines)
9046
9047 # Using a funcref class variable pointing to a class method at script level.
9048 lines =<< trim END
9049 vim9script
9050 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009051 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02009052 static def Foo(n: number): number
9053 return n * 10
9054 enddef
9055 static def Init()
9056 Cb = Foo
9057 enddef
9058 endclass
9059
9060 A.Init()
9061 assert_equal(200, A.Cb(20))
9062 END
9063 v9.CheckSourceSuccess(lines)
9064enddef
9065
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009066" Test for using object methods as popup callback functions
9067def Test_objmethod_popup_callback()
9068 # Use the popup from the script level
9069 var lines =<< trim END
9070 vim9script
9071
9072 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009073 var selection: number = -1
9074 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009075
9076 def PopupFilter(id: number, key: string): bool
9077 add(this.filterkeys, key)
9078 return popup_filter_yesno(id, key)
9079 enddef
9080
9081 def PopupCb(id: number, result: number)
9082 this.selection = result ? 100 : 200
9083 enddef
9084 endclass
9085
9086 var a = A.new()
9087 feedkeys('', 'xt')
9088 var winid = popup_create('Y/N?',
9089 {filter: a.PopupFilter, callback: a.PopupCb})
9090 feedkeys('y', 'xt')
9091 popup_close(winid)
9092 assert_equal(100, a.selection)
9093 assert_equal(['y'], a.filterkeys)
9094 feedkeys('', 'xt')
9095 winid = popup_create('Y/N?',
9096 {filter: a.PopupFilter, callback: a.PopupCb})
9097 feedkeys('n', 'xt')
9098 popup_close(winid)
9099 assert_equal(200, a.selection)
9100 assert_equal(['y', 'n'], a.filterkeys)
9101 END
9102 v9.CheckSourceSuccess(lines)
9103
9104 # Use the popup from a def function
9105 lines =<< trim END
9106 vim9script
9107
9108 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009109 var selection: number = -1
9110 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009111
9112 def PopupFilter(id: number, key: string): bool
9113 add(this.filterkeys, key)
9114 return popup_filter_yesno(id, key)
9115 enddef
9116
9117 def PopupCb(id: number, result: number)
9118 this.selection = result ? 100 : 200
9119 enddef
9120 endclass
9121
9122 def Foo()
9123 var a = A.new()
9124 feedkeys('', 'xt')
9125 var winid = popup_create('Y/N?',
9126 {filter: a.PopupFilter, callback: a.PopupCb})
9127 feedkeys('y', 'xt')
9128 popup_close(winid)
9129 assert_equal(100, a.selection)
9130 assert_equal(['y'], a.filterkeys)
9131 feedkeys('', 'xt')
9132 winid = popup_create('Y/N?',
9133 {filter: a.PopupFilter, callback: a.PopupCb})
9134 feedkeys('n', 'xt')
9135 popup_close(winid)
9136 assert_equal(200, a.selection)
9137 assert_equal(['y', 'n'], a.filterkeys)
9138 enddef
9139 Foo()
9140 END
9141 v9.CheckSourceSuccess(lines)
9142enddef
9143
9144" Test for using class methods as popup callback functions
9145def Test_classmethod_popup_callback()
9146 # Use the popup from the script level
9147 var lines =<< trim END
9148 vim9script
9149
9150 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009151 static var selection: number = -1
9152 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009153
9154 static def PopupFilter(id: number, key: string): bool
9155 add(filterkeys, key)
9156 return popup_filter_yesno(id, key)
9157 enddef
9158
9159 static def PopupCb(id: number, result: number)
9160 selection = result ? 100 : 200
9161 enddef
9162 endclass
9163
9164 feedkeys('', 'xt')
9165 var winid = popup_create('Y/N?',
9166 {filter: A.PopupFilter, callback: A.PopupCb})
9167 feedkeys('y', 'xt')
9168 popup_close(winid)
9169 assert_equal(100, A.selection)
9170 assert_equal(['y'], A.filterkeys)
9171 feedkeys('', 'xt')
9172 winid = popup_create('Y/N?',
9173 {filter: A.PopupFilter, callback: A.PopupCb})
9174 feedkeys('n', 'xt')
9175 popup_close(winid)
9176 assert_equal(200, A.selection)
9177 assert_equal(['y', 'n'], A.filterkeys)
9178 END
9179 v9.CheckSourceSuccess(lines)
9180
9181 # Use the popup from a def function
9182 lines =<< trim END
9183 vim9script
9184
9185 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009186 static var selection: number = -1
9187 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009188
9189 static def PopupFilter(id: number, key: string): bool
9190 add(filterkeys, key)
9191 return popup_filter_yesno(id, key)
9192 enddef
9193
9194 static def PopupCb(id: number, result: number)
9195 selection = result ? 100 : 200
9196 enddef
9197 endclass
9198
9199 def Foo()
9200 feedkeys('', 'xt')
9201 var winid = popup_create('Y/N?',
9202 {filter: A.PopupFilter, callback: A.PopupCb})
9203 feedkeys('y', 'xt')
9204 popup_close(winid)
9205 assert_equal(100, A.selection)
9206 assert_equal(['y'], A.filterkeys)
9207 feedkeys('', 'xt')
9208 winid = popup_create('Y/N?',
9209 {filter: A.PopupFilter, callback: A.PopupCb})
9210 feedkeys('n', 'xt')
9211 popup_close(winid)
9212 assert_equal(200, A.selection)
9213 assert_equal(['y', 'n'], A.filterkeys)
9214 enddef
9215 Foo()
9216 END
9217 v9.CheckSourceSuccess(lines)
9218enddef
9219
9220" Test for using an object method as a timer callback function
9221def Test_objmethod_timer_callback()
9222 # Use the timer callback from script level
9223 var lines =<< trim END
9224 vim9script
9225
9226 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009227 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009228 def TimerCb(timerID: number)
9229 this.timerTick = 6
9230 enddef
9231 endclass
9232
9233 var a = A.new()
9234 timer_start(0, a.TimerCb)
9235 var maxWait = 5
9236 while maxWait > 0 && a.timerTick == -1
9237 :sleep 10m
9238 maxWait -= 1
9239 endwhile
9240 assert_equal(6, a.timerTick)
9241 END
9242 v9.CheckSourceSuccess(lines)
9243
9244 # Use the timer callback from a def function
9245 lines =<< trim END
9246 vim9script
9247
9248 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009249 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009250 def TimerCb(timerID: number)
9251 this.timerTick = 6
9252 enddef
9253 endclass
9254
9255 def Foo()
9256 var a = A.new()
9257 timer_start(0, a.TimerCb)
9258 var maxWait = 5
9259 while maxWait > 0 && a.timerTick == -1
9260 :sleep 10m
9261 maxWait -= 1
9262 endwhile
9263 assert_equal(6, a.timerTick)
9264 enddef
9265 Foo()
9266 END
9267 v9.CheckSourceSuccess(lines)
9268enddef
9269
9270" Test for using a class method as a timer callback function
9271def Test_classmethod_timer_callback()
9272 # Use the timer callback from script level
9273 var lines =<< trim END
9274 vim9script
9275
9276 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009277 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009278 static def TimerCb(timerID: number)
9279 timerTick = 6
9280 enddef
9281 endclass
9282
9283 timer_start(0, A.TimerCb)
9284 var maxWait = 5
9285 while maxWait > 0 && A.timerTick == -1
9286 :sleep 10m
9287 maxWait -= 1
9288 endwhile
9289 assert_equal(6, A.timerTick)
9290 END
9291 v9.CheckSourceSuccess(lines)
9292
9293 # Use the timer callback from a def function
9294 lines =<< trim END
9295 vim9script
9296
9297 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009298 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02009299 static def TimerCb(timerID: number)
9300 timerTick = 6
9301 enddef
9302 endclass
9303
9304 def Foo()
9305 timer_start(0, A.TimerCb)
9306 var maxWait = 5
9307 while maxWait > 0 && A.timerTick == -1
9308 :sleep 10m
9309 maxWait -= 1
9310 endwhile
9311 assert_equal(6, A.timerTick)
9312 enddef
9313 Foo()
9314 END
9315 v9.CheckSourceSuccess(lines)
9316enddef
9317
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009318" Test for using a class variable as the first and/or second operand of a binary
9319" operator.
9320def Test_class_variable_as_operands()
9321 var lines =<< trim END
9322 vim9script
9323 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01009324 static var truthy: bool = true
9325 public static var TruthyFn: func
9326 static var list: list<any> = []
9327 static var four: number = 4
9328 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009329
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009330 static def Str(): string
9331 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009332 enddef
9333
9334 static def Four(): number
9335 return four
9336 enddef
9337
9338 static def List(): list<any>
9339 return list
9340 enddef
9341
9342 static def Truthy(): bool
9343 return truthy
9344 enddef
9345
9346 def TestOps()
9347 assert_true(Tests.truthy == truthy)
9348 assert_true(truthy == Tests.truthy)
9349 assert_true(Tests.list isnot [])
9350 assert_true([] isnot Tests.list)
9351 assert_equal(2, Tests.four >> 1)
9352 assert_equal(16, 1 << Tests.four)
9353 assert_equal(8, Tests.four + four)
9354 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009355 assert_equal('hellohello', Tests.str .. str)
9356 assert_equal('hellohello', str .. Tests.str)
9357
9358 # Using class variable for list indexing
9359 var l = range(10)
9360 assert_equal(4, l[Tests.four])
9361 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9362
9363 # Using class variable for Dict key
9364 var d = {hello: 'abc'}
9365 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009366 enddef
9367 endclass
9368
9369 def TestOps2()
9370 assert_true(Tests.truthy == Tests.Truthy())
9371 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009372 assert_true(Tests.truthy == Tests.TruthyFn())
9373 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009374 assert_true(Tests.list is Tests.List())
9375 assert_true(Tests.List() is Tests.list)
9376 assert_equal(2, Tests.four >> 1)
9377 assert_equal(16, 1 << Tests.four)
9378 assert_equal(8, Tests.four + Tests.Four())
9379 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009380 assert_equal('hellohello', Tests.str .. Tests.Str())
9381 assert_equal('hellohello', Tests.Str() .. Tests.str)
9382
9383 # Using class variable for list indexing
9384 var l = range(10)
9385 assert_equal(4, l[Tests.four])
9386 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9387
9388 # Using class variable for Dict key
9389 var d = {hello: 'abc'}
9390 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009391 enddef
9392
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009393 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009394 var t = Tests.new()
9395 t.TestOps()
9396 TestOps2()
9397
9398 assert_true(Tests.truthy == Tests.Truthy())
9399 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02009400 assert_true(Tests.truthy == Tests.TruthyFn())
9401 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009402 assert_true(Tests.list is Tests.List())
9403 assert_true(Tests.List() is Tests.list)
9404 assert_equal(2, Tests.four >> 1)
9405 assert_equal(16, 1 << Tests.four)
9406 assert_equal(8, Tests.four + Tests.Four())
9407 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02009408 assert_equal('hellohello', Tests.str .. Tests.Str())
9409 assert_equal('hellohello', Tests.Str() .. Tests.str)
9410
9411 # Using class variable for list indexing
9412 var l = range(10)
9413 assert_equal(4, l[Tests.four])
9414 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
9415
9416 # Using class variable for Dict key
9417 var d = {hello: 'abc'}
9418 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02009419 END
9420 v9.CheckSourceSuccess(lines)
9421enddef
9422
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009423" Test for checking the type of the key used to access an object dict member.
9424def Test_dict_member_key_type_check()
9425 var lines =<< trim END
9426 vim9script
9427
9428 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01009429 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009430 endclass
9431
9432 class Test extends State
9433 def ObjMethodTests()
9434 var cursor: number = 0
9435 var z: number = 0
9436 [this.numbers[cursor]] = ['zero.1']
9437 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9438 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9439 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9440 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9441 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9442 [this.numbers[cursor], z] = ['zero.4', 1]
9443 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9444 [z, this.numbers[cursor]] = [1, 'zero.5']
9445 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9446 enddef
9447
9448 static def ClassMethodTests(that: State)
9449 var cursor: number = 0
9450 var z: number = 0
9451 [that.numbers[cursor]] = ['zero.1']
9452 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9453 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9454 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9455 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9456 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9457 [that.numbers[cursor], z] = ['zero.4', 1]
9458 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9459 [z, that.numbers[cursor]] = [1, 'zero.5']
9460 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9461 enddef
9462
9463 def new()
9464 enddef
9465
9466 def newMethodTests()
9467 var cursor: number = 0
9468 var z: number
9469 [this.numbers[cursor]] = ['zero.1']
9470 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
9471 [this.numbers[string(cursor)], z] = ['zero.2', 1]
9472 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
9473 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
9474 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
9475 [this.numbers[cursor], z] = ['zero.4', 1]
9476 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
9477 [z, this.numbers[cursor]] = [1, 'zero.5']
9478 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
9479 enddef
9480 endclass
9481
9482 def DefFuncTests(that: Test)
9483 var cursor: number = 0
9484 var z: number
9485 [that.numbers[cursor]] = ['zero.1']
9486 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
9487 [that.numbers[string(cursor)], z] = ['zero.2', 1]
9488 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
9489 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
9490 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
9491 [that.numbers[cursor], z] = ['zero.4', 1]
9492 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
9493 [z, that.numbers[cursor]] = [1, 'zero.5']
9494 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
9495 enddef
9496
9497 Test.newMethodTests()
9498 Test.new().ObjMethodTests()
9499 Test.ClassMethodTests(Test.new())
9500 DefFuncTests(Test.new())
9501
9502 const test: Test = Test.new()
9503 var cursor: number = 0
9504 [test.numbers[cursor], cursor] = ['zero', 1]
9505 [cursor, test.numbers[cursor]] = [1, 'one']
9506 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
9507 END
9508 v9.CheckSourceSuccess(lines)
9509
9510 lines =<< trim END
9511 vim9script
9512
9513 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009514 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009515
9516 def new()
9517 enddef
9518
9519 def Foo()
9520 var z: number
9521 [this.numbers.a, z] = [{}, 10]
9522 enddef
9523 endclass
9524
9525 var a = A.new()
9526 a.Foo()
9527 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009528 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009529
9530 lines =<< trim END
9531 vim9script
9532
9533 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01009534 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009535
9536 def new()
9537 enddef
9538
9539 def Foo()
9540 var x: string = 'a'
9541 var y: number
9542 [this.numbers[x], y] = [{}, 10]
9543 enddef
9544 endclass
9545
9546 var a = A.new()
9547 a.Foo()
9548 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009549 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009550enddef
9551
mityua5550692023-11-25 15:41:20 +01009552def Test_compile_many_def_functions_in_funcref_instr()
9553 # This used to crash Vim. This is reproducible only when run on new instance
9554 # of Vim.
9555 var lines =<< trim END
9556 vim9script
9557
9558 class A
9559 def new()
9560 this.TakeFunc(this.F00)
9561 enddef
9562
9563 def TakeFunc(F: func)
9564 enddef
9565
9566 def F00()
9567 this.F01()
9568 this.F02()
9569 this.F03()
9570 this.F04()
9571 this.F05()
9572 this.F06()
9573 this.F07()
9574 this.F08()
9575 this.F09()
9576 this.F10()
9577 this.F11()
9578 this.F12()
9579 this.F13()
9580 this.F14()
9581 this.F15()
9582 this.F16()
9583 this.F17()
9584 this.F18()
9585 this.F19()
9586 this.F20()
9587 this.F21()
9588 this.F22()
9589 this.F23()
9590 this.F24()
9591 this.F25()
9592 this.F26()
9593 this.F27()
9594 this.F28()
9595 this.F29()
9596 this.F30()
9597 this.F31()
9598 this.F32()
9599 this.F33()
9600 this.F34()
9601 this.F35()
9602 this.F36()
9603 this.F37()
9604 this.F38()
9605 this.F39()
9606 this.F40()
9607 this.F41()
9608 this.F42()
9609 this.F43()
9610 this.F44()
9611 this.F45()
9612 this.F46()
9613 this.F47()
9614 enddef
9615
9616 def F01()
9617 enddef
9618 def F02()
9619 enddef
9620 def F03()
9621 enddef
9622 def F04()
9623 enddef
9624 def F05()
9625 enddef
9626 def F06()
9627 enddef
9628 def F07()
9629 enddef
9630 def F08()
9631 enddef
9632 def F09()
9633 enddef
9634 def F10()
9635 enddef
9636 def F11()
9637 enddef
9638 def F12()
9639 enddef
9640 def F13()
9641 enddef
9642 def F14()
9643 enddef
9644 def F15()
9645 enddef
9646 def F16()
9647 enddef
9648 def F17()
9649 enddef
9650 def F18()
9651 enddef
9652 def F19()
9653 enddef
9654 def F20()
9655 enddef
9656 def F21()
9657 enddef
9658 def F22()
9659 enddef
9660 def F23()
9661 enddef
9662 def F24()
9663 enddef
9664 def F25()
9665 enddef
9666 def F26()
9667 enddef
9668 def F27()
9669 enddef
9670 def F28()
9671 enddef
9672 def F29()
9673 enddef
9674 def F30()
9675 enddef
9676 def F31()
9677 enddef
9678 def F32()
9679 enddef
9680 def F33()
9681 enddef
9682 def F34()
9683 enddef
9684 def F35()
9685 enddef
9686 def F36()
9687 enddef
9688 def F37()
9689 enddef
9690 def F38()
9691 enddef
9692 def F39()
9693 enddef
9694 def F40()
9695 enddef
9696 def F41()
9697 enddef
9698 def F42()
9699 enddef
9700 def F43()
9701 enddef
9702 def F44()
9703 enddef
9704 def F45()
9705 enddef
9706 def F46()
9707 enddef
9708 def F47()
9709 enddef
9710 endclass
9711
9712 A.new()
9713 END
9714 writefile(lines, 'Xscript', 'D')
9715 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9716 assert_equal(0, v:shell_error)
9717enddef
9718
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009719" Test for 'final' class and object variables
9720def Test_final_class_object_variable()
9721 # Test for changing a final object variable from an object function
9722 var lines =<< trim END
9723 vim9script
9724 class A
9725 final foo: string = "abc"
9726 def Foo()
9727 this.foo = "def"
9728 enddef
9729 endclass
9730 defcompile A.Foo
9731 END
9732 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9733
9734 # Test for changing a final object variable from the 'new' function
9735 lines =<< trim END
9736 vim9script
9737 class A
9738 final s1: string
9739 final s2: string
9740 def new(this.s1)
9741 this.s2 = 'def'
9742 enddef
9743 endclass
9744 var a = A.new('abc')
9745 assert_equal('abc', a.s1)
9746 assert_equal('def', a.s2)
9747 END
9748 v9.CheckSourceSuccess(lines)
9749
9750 # Test for a final class variable
9751 lines =<< trim END
9752 vim9script
9753 class A
9754 static final s1: string = "abc"
9755 endclass
9756 assert_equal('abc', A.s1)
9757 END
9758 v9.CheckSourceSuccess(lines)
9759
9760 # Test for changing a final class variable from a class function
9761 lines =<< trim END
9762 vim9script
9763 class A
9764 static final s1: string = "abc"
9765 static def Foo()
9766 s1 = "def"
9767 enddef
9768 endclass
9769 A.Foo()
9770 END
9771 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9772
9773 # Test for changing a public final class variable at script level
9774 lines =<< trim END
9775 vim9script
9776 class A
9777 public static final s1: string = "abc"
9778 endclass
9779 assert_equal('abc', A.s1)
9780 A.s1 = 'def'
9781 END
9782 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9783
9784 # Test for changing a public final class variable from a class function
9785 lines =<< trim END
9786 vim9script
9787 class A
9788 public static final s1: string = "abc"
9789 static def Foo()
9790 s1 = "def"
9791 enddef
9792 endclass
9793 A.Foo()
9794 END
9795 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9796
9797 # Test for changing a public final class variable from a function
9798 lines =<< trim END
9799 vim9script
9800 class A
9801 public static final s1: string = "abc"
9802 endclass
9803 def Foo()
9804 A.s1 = 'def'
9805 enddef
9806 defcompile
9807 END
9808 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9809
9810 # Test for using a final variable of composite type
9811 lines =<< trim END
9812 vim9script
9813 class A
9814 public final l: list<number>
9815 def new()
9816 this.l = [1, 2]
9817 enddef
9818 def Foo()
9819 this.l[0] = 3
9820 this.l->add(4)
9821 enddef
9822 endclass
9823 var a = A.new()
9824 assert_equal([1, 2], a.l)
9825 a.Foo()
9826 assert_equal([3, 2, 4], a.l)
9827 END
9828 v9.CheckSourceSuccess(lines)
9829
9830 # Test for changing a final variable of composite type from another object
9831 # function
9832 lines =<< trim END
9833 vim9script
9834 class A
9835 public final l: list<number> = [1, 2]
9836 def Foo()
9837 this.l = [3, 4]
9838 enddef
9839 endclass
9840 var a = A.new()
9841 a.Foo()
9842 END
9843 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9844
9845 # Test for modifying a final variable of composite type at script level
9846 lines =<< trim END
9847 vim9script
9848 class A
9849 public final l: list<number> = [1, 2]
9850 endclass
9851 var a = A.new()
9852 a.l[0] = 3
9853 a.l->add(4)
9854 assert_equal([3, 2, 4], a.l)
9855 END
9856 v9.CheckSourceSuccess(lines)
9857
9858 # Test for modifying a final variable of composite type from a function
9859 lines =<< trim END
9860 vim9script
9861 class A
9862 public final l: list<number> = [1, 2]
9863 endclass
9864 def Foo()
9865 var a = A.new()
9866 a.l[0] = 3
9867 a.l->add(4)
9868 assert_equal([3, 2, 4], a.l)
9869 enddef
9870 Foo()
9871 END
9872 v9.CheckSourceSuccess(lines)
9873
9874 # Test for modifying a final variable of composite type from another object
9875 # function
9876 lines =<< trim END
9877 vim9script
9878 class A
9879 public final l: list<number> = [1, 2]
9880 def Foo()
9881 this.l[0] = 3
9882 this.l->add(4)
9883 enddef
9884 endclass
9885 var a = A.new()
9886 a.Foo()
9887 assert_equal([3, 2, 4], a.l)
9888 END
9889 v9.CheckSourceSuccess(lines)
9890
9891 # Test for assigning a new value to a final variable of composite type at
9892 # script level
9893 lines =<< trim END
9894 vim9script
9895 class A
9896 public final l: list<number> = [1, 2]
9897 endclass
9898 var a = A.new()
9899 a.l = [3, 4]
9900 END
9901 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9902
9903 # Test for assigning a new value to a final variable of composite type from
9904 # another object function
9905 lines =<< trim END
9906 vim9script
9907 class A
9908 public final l: list<number> = [1, 2]
9909 def Foo()
9910 this.l = [3, 4]
9911 enddef
9912 endclass
9913 var a = A.new()
9914 a.Foo()
9915 END
9916 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9917
9918 # Test for assigning a new value to a final variable of composite type from
9919 # another function
9920 lines =<< trim END
9921 vim9script
9922 class A
9923 public final l: list<number> = [1, 2]
9924 endclass
9925 def Foo()
9926 var a = A.new()
9927 a.l = [3, 4]
9928 enddef
9929 Foo()
9930 END
9931 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9932
9933 # Error case: Use 'final' with just a variable name
9934 lines =<< trim END
9935 vim9script
9936 class A
9937 final foo
9938 endclass
9939 var a = A.new()
9940 END
9941 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9942
9943 # Error case: Use 'final' followed by 'public'
9944 lines =<< trim END
9945 vim9script
9946 class A
9947 final public foo: number
9948 endclass
9949 var a = A.new()
9950 END
9951 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9952
9953 # Error case: Use 'final' followed by 'static'
9954 lines =<< trim END
9955 vim9script
9956 class A
9957 final static foo: number
9958 endclass
9959 var a = A.new()
9960 END
9961 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9962
9963 # Error case: 'final' cannot be used in an interface
9964 lines =<< trim END
9965 vim9script
9966 interface A
9967 final foo: number = 10
9968 endinterface
9969 END
9970 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9971
9972 # Error case: 'final' not supported for an object method
9973 lines =<< trim END
9974 vim9script
9975 class A
9976 final def Foo()
9977 enddef
9978 endclass
9979 END
9980 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9981
9982 # Error case: 'final' not supported for a class method
9983 lines =<< trim END
9984 vim9script
9985 class A
9986 static final def Foo()
9987 enddef
9988 endclass
9989 END
9990 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9991enddef
9992
9993" Test for 'const' class and object variables
9994def Test_const_class_object_variable()
9995 # Test for changing a const object variable from an object function
9996 var lines =<< trim END
9997 vim9script
9998 class A
9999 const foo: string = "abc"
10000 def Foo()
10001 this.foo = "def"
10002 enddef
10003 endclass
10004 defcompile A.Foo
10005 END
10006 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
10007
10008 # Test for changing a const object variable from the 'new' function
10009 lines =<< trim END
10010 vim9script
10011 class A
10012 const s1: string
10013 const s2: string
10014 def new(this.s1)
10015 this.s2 = 'def'
10016 enddef
10017 endclass
10018 var a = A.new('abc')
10019 assert_equal('abc', a.s1)
10020 assert_equal('def', a.s2)
10021 END
10022 v9.CheckSourceSuccess(lines)
10023
10024 # Test for changing a const object variable from an object method called from
10025 # the 'new' function
10026 lines =<< trim END
10027 vim9script
10028 class A
10029 const s1: string = 'abc'
10030 def new()
10031 this.ChangeStr()
10032 enddef
10033 def ChangeStr()
10034 this.s1 = 'def'
10035 enddef
10036 endclass
10037 var a = A.new()
10038 END
10039 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10040
10041 # Test for a const class variable
10042 lines =<< trim END
10043 vim9script
10044 class A
10045 static const s1: string = "abc"
10046 endclass
10047 assert_equal('abc', A.s1)
10048 END
10049 v9.CheckSourceSuccess(lines)
10050
10051 # Test for changing a const class variable from a class function
10052 lines =<< trim END
10053 vim9script
10054 class A
10055 static const s1: string = "abc"
10056 static def Foo()
10057 s1 = "def"
10058 enddef
10059 endclass
10060 A.Foo()
10061 END
10062 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10063
10064 # Test for changing a public const class variable at script level
10065 lines =<< trim END
10066 vim9script
10067 class A
10068 public static const s1: string = "abc"
10069 endclass
10070 assert_equal('abc', A.s1)
10071 A.s1 = 'def'
10072 END
10073 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
10074
10075 # Test for changing a public const class variable from a class function
10076 lines =<< trim END
10077 vim9script
10078 class A
10079 public static const s1: string = "abc"
10080 static def Foo()
10081 s1 = "def"
10082 enddef
10083 endclass
10084 A.Foo()
10085 END
10086 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10087
10088 # Test for changing a public const class variable from a function
10089 lines =<< trim END
10090 vim9script
10091 class A
10092 public static const s1: string = "abc"
10093 endclass
10094 def Foo()
10095 A.s1 = 'def'
10096 enddef
10097 defcompile
10098 END
10099 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
10100
10101 # Test for changing a const List item from an object function
10102 lines =<< trim END
10103 vim9script
10104 class A
10105 public const l: list<number>
10106 def new()
10107 this.l = [1, 2]
10108 enddef
10109 def Foo()
10110 this.l[0] = 3
10111 enddef
10112 endclass
10113 var a = A.new()
10114 assert_equal([1, 2], a.l)
10115 a.Foo()
10116 END
10117 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
10118
10119 # Test for adding a value to a const List from an object function
10120 lines =<< trim END
10121 vim9script
10122 class A
10123 public const l: list<number>
10124 def new()
10125 this.l = [1, 2]
10126 enddef
10127 def Foo()
10128 this.l->add(3)
10129 enddef
10130 endclass
10131 var a = A.new()
10132 a.Foo()
10133 END
10134 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
10135
10136 # Test for reassigning a const List from an object function
10137 lines =<< trim END
10138 vim9script
10139 class A
10140 public const l: list<number> = [1, 2]
10141 def Foo()
10142 this.l = [3, 4]
10143 enddef
10144 endclass
10145 var a = A.new()
10146 a.Foo()
10147 END
10148 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10149
10150 # Test for changing a const List item at script level
10151 lines =<< trim END
10152 vim9script
10153 class A
10154 public const l: list<number> = [1, 2]
10155 endclass
10156 var a = A.new()
10157 a.l[0] = 3
10158 END
10159 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
10160
10161 # Test for adding a value to a const List item at script level
10162 lines =<< trim END
10163 vim9script
10164 class A
10165 public const l: list<number> = [1, 2]
10166 endclass
10167 var a = A.new()
10168 a.l->add(4)
10169 END
10170 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
10171
10172 # Test for changing a const List item from a function
10173 lines =<< trim END
10174 vim9script
10175 class A
10176 public const l: list<number> = [1, 2]
10177 endclass
10178 def Foo()
10179 var a = A.new()
10180 a.l[0] = 3
10181 enddef
10182 Foo()
10183 END
10184 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
10185
10186 # Test for adding a value to a const List item from a function
10187 lines =<< trim END
10188 vim9script
10189 class A
10190 public const l: list<number> = [1, 2]
10191 endclass
10192 def Foo()
10193 var a = A.new()
10194 a.l->add(4)
10195 enddef
10196 Foo()
10197 END
10198 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
10199
10200 # Test for changing a const List item from an object method
10201 lines =<< trim END
10202 vim9script
10203 class A
10204 public const l: list<number> = [1, 2]
10205 def Foo()
10206 this.l[0] = 3
10207 enddef
10208 endclass
10209 var a = A.new()
10210 a.Foo()
10211 END
10212 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
10213
10214 # Test for adding a value to a const List item from an object method
10215 lines =<< trim END
10216 vim9script
10217 class A
10218 public const l: list<number> = [1, 2]
10219 def Foo()
10220 this.l->add(4)
10221 enddef
10222 endclass
10223 var a = A.new()
10224 a.Foo()
10225 END
10226 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
10227
10228 # Test for reassigning a const List object variable at script level
10229 lines =<< trim END
10230 vim9script
10231 class A
10232 public const l: list<number> = [1, 2]
10233 endclass
10234 var a = A.new()
10235 a.l = [3, 4]
10236 END
10237 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
10238
10239 # Test for reassigning a const List object variable from an object method
10240 lines =<< trim END
10241 vim9script
10242 class A
10243 public const l: list<number> = [1, 2]
10244 def Foo()
10245 this.l = [3, 4]
10246 enddef
10247 endclass
10248 var a = A.new()
10249 a.Foo()
10250 END
10251 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
10252
10253 # Test for reassigning a const List object variable from another function
10254 lines =<< trim END
10255 vim9script
10256 class A
10257 public const l: list<number> = [1, 2]
10258 endclass
10259 def Foo()
10260 var a = A.new()
10261 a.l = [3, 4]
10262 enddef
10263 Foo()
10264 END
10265 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
10266
10267 # Error case: Use 'const' with just a variable name
10268 lines =<< trim END
10269 vim9script
10270 class A
10271 const foo
10272 endclass
10273 var a = A.new()
10274 END
10275 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10276
10277 # Error case: Use 'const' followed by 'public'
10278 lines =<< trim END
10279 vim9script
10280 class A
10281 const public foo: number
10282 endclass
10283 var a = A.new()
10284 END
10285 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10286
10287 # Error case: Use 'const' followed by 'static'
10288 lines =<< trim END
10289 vim9script
10290 class A
10291 const static foo: number
10292 endclass
10293 var a = A.new()
10294 END
10295 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10296
10297 # Error case: 'const' cannot be used in an interface
10298 lines =<< trim END
10299 vim9script
10300 interface A
10301 const foo: number = 10
10302 endinterface
10303 END
10304 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
10305
10306 # Error case: 'const' not supported for an object method
10307 lines =<< trim END
10308 vim9script
10309 class A
10310 const def Foo()
10311 enddef
10312 endclass
10313 END
10314 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10315
10316 # Error case: 'const' not supported for a class method
10317 lines =<< trim END
10318 vim9script
10319 class A
10320 static const def Foo()
10321 enddef
10322 endclass
10323 END
10324 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
10325enddef
10326
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +010010327" Test for compiling class/object methods using :defcompile
10328def Test_defcompile_class()
10329 # defcompile all the classes in the current script
10330 var lines =<< trim END
10331 vim9script
10332 class A
10333 def Foo()
10334 var i = 10
10335 enddef
10336 endclass
10337 class B
10338 def Bar()
10339 var i = 20
10340 xxx
10341 enddef
10342 endclass
10343 defcompile
10344 END
10345 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
10346
10347 # defcompile a specific class
10348 lines =<< trim END
10349 vim9script
10350 class A
10351 def Foo()
10352 xxx
10353 enddef
10354 endclass
10355 class B
10356 def Bar()
10357 yyy
10358 enddef
10359 endclass
10360 defcompile B
10361 END
10362 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
10363
10364 # defcompile a non-class
10365 lines =<< trim END
10366 vim9script
10367 class A
10368 def Foo()
10369 enddef
10370 endclass
10371 var X: list<number> = []
10372 defcompile X
10373 END
10374 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
10375
10376 # defcompile a class twice
10377 lines =<< trim END
10378 vim9script
10379 class A
10380 def new()
10381 enddef
10382 endclass
10383 defcompile A
10384 defcompile A
10385 assert_equal('Function A.new does not need compiling', v:statusmsg)
10386 END
10387 v9.CheckSourceSuccess(lines)
10388
10389 # defcompile should not compile an imported class
10390 lines =<< trim END
10391 vim9script
10392 export class A
10393 def Foo()
10394 xxx
10395 enddef
10396 endclass
10397 END
10398 writefile(lines, 'Xdefcompileimport.vim', 'D')
10399 lines =<< trim END
10400 vim9script
10401
10402 import './Xdefcompileimport.vim'
10403 class B
10404 endclass
10405 defcompile
10406 END
10407 v9.CheckScriptSuccess(lines)
10408enddef
10409
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +010010410" Test for cases common to all the object builtin methods
10411def Test_object_builtin_method()
10412 var lines =<< trim END
10413 vim9script
10414 class A
10415 def abc()
10416 enddef
10417 endclass
10418 END
10419 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
10420
10421 for funcname in ["len", "string", "empty"]
10422 lines =<< trim eval END
10423 vim9script
10424 class A
10425 static def {funcname}(): number
10426 enddef
10427 endclass
10428 END
10429 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
10430 endfor
10431enddef
10432
10433" Test for using the empty() builtin method with an object
10434" This is a legacy function to use the test_garbagecollect_now() function.
10435func Test_object_empty()
10436 let lines =<< trim END
10437 vim9script
10438 class A
10439 def empty(): bool
10440 return true
10441 enddef
10442 endclass
10443
10444 def Foo()
10445 var afoo = A.new()
10446 assert_equal(true, empty(afoo))
10447 assert_equal(true, afoo->empty())
10448 enddef
10449
10450 var a = A.new()
10451 assert_equal(1, empty(a))
10452 assert_equal(1, a->empty())
10453 test_garbagecollect_now()
10454 assert_equal(1, empty(a))
10455 Foo()
10456 test_garbagecollect_now()
10457 Foo()
10458 END
10459 call v9.CheckSourceSuccess(lines)
10460
10461 " empty() should return 1 without a builtin method
10462 let lines =<< trim END
10463 vim9script
10464 class A
10465 endclass
10466
10467 def Foo()
10468 var afoo = A.new()
10469 assert_equal(1, empty(afoo))
10470 enddef
10471
10472 var a = A.new()
10473 assert_equal(1, empty(a))
10474 Foo()
10475 END
10476 call v9.CheckSourceSuccess(lines)
10477
10478 " Unsupported signature for the empty() method
10479 let lines =<< trim END
10480 vim9script
10481 class A
10482 def empty()
10483 enddef
10484 endclass
10485 END
10486 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
10487
10488 " Error when calling the empty() method
10489 let lines =<< trim END
10490 vim9script
10491 class A
10492 def empty(): bool
10493 throw "Failed to check emptiness"
10494 enddef
10495 endclass
10496
10497 def Foo()
10498 var afoo = A.new()
10499 var i = empty(afoo)
10500 enddef
10501
10502 var a = A.new()
10503 assert_fails('empty(a)', 'Failed to check emptiness')
10504 assert_fails('Foo()', 'Failed to check emptiness')
10505 END
10506 call v9.CheckSourceSuccess(lines)
10507
10508 " call empty() using an object from a script
10509 let lines =<< trim END
10510 vim9script
10511 class A
10512 def empty(): bool
10513 return true
10514 enddef
10515 endclass
10516 var afoo = A.new()
10517 assert_equal(true, afoo.empty())
10518 END
10519 call v9.CheckSourceSuccess(lines)
10520
10521 " call empty() using an object from a method
10522 let lines =<< trim END
10523 vim9script
10524 class A
10525 def empty(): bool
10526 return true
10527 enddef
10528 endclass
10529 def Foo()
10530 var afoo = A.new()
10531 assert_equal(true, afoo.empty())
10532 enddef
10533 Foo()
10534 END
10535 call v9.CheckSourceSuccess(lines)
10536
10537 " call empty() using "this" from an object method
10538 let lines =<< trim END
10539 vim9script
10540 class A
10541 def empty(): bool
10542 return true
10543 enddef
10544 def Foo(): bool
10545 return this.empty()
10546 enddef
10547 endclass
10548 def Bar()
10549 var abar = A.new()
10550 assert_equal(true, abar.Foo())
10551 enddef
10552 Bar()
10553 END
10554 call v9.CheckSourceSuccess(lines)
10555
10556 " Call empty() from a derived object
10557 let lines =<< trim END
10558 vim9script
10559 class A
10560 def empty(): bool
10561 return false
10562 enddef
10563 endclass
10564 class B extends A
10565 def empty(): bool
10566 return true
10567 enddef
10568 endclass
10569 def Foo(afoo: A)
10570 assert_equal(true, empty(afoo))
10571 var bfoo = B.new()
10572 assert_equal(true, empty(bfoo))
10573 enddef
10574 var b = B.new()
10575 assert_equal(1, empty(b))
10576 Foo(b)
10577 END
10578 call v9.CheckSourceSuccess(lines)
10579
10580 " Invoking empty method using an interface
10581 let lines =<< trim END
10582 vim9script
10583 interface A
10584 def empty(): bool
10585 endinterface
10586 class B implements A
10587 def empty(): bool
10588 return false
10589 enddef
10590 endclass
10591 def Foo(a: A)
10592 assert_equal(false, empty(a))
10593 enddef
10594 var b = B.new()
10595 Foo(b)
10596 END
10597 call v9.CheckSourceSuccess(lines)
10598endfunc
10599
10600" Test for using the len() builtin method with an object
10601" This is a legacy function to use the test_garbagecollect_now() function.
10602func Test_object_length()
10603 let lines =<< trim END
10604 vim9script
10605 class A
10606 var mylen: number = 0
10607 def new(n: number)
10608 this.mylen = n
10609 enddef
10610 def len(): number
10611 return this.mylen
10612 enddef
10613 endclass
10614
10615 def Foo()
10616 var afoo = A.new(12)
10617 assert_equal(12, len(afoo))
10618 assert_equal(12, afoo->len())
10619 enddef
10620
10621 var a = A.new(22)
10622 assert_equal(22, len(a))
10623 assert_equal(22, a->len())
10624 test_garbagecollect_now()
10625 assert_equal(22, len(a))
10626 Foo()
10627 test_garbagecollect_now()
10628 Foo()
10629 END
10630 call v9.CheckSourceSuccess(lines)
10631
10632 " len() should return 0 without a builtin method
10633 let lines =<< trim END
10634 vim9script
10635 class A
10636 endclass
10637
10638 def Foo()
10639 var afoo = A.new()
10640 assert_equal(0, len(afoo))
10641 enddef
10642
10643 var a = A.new()
10644 assert_equal(0, len(a))
10645 Foo()
10646 END
10647 call v9.CheckSourceSuccess(lines)
10648
10649 " Unsupported signature for the len() method
10650 let lines =<< trim END
10651 vim9script
10652 class A
10653 def len()
10654 enddef
10655 endclass
10656 END
10657 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10658
10659 " Error when calling the len() method
10660 let lines =<< trim END
10661 vim9script
10662 class A
10663 def len(): number
10664 throw "Failed to compute length"
10665 enddef
10666 endclass
10667
10668 def Foo()
10669 var afoo = A.new()
10670 var i = len(afoo)
10671 enddef
10672
10673 var a = A.new()
10674 assert_fails('len(a)', 'Failed to compute length')
10675 assert_fails('Foo()', 'Failed to compute length')
10676 END
10677 call v9.CheckSourceSuccess(lines)
10678
10679 " call len() using an object from a script
10680 let lines =<< trim END
10681 vim9script
10682 class A
10683 def len(): number
10684 return 5
10685 enddef
10686 endclass
10687 var afoo = A.new()
10688 assert_equal(5, afoo.len())
10689 END
10690 call v9.CheckSourceSuccess(lines)
10691
10692 " call len() using an object from a method
10693 let lines =<< trim END
10694 vim9script
10695 class A
10696 def len(): number
10697 return 5
10698 enddef
10699 endclass
10700 def Foo()
10701 var afoo = A.new()
10702 assert_equal(5, afoo.len())
10703 enddef
10704 Foo()
10705 END
10706 call v9.CheckSourceSuccess(lines)
10707
10708 " call len() using "this" from an object method
10709 let lines =<< trim END
10710 vim9script
10711 class A
10712 def len(): number
10713 return 8
10714 enddef
10715 def Foo(): number
10716 return this.len()
10717 enddef
10718 endclass
10719 def Bar()
10720 var abar = A.new()
10721 assert_equal(8, abar.Foo())
10722 enddef
10723 Bar()
10724 END
10725 call v9.CheckSourceSuccess(lines)
10726
10727 " Call len() from a derived object
10728 let lines =<< trim END
10729 vim9script
10730 class A
10731 def len(): number
10732 return 10
10733 enddef
10734 endclass
10735 class B extends A
10736 def len(): number
10737 return 20
10738 enddef
10739 endclass
10740 def Foo(afoo: A)
10741 assert_equal(20, len(afoo))
10742 var bfoo = B.new()
10743 assert_equal(20, len(bfoo))
10744 enddef
10745 var b = B.new()
10746 assert_equal(20, len(b))
10747 Foo(b)
10748 END
10749 call v9.CheckSourceSuccess(lines)
10750
10751 " Invoking len method using an interface
10752 let lines =<< trim END
10753 vim9script
10754 interface A
10755 def len(): number
10756 endinterface
10757 class B implements A
10758 def len(): number
10759 return 123
10760 enddef
10761 endclass
10762 def Foo(a: A)
10763 assert_equal(123, len(a))
10764 enddef
10765 var b = B.new()
10766 Foo(b)
10767 END
10768 call v9.CheckSourceSuccess(lines)
10769endfunc
10770
10771" Test for using the string() builtin method with an object
10772" This is a legacy function to use the test_garbagecollect_now() function.
10773func Test_object_string()
10774 let lines =<< trim END
10775 vim9script
10776 class A
10777 var name: string
10778 def string(): string
10779 return this.name
10780 enddef
10781 endclass
10782
10783 def Foo()
10784 var afoo = A.new("foo-A")
10785 assert_equal('foo-A', string(afoo))
10786 assert_equal('foo-A', afoo->string())
10787 enddef
10788
10789 var a = A.new("script-A")
10790 assert_equal('script-A', string(a))
10791 assert_equal('script-A', a->string())
10792 assert_equal(['script-A'], execute('echo a')->split("\n"))
10793 test_garbagecollect_now()
10794 assert_equal('script-A', string(a))
10795 Foo()
10796 test_garbagecollect_now()
10797 Foo()
10798 END
10799 call v9.CheckSourceSuccess(lines)
10800
10801 " string() should return "object of A {}" without a builtin method
10802 let lines =<< trim END
10803 vim9script
10804 class A
10805 endclass
10806
10807 def Foo()
10808 var afoo = A.new()
10809 assert_equal('object of A {}', string(afoo))
10810 enddef
10811
10812 var a = A.new()
10813 assert_equal('object of A {}', string(a))
10814 Foo()
10815 END
10816 call v9.CheckSourceSuccess(lines)
10817
10818 " Unsupported signature for the string() method
10819 let lines =<< trim END
10820 vim9script
10821 class A
10822 def string()
10823 enddef
10824 endclass
10825 END
10826 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10827
10828 " Error when calling the string() method
10829 let lines =<< trim END
10830 vim9script
10831 class A
10832 def string(): string
10833 throw "Failed to get text"
10834 enddef
10835 endclass
10836
10837 def Foo()
10838 var afoo = A.new()
10839 var i = string(afoo)
10840 enddef
10841
10842 var a = A.new()
10843 assert_fails('string(a)', 'Failed to get text')
10844 assert_fails('Foo()', 'Failed to get text')
10845 END
10846 call v9.CheckSourceSuccess(lines)
10847
10848 " call string() using an object from a script
10849 let lines =<< trim END
10850 vim9script
10851 class A
10852 def string(): string
10853 return 'A'
10854 enddef
10855 endclass
10856 var afoo = A.new()
10857 assert_equal('A', afoo.string())
10858 END
10859 call v9.CheckSourceSuccess(lines)
10860
10861 " call string() using an object from a method
10862 let lines =<< trim END
10863 vim9script
10864 class A
10865 def string(): string
10866 return 'A'
10867 enddef
10868 endclass
10869 def Foo()
10870 var afoo = A.new()
10871 assert_equal('A', afoo.string())
10872 enddef
10873 Foo()
10874 END
10875 call v9.CheckSourceSuccess(lines)
10876
10877 " call string() using "this" from an object method
10878 let lines =<< trim END
10879 vim9script
10880 class A
10881 def string(): string
10882 return 'A'
10883 enddef
10884 def Foo(): string
10885 return this.string()
10886 enddef
10887 endclass
10888 def Bar()
10889 var abar = A.new()
10890 assert_equal('A', abar.string())
10891 enddef
10892 Bar()
10893 END
10894 call v9.CheckSourceSuccess(lines)
10895
10896 " Call string() from a derived object
10897 let lines =<< trim END
10898 vim9script
10899 class A
10900 def string(): string
10901 return 'A'
10902 enddef
10903 endclass
10904 class B extends A
10905 def string(): string
10906 return 'B'
10907 enddef
10908 endclass
10909 def Foo(afoo: A)
10910 assert_equal('B', string(afoo))
10911 var bfoo = B.new()
10912 assert_equal('B', string(bfoo))
10913 enddef
10914 var b = B.new()
10915 assert_equal('B', string(b))
10916 Foo(b)
10917 END
10918 call v9.CheckSourceSuccess(lines)
10919
10920 " Invoking string method using an interface
10921 let lines =<< trim END
10922 vim9script
10923 interface A
10924 def string(): string
10925 endinterface
10926 class B implements A
10927 def string(): string
10928 return 'B'
10929 enddef
10930 endclass
10931 def Foo(a: A)
10932 assert_equal('B', string(a))
10933 enddef
10934 var b = B.new()
10935 Foo(b)
10936 END
10937 call v9.CheckSourceSuccess(lines)
10938endfunc
10939
Ernie Rael9d779c52024-07-07 20:41:44 +020010940" Test for using the string() builtin method with an object's method
10941def Test_method_string()
10942 var lines =<< trim END
10943 vim9script
10944 class A
10945 def F()
10946 enddef
10947 endclass
10948 assert_match('function(''<SNR>\d\+_A\.F'')', string(A.new().F))
10949 END
10950 v9.CheckScriptSuccess(lines)
10951enddef
10952
10953
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010954" Test for using a class in the class definition
10955def Test_Ref_Class_Within_Same_Class()
10956 var lines =<< trim END
10957 vim9script
10958 class A
10959 var n: number = 0
10960 def Equals(other: A): bool
10961 return this.n == other.n
10962 enddef
10963 endclass
10964
10965 var a1 = A.new(10)
10966 var a2 = A.new(10)
10967 var a3 = A.new(20)
10968 assert_equal(true, a1.Equals(a2))
10969 assert_equal(false, a2.Equals(a3))
10970 END
10971 v9.CheckScriptSuccess(lines)
10972
10973 lines =<< trim END
10974 vim9script
10975
10976 class Foo
10977 var num: number
10978 def Clone(): Foo
10979 return Foo.new(this.num)
10980 enddef
10981 endclass
10982
10983 var f1 = Foo.new(1)
10984
10985 def F()
10986 var f2: Foo = f1.Clone()
10987 assert_equal(false, f2 is f1)
10988 assert_equal(true, f2.num == f1.num)
10989 enddef
10990 F()
10991
10992 var f3: Foo = f1.Clone()
10993 assert_equal(false, f3 is f1)
10994 assert_equal(true, f3.num == f1.num)
10995 END
10996 v9.CheckScriptSuccess(lines)
10997
10998 # Test for trying to use a class to extend when defining the same class
10999 lines =<< trim END
11000 vim9script
11001 class A extends A
11002 endclass
11003 END
11004 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
11005
11006 # Test for trying to use a class to implement when defining the same class
11007 lines =<< trim END
11008 vim9script
11009 class A implements A
11010 endclass
11011 END
11012 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
11013enddef
11014
Ernie Raelf0e69142024-06-22 11:12:00 +020011015" Test for comparing a class referencing itself
11016def Test_Object_Compare_With_Recursive_Class_Ref()
11017 var lines =<< trim END
11018 vim9script
11019
11020 class C
11021 public var nest: C
11022 endclass
11023
11024 var o1 = C.new()
11025 o1.nest = o1
11026
11027 var result = o1 == o1
11028 assert_equal(true, result)
11029 END
11030 v9.CheckScriptSuccess(lines)
Ernie Rael86257142024-06-23 09:54:45 +020011031
11032 lines =<< trim END
11033 vim9script
11034
11035 class C
11036 public var nest: C
11037 endclass
11038 var o1 = C.new()
11039 var o2 = C.new(C.new())
11040
11041 var result = o1 == o2
11042 assert_equal(false, result)
11043 END
11044 v9.CheckScriptSuccess(lines)
Ernie Rael05ff4e42024-07-04 16:50:11 +020011045
11046 lines =<< trim END
11047 vim9script
11048 class C
11049 var nest1: C
11050 var nest2: C
11051 def Init(n1: C, n2: C)
11052 this.nest1 = n1
11053 this.nest2 = n2
11054 enddef
11055 endclass
11056
11057 var o1 = C.new()
11058 var o2 = C.new()
11059 o1.Init(o1, o2)
11060 o2.Init(o2, o1)
11061
11062 var result = o1 == o2
11063 assert_equal(true, result)
11064 END
11065 v9.CheckScriptSuccess(lines)
Ernie Raelf0e69142024-06-22 11:12:00 +020011066enddef
11067
Ernie Raelf3975492024-07-06 11:44:37 +020011068" Test for comparing a class with nesting objects
11069def Test_Object_Compare_With_Nesting_Objects()
11070 # On a compare, after vim equal recurses 1000 times, not finding an unequal,
11071 # return the compare is equal.
11072 # Test that limit
11073
11074 var lines =<< trim END
11075 vim9script
11076 class C
11077 public var n: number
11078 public var nest: C
11079
11080 # Create a "C" that chains/nests to indicated depth.
11081 # return {head: firstC, tail: lastC}
11082 static def CreateNested(depth: number): dict<C>
11083 var first = C.new(1, null_object)
11084 var last = first
11085 for i in range(2, depth)
11086 last.nest = C.new(i, null_object)
11087 last = last.nest
11088 endfor
11089 return {head: first, tail: last}
11090 enddef
11091
11092 # Return pointer to nth item in chain.
11093 def GetLink(depth: number): C
11094 var count = 1
11095 var p: C = this
11096 while count < depth
11097 p = p.nest
11098 if p == null
11099 throw "too deep"
11100 endif
11101 count += 1
11102 endwhile
11103 return p
11104 enddef
11105
11106 # Return the length of the chain
11107 def len(): number
11108 var count = 1
11109 var p: C = this
11110 while p.nest != null
11111 p = p.nest
11112 count += 1
11113 endwhile
11114 return count
11115 enddef
11116 endclass
11117
11118 var chain = C.CreateNested(3)
11119 var s = "object of C {n: 1, nest: object of C {n: 2, nest: object of C {n: 3, nest: object of [unknown]}}}"
11120 assert_equal(s, string(chain.head))
11121 assert_equal(3, chain.head->len())
11122
11123 var chain1 = C.CreateNested(100)
11124 var chain2 = C.CreateNested(100)
11125 assert_true(chain1.head == chain2.head)
11126
11127 # modify the tail of chain2, compare not equal
11128 chain2.tail.n = 123456
11129 assert_true(chain1.head != chain2.head)
11130
11131 # a tail of a different length compares not equal
11132 chain2 = C.CreateNested(101)
11133 assert_true(chain1.head != chain2.head)
11134
11135 chain1 = C.CreateNested(1000)
11136 chain2 = C.CreateNested(1000)
11137 assert_true(chain1.head == chain2.head)
11138
11139 # modify the tail of chain2, compare not equal
11140 chain2.tail.n = 123456
11141 assert_true(chain1.head != chain2.head)
11142
11143 # try a chain longer that the limit
11144 chain1 = C.CreateNested(1001)
11145 chain2 = C.CreateNested(1001)
11146 assert_true(chain1.head == chain2.head)
11147
11148 # modify the tail, but still equal
11149 chain2.tail.n = 123456
11150 assert_true(chain1.head == chain2.head)
11151
11152 # remove 2 items from front, shorten the chain by two.
11153 chain1.head = chain1.head.GetLink(3)
11154 chain2.head = chain2.head.GetLink(3)
11155 assert_equal(3, chain1.head.n)
11156 assert_equal(3, chain2.head.n)
11157 assert_equal(999, chain1.head->len())
11158 assert_equal(999, chain2.head->len())
11159 # Now less than the limit, compare not equal
11160 assert_true(chain1.head != chain2.head)
11161 END
11162 v9.CheckScriptSuccess(lines)
11163enddef
11164
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010011165" Test for using a compound operator from a lambda function in an object method
11166def Test_compound_op_in_objmethod_lambda()
11167 # Test using the "+=" operator
11168 var lines =<< trim END
11169 vim9script
11170 class A
11171 var n: number = 10
11172 def Foo()
11173 var Fn = () => {
11174 this.n += 1
11175 }
11176 Fn()
11177 enddef
11178 endclass
11179
11180 var a = A.new()
11181 a.Foo()
11182 assert_equal(11, a.n)
11183 END
11184 v9.CheckScriptSuccess(lines)
11185
11186 # Test using the "..=" operator
11187 lines =<< trim END
11188 vim9script
11189 class A
11190 var s: string = "a"
11191 def Foo()
11192 var Fn = () => {
11193 this.s ..= "a"
11194 }
11195 Fn()
11196 enddef
11197 endclass
11198
11199 var a = A.new()
11200 a.Foo()
11201 a.Foo()
11202 assert_equal("aaa", a.s)
11203 END
11204 v9.CheckScriptSuccess(lines)
11205enddef
11206
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011207" Test for using test_refcount() with a class and an object
11208def Test_class_object_refcount()
11209 var lines =<< trim END
11210 vim9script
11211 class A
11212 endclass
11213 var a: A = A.new()
11214 assert_equal(2, test_refcount(A))
11215 assert_equal(1, test_refcount(a))
11216 var b = a
11217 assert_equal(2, test_refcount(A))
11218 assert_equal(2, test_refcount(a))
11219 assert_equal(2, test_refcount(b))
11220 END
11221 v9.CheckScriptSuccess(lines)
11222enddef
11223
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010011224" call a lambda function in one object from another object
11225def Test_lambda_invocation_across_classes()
11226 var lines =<< trim END
11227 vim9script
11228 class A
11229 var s: string = "foo"
11230 def GetFn(): func
11231 var Fn = (): string => {
11232 return this.s
11233 }
11234 return Fn
11235 enddef
11236 endclass
11237
11238 class B
11239 var s: string = "bar"
11240 def GetFn(): func
11241 var a = A.new()
11242 return a.GetFn()
11243 enddef
11244 endclass
11245
11246 var b = B.new()
11247 var Fn = b.GetFn()
11248 assert_equal("foo", Fn())
11249 END
11250 v9.CheckScriptSuccess(lines)
11251enddef
11252
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010011253" Test for using a class member which is an object of the current class
11254def Test_current_class_object_class_member()
11255 var lines =<< trim END
11256 vim9script
11257 class A
11258 public static var obj1: A = A.new(10)
11259 var n: number
11260 endclass
11261 defcompile
11262 assert_equal(10, A.obj1.n)
11263 END
11264 v9.CheckScriptSuccess(lines)
11265enddef
11266
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020011267" Test for updating a base class variable from a base class method without the
11268" class name. This used to crash Vim (Github issue #14352).
11269def Test_use_base_class_variable_from_base_class_method()
11270 var lines =<< trim END
11271 vim9script
11272
11273 class DictKeyClass
11274 static var _obj_id_count = 1
11275 def _GenerateKey()
11276 _obj_id_count += 1
11277 enddef
11278 static def GetIdCount(): number
11279 return _obj_id_count
11280 enddef
11281 endclass
11282
11283 class C extends DictKeyClass
11284 def F()
11285 this._GenerateKey()
11286 enddef
11287 endclass
11288
11289 C.new().F()
11290 assert_equal(2, DictKeyClass.GetIdCount())
11291 END
11292 v9.CheckScriptSuccess(lines)
11293enddef
11294
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020011295" Test for accessing protected funcref object and class variables
11296def Test_protected_funcref()
11297 # protected funcref object variable
11298 var lines =<< trim END
11299 vim9script
11300 class Test1
11301 const _Id: func(any): any = (v) => v
11302 endclass
11303 var n = Test1.new()._Id(1)
11304 END
11305 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
11306
11307 # protected funcref class variable
11308 lines =<< trim END
11309 vim9script
11310 class Test2
11311 static const _Id: func(any): any = (v) => v
11312 endclass
11313 var n = Test2._Id(2)
11314 END
11315 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
11316enddef
11317
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020011318" Test for using lambda block in classes
11319def Test_lambda_block_in_class()
11320 # This used to crash Vim
11321 var lines =<< trim END
11322 vim9script
11323 class IdClass1
11324 const Id: func(number): number = (num: number): number => {
11325 # Return a ID
11326 return num * 10
11327 }
11328 endclass
11329 var id = IdClass1.new()
11330 assert_equal(20, id.Id(2))
11331 END
11332 v9.CheckScriptSuccess(lines)
11333
11334 # This used to crash Vim
11335 lines =<< trim END
11336 vim9script
11337 class IdClass2
11338 static const Id: func(number): number = (num: number): number => {
11339 # Return a ID
11340 return num * 2
11341 }
11342 endclass
11343 assert_equal(16, IdClass2.Id(8))
11344 END
11345 v9.CheckScriptSuccess(lines)
11346enddef
11347
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020011348" Test for defcompiling an abstract method
11349def Test_abstract_method_defcompile()
11350 # Compile an abstract class with abstract object methods
11351 var lines =<< trim END
11352 vim9script
11353 abstract class A
11354 abstract def Foo(): string
11355 abstract def Bar(): list<string>
11356 endclass
11357 defcompile
11358 END
11359 v9.CheckScriptSuccess(lines)
11360
11361 # Compile a concrete object method in an abstract class
11362 lines =<< trim END
11363 vim9script
11364 abstract class A
11365 abstract def Foo(): string
11366 abstract def Bar(): list<string>
11367 def Baz(): string
11368 pass
11369 enddef
11370 endclass
11371 defcompile
11372 END
11373 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11374
11375 # Compile a concrete class method in an abstract class
11376 lines =<< trim END
11377 vim9script
11378 abstract class A
11379 abstract def Foo(): string
11380 abstract def Bar(): list<string>
11381 static def Baz(): string
11382 pass
11383 enddef
11384 endclass
11385 defcompile
11386 END
11387 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
11388enddef
11389
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020011390" Test for defining a class in a function
11391def Test_class_definition_in_a_function()
11392 var lines =<< trim END
11393 vim9script
11394 def Foo()
11395 class A
11396 endclass
11397 enddef
11398 defcompile
11399 END
11400 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
11401enddef
11402
Yegappan Lakshmanandbac0da2024-05-25 20:23:54 +020011403" Test for using [] with a class and an object
11404def Test_class_object_index()
11405 var lines =<< trim END
11406 vim9script
11407 class A
11408 endclass
11409 A[10] = 1
11410 END
11411 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a class: A[10] = 1', 4)
11412
11413 lines =<< trim END
11414 vim9script
11415 class A
11416 endclass
11417 var a = A.new()
11418 a[10] = 1
11419 END
11420 v9.CheckScriptFailure(lines, 'E689: Index not allowed after a object: a[10] = 1', 5)
11421enddef
11422
LemonBoyf4af3312024-07-04 13:43:12 +020011423def Test_class_member_init_typecheck()
11424 # Ensure the class member is assigned its declared type.
11425 var lines =<< trim END
11426 vim9script
11427 class S
11428 static var l: list<string> = []
11429 endclass
11430 S.l->add(123)
11431 END
11432 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 5)
11433
11434 # Ensure the initializer value and the declared type match.
11435 lines =<< trim END
11436 vim9script
11437 class S
11438 var l: list<string> = [1, 2, 3]
11439 endclass
11440 var o = S.new()
11441 END
11442 v9.CheckScriptFailure(lines, 'E1382: Variable "l": type mismatch, expected list<string> but got list<number>')
11443
11444 # Ensure the class member is assigned its declared type.
11445 lines =<< trim END
11446 vim9script
11447 class S
11448 var l: list<string> = []
11449 endclass
11450 var o = S.new()
11451 o.l->add(123)
11452 END
11453 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number', 6)
11454enddef
11455
LemonBoy50d48542024-07-04 17:03:17 +020011456def Test_class_cast()
11457 var lines =<< trim END
11458 vim9script
11459 class A
11460 endclass
11461 class B extends A
11462 var mylen: number
11463 endclass
11464 def F(o: A): number
11465 return (<B>o).mylen
11466 enddef
11467
11468 defcompile F
11469 END
11470 v9.CheckScriptSuccess(lines)
11471enddef
11472
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011473" Test for using a variable of type "any" with an object
11474def Test_any_obj_var_type()
11475 var lines =<< trim END
11476 vim9script
11477 class A
11478 var name: string = "foobar"
11479 def Foo(): string
11480 return "func foo"
11481 enddef
11482 endclass
11483
11484 def CheckVals(x: any)
11485 assert_equal("foobar", x.name)
11486 assert_equal("func foo", x.Foo())
11487 enddef
11488
11489 var a = A.new()
11490 CheckVals(a)
11491 END
11492 v9.CheckScriptSuccess(lines)
11493
11494 # Try to set a non-existing variable
11495 lines =<< trim END
11496 vim9script
11497 class A
11498 var name: string = "foobar"
11499 endclass
11500
11501 def SetNonExistingVar(x: any)
11502 x.bar = [1, 2, 3]
11503 enddef
11504
11505 var a = A.new()
11506 SetNonExistingVar(a)
11507 END
11508 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11509
11510 # Try to read a non-existing variable
11511 lines =<< trim END
11512 vim9script
11513 class A
11514 var name: string = "foobar"
11515 endclass
11516
11517 def GetNonExistingVar(x: any)
11518 var i: dict<any> = x.bar
11519 enddef
11520
11521 var a = A.new()
11522 GetNonExistingVar(a)
11523 END
11524 v9.CheckScriptFailure(lines, 'E1326: Variable "bar" not found in object "A"', 1)
11525
11526 # Try to invoke a non-existing method
11527 lines =<< trim END
11528 vim9script
11529 class A
11530 def Foo(): number
11531 return 10
11532 enddef
11533 endclass
11534
11535 def CallNonExistingMethod(x: any)
11536 var i: number = x.Bar()
11537 enddef
11538
11539 var a = A.new()
11540 CallNonExistingMethod(a)
11541 END
11542 v9.CheckScriptFailure(lines, 'E1326: Variable "Bar" not found in object "A"', 1)
11543
11544 # Use an object which is a Dict value
11545 lines =<< trim END
11546 vim9script
11547 class Foo
11548 def Bar(): number
11549 return 369
11550 enddef
11551 endclass
11552
11553 def GetValue(FooDict: dict<any>): number
11554 var n: number = 0
11555 for foo in values(FooDict)
11556 n += foo.Bar()
11557 endfor
11558 return n
11559 enddef
11560
11561 var d = {'x': Foo.new()}
11562 assert_equal(369, GetValue(d))
11563 END
11564 v9.CheckScriptSuccess(lines)
11565
zeertzjqd32bf0a2024-12-17 20:55:13 +010011566 # Nested data. Object containing a Dict containing another Object.
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011567 lines =<< trim END
11568 vim9script
11569 class Context
11570 public var state: dict<any> = {}
11571 endclass
11572
11573 class Metadata
11574 public var value = 0
11575 endclass
11576
11577 var ctx = Context.new()
11578 ctx.state["meta"] = Metadata.new(2468)
11579
11580 const foo = ctx.state.meta.value
11581
11582 def F(): number
11583 const bar = ctx.state.meta.value
11584 return bar
11585 enddef
11586
11587 assert_equal(2468, F())
11588 END
11589 v9.CheckScriptSuccess(lines)
11590
11591 # Accessing an object from a method inside the class using any type
11592 lines =<< trim END
11593 vim9script
11594 class C
11595 def _G(): string
11596 return '_G'
11597 enddef
11598 static def S(o_any: any): string
11599 return o_any._G()
11600 enddef
11601 endclass
11602
11603 var o1 = C.new()
11604 assert_equal('_G', C.S(o1))
11605 END
11606 v9.CheckScriptSuccess(lines)
11607
11608 # Modifying an object private variable from a method in another class using
11609 # any type
11610 lines =<< trim END
11611 vim9script
11612
11613 class A
11614 var num = 10
11615 endclass
11616
11617 class B
11618 def SetVal(x: any)
11619 x.num = 20
11620 enddef
11621 endclass
11622
11623 var a = A.new()
11624 var b = B.new()
11625 b.SetVal(a)
11626 END
11627 v9.CheckScriptFailure(lines, 'E1335: Variable "num" in class "A" is not writable', 1)
11628
11629 # Accessing a object protected variable from a method in another class using
11630 # any type
11631 lines =<< trim END
11632 vim9script
11633
11634 class A
11635 var _num = 10
11636 endclass
11637
11638 class B
11639 def GetVal(x: any): number
11640 return x._num
11641 enddef
11642 endclass
11643
11644 var a = A.new()
11645 var b = B.new()
11646 var i = b.GetVal(a)
11647 END
11648 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_num" in class "A"', 1)
11649
11650 # Accessing an object returned from an imported function and class
11651 lines =<< trim END
11652 vim9script
11653 export class Foo
11654 public var name: string
11655 endclass
11656
11657 export def ReturnFooObject(): Foo
11658 var r = Foo.new('star')
11659 return r
11660 enddef
11661 END
11662 writefile(lines, 'Xanyvar1.vim', 'D')
11663
11664 lines =<< trim END
11665 vim9script
11666
11667 import './Xanyvar1.vim'
11668
11669 def GetName(): string
11670 var whatever = Xanyvar1.ReturnFooObject()
11671 return whatever.name
11672 enddef
11673
11674 assert_equal('star', GetName())
11675 END
11676 v9.CheckScriptSuccess(lines)
11677
11678 # Try to modify a private object variable using a variable of type "any"
11679 lines =<< trim END
11680 vim9script
11681
11682 class Foo
11683 var n: number = 10
11684 endclass
11685 def Fn(x: any)
11686 x.n = 20
11687 enddef
11688 var a = Foo.new()
11689 Fn(a)
11690 END
11691 v9.CheckScriptFailure(lines, 'E1335: Variable "n" in class "Foo" is not writable', 1)
11692
11693 # Try to read a protected object variable using a variable of type "any"
11694 lines =<< trim END
11695 vim9script
11696
11697 class Foo
11698 var _n: number = 10
11699 endclass
11700 def Fn(x: any): number
11701 return x._n
11702 enddef
11703
11704 var a = Foo.new()
11705 Fn(a)
11706 END
11707 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_n" in class "Foo"', 1)
11708
11709 # Read a protected object variable using a variable of type "any" in an object
11710 # method
11711 lines =<< trim END
11712 vim9script
11713
11714 class Foo
11715 var _n: number = 10
11716 def Fn(x: any): number
11717 return x._n
11718 enddef
11719 endclass
11720
11721 var a = Foo.new()
11722 assert_equal(10, a.Fn(a))
11723 END
11724 v9.CheckScriptSuccess(lines)
11725
11726 # Try to call a protected object method using a "any" type variable
11727 lines =<< trim END
11728 vim9script
11729
11730 class Foo
11731 def _GetVal(): number
11732 return 234
11733 enddef
11734 endclass
11735 def Fn(x: any): number
11736 return x._GetVal()
11737 enddef
11738
11739 var a = Foo.new()
11740 Fn(a)
11741 END
11742 v9.CheckScriptFailure(lines, 'E1366: Cannot access protected method: _GetVal', 1)
11743
11744 # Call a protected object method using a "any" type variable from another
11745 # object method
11746 lines =<< trim END
11747 vim9script
11748
11749 class Foo
11750 def _GetVal(): number
11751 return 234
11752 enddef
11753 def FooVal(x: any): number
11754 return x._GetVal()
11755 enddef
11756 endclass
11757
11758 var a = Foo.new()
11759 assert_equal(234, a.FooVal(a))
11760 END
11761 v9.CheckScriptSuccess(lines)
11762
11763 # Method chaining
11764 lines =<< trim END
11765 vim9script
11766
11767 export class T
11768 var id: number = 268
11769 def F(): any
11770 return this
11771 enddef
11772 endclass
11773
11774 def H()
11775 var a = T.new().F().F()
11776 assert_equal(268, a.id)
11777 enddef
11778 H()
11779
11780 var b: T = T.new().F().F()
11781 assert_equal(268, b.id)
11782 END
11783 v9.CheckScriptSuccess(lines)
11784
11785 # Using a null object to access a member variable
11786 lines =<< trim END
11787 vim9script
11788 def Fn(x: any): number
11789 return x.num
11790 enddef
11791
11792 Fn(null_object)
11793 END
11794 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
11795
11796 # Using a null object to invoke a method
11797 lines =<< trim END
11798 vim9script
11799 def Fn(x: any)
11800 x.Foo()
11801 enddef
11802
11803 Fn(null_object)
11804 END
11805 v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
Yegappan Lakshmanane7984462024-11-12 21:03:00 +010011806
11807 # Try to change a const object variable using a "any" variable
11808 lines =<< trim END
11809 vim9script
11810 class A
11811 public const v1: number = 123
11812 endclass
11813
11814 def Fn(o: any)
11815 o.v1 = 321
11816 enddef
11817
11818 var a = A.new()
11819 Fn(a)
11820 END
11821 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11822
11823 # Try to change a final object variable using a "any" variable
11824 lines =<< trim END
11825 vim9script
11826 class A
11827 public final v1: number = 123
11828 endclass
11829
11830 def Fn(o: any)
11831 o.v1 = 321
11832 enddef
11833
11834 var a = A.new()
11835 Fn(a)
11836 END
11837 v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
11838
11839 # Assign a different type of value to an "any" type object variable
11840 lines =<< trim END
11841 vim9script
11842 class A
11843 public var v1: list<any> = [1, 2]
11844 endclass
11845
11846 def Fn(o: A)
11847 o.v1 = 'abc'
11848 enddef
11849
11850 var a = A.new()
11851 Fn(a)
11852 END
11853 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 1)
Yegappan Lakshmanan56d45f12024-11-11 19:58:55 +010011854enddef
11855
Yegappan Lakshmanan481992c2024-12-06 18:35:12 +010011856" Test for using an object method with mapnew()
11857def Test_mapnew_with_instance_method()
11858 var lines =<< trim END
11859 vim9script
11860
11861 class Foo
11862 var str: string
11863 var nums: list<number> = [1, 2, 3]
11864
11865 def InstanceMethod(n: number): string
11866 return this.str .. n
11867 enddef
11868
11869 def MapperMethod(idx: number, elem: number): string
11870 return elem->this.InstanceMethod()
11871 enddef
11872
11873 def MapTest()
11874 this.str = "foo"
11875 var l = ['foo1', 'foo2', 'foo3']
11876 assert_equal(l, this.nums->mapnew(this.MapperMethod))
11877 enddef
11878 endclass
11879
11880 Foo.new().MapTest()
11881 END
11882 v9.CheckSourceSuccess(lines)
11883
11884 # Error in the mapnew() function
11885 lines =<< trim END
11886 vim9script
11887
11888 class Foo
11889 var str: string
11890 var nums: list<number> = [1, 2, 3]
11891
11892 def InstanceMethod(n: number): string
11893 throw "InstanceMethod failed"
11894 enddef
11895
11896 def MapperMethod(idx: number, elem: number): string
11897 return elem->this.InstanceMethod()
11898 enddef
11899
11900 def MapTest()
11901 this.str = "foo"
11902 var caught_exception: bool = false
11903 try
11904 this.nums->mapnew(this.MapperMethod)
11905 catch /InstanceMethod failed/
11906 caught_exception = true
11907 endtry
11908 assert_true(caught_exception)
11909 enddef
11910 endclass
11911
11912 Foo.new().MapTest()
11913 END
11914 v9.CheckSourceSuccess(lines)
11915enddef
11916
Yegappan Lakshmananb0206e92024-12-30 09:52:16 +010011917" Test for using an object method in a method call.
11918def Test_use_object_method_in_a_method_call()
11919 var lines =<< trim END
11920 vim9script
11921
11922 class Foo
11923 def Cost(nums: list<number>): number
11924 return nums[0] * nums[1]
11925 enddef
11926
11927 def ShowCost(): string
11928 var g = [4, 5]
11929 return $"Cost is: {g->this.Cost()}"
11930 enddef
11931 endclass
11932
11933 var d = Foo.new()
11934 assert_equal('Cost is: 20', d.ShowCost())
11935 END
11936 v9.CheckSourceSuccess(lines)
11937
11938 # Test for using a non-existing object method in string interpolation
11939 lines =<< trim END
11940 vim9script
11941
11942 class Foo
11943 def Cost(nums: list<number>): number
11944 return nums[0] * nums[1]
11945 enddef
11946
11947 def ShowCost(): string
11948 var g = [4, 5]
11949 echo $"Cost is: {g->this.NewCost()}"
11950 enddef
11951 endclass
11952
11953 var d = Foo.new()
11954 d.ShowCost()
11955 END
11956 v9.CheckSourceFailure(lines, 'E1326: Variable "NewCost" not found in object "Foo"')
11957enddef
11958
Yegappan Lakshmananb04af4c2025-01-03 10:50:08 +010011959" Test for referencing an object variable which is not yet initialized
11960def Test_uninitialized_object_var()
11961 var lines =<< trim END
11962 vim9script
11963 class Foo
11964 const two: number = Foo.Two(this)
11965 const one: number = 1
11966
11967 static def Two(that: Foo): number
11968 return that.one + 2
11969 enddef
11970 endclass
11971
11972 echo Foo.Two(Foo.new())
11973 END
11974 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'one' referenced")
11975
11976 lines =<< trim END
11977 vim9script
11978 class Foo
11979 const one: number = Foo.One(this)
11980
11981 static def One(that: Foo): number
11982 return 1
11983 enddef
11984 endclass
11985
11986 assert_equal(1, Foo.One(Foo.new()))
11987 END
11988 v9.CheckSourceSuccess(lines)
11989
11990 lines =<< trim END
11991 vim9script
11992 class Foo
11993 const one: number = 1
11994 const two: number = Foo.Two(this)
11995
11996 static def Two(that: Foo): number
11997 return that.one + 1
11998 enddef
11999 endclass
12000
12001 assert_equal(2, Foo.Two(Foo.new()))
12002 END
12003 v9.CheckSourceSuccess(lines)
12004
12005 lines =<< trim END
12006 vim9script
12007 class Foo
12008 const Id: func(any): any = ((_) => (v) => v)(this)
12009
12010 static def Id(that: Foo): func(any): any
12011 return that.Id
12012 enddef
12013 endclass
12014
12015 assert_equal(5, Foo.Id(Foo.new())(5))
12016 assert_equal(7, Foo.new().Id(7))
12017 END
12018 v9.CheckSourceSuccess(lines)
12019
12020 lines =<< trim END
12021 vim9script
12022 class Foo
12023 const Id: func(any): any = ((that) => (_) => that)(this)
12024
12025 static def Id(that: Foo): func(any): any
12026 return that.Id
12027 enddef
12028 endclass
12029
12030 const Id0: func(any): any = Foo.Id(Foo.new())
12031 const Id1: func(any): any = Foo.new().Id
12032 END
12033 v9.CheckSourceSuccess(lines)
12034
12035 lines =<< trim END
12036 vim9script
12037 class Foo
12038 const Id: any = Foo.Id(this)
12039
12040 static def Id(that: Foo): any
12041 return that.Id
12042 enddef
12043 endclass
12044
12045 const Id2: any = Foo.Id(Foo.new())
12046 const Id3: any = Foo.new().Id
12047 END
12048 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'Id' referenced")
12049
12050 lines =<< trim END
12051 vim9script
12052
12053 class Foo
12054 var x: string = ''
12055 var Y: func(): string = () => this.x
12056 endclass
12057
12058 var foo = Foo.new('ok')
12059 assert_equal('ok', foo.Y())
12060 END
12061 v9.CheckSourceSuccess(lines)
12062
12063 lines =<< trim END
12064 vim9script
12065
12066 class Foo
12067 var x: string = this.x
12068 endclass
12069
12070 var foo = Foo.new('ok')
12071 END
12072 v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'x' referenced")
12073enddef
12074
Yegappan Lakshmanan2050dcc2025-01-06 18:34:49 +010012075" Test for initializing member variables of compound type in the constructor
12076def Test_constructor_init_compound_member_var()
12077 var lines =<< trim END
12078 vim9script
12079
12080 class Foo
12081 var v1: string = "aaa"
12082 var v2: list<number> = [1, 2]
12083 var v3: dict<string> = {a: 'a', b: 'b'}
12084 endclass
12085
12086 class Bar
12087 var v4: string = "bbb"
12088 var v5: Foo = Foo.new()
12089 var v6: list<number> = [1, 2]
12090 endclass
12091
12092 var b: Bar = Bar.new()
12093 assert_equal("aaa", b.v5.v1)
12094 assert_equal([1, 2], b.v5.v2)
12095 assert_equal({a: 'a', b: 'b'}, b.v5.v3)
12096 assert_equal("bbb", b.v4)
12097 assert_equal([1, 2], b.v6)
12098 END
12099 v9.CheckSourceSuccess(lines)
12100enddef
12101
Bram Moolenaar00b28d62022-12-08 15:32:33 +000012102" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker