blob: bd06c6e28622ec58e4f96fc8cd2b6e832a0f67ef [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 Lakshmanan35b867b2024-03-09 15:44:19 +0100106 # Try to define a class with the same name as an existing variable
107 lines =<< trim END
108 vim9script
109 var Something: list<number> = [1]
110 class Thing
111 endclass
112 interface Api
113 endinterface
114 class Something extends Thing implements Api
115 var v1: string = ''
116 def Foo()
117 enddef
118 endclass
119 END
120 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "Something"', 7)
121
zeertzjqe7102202024-02-13 20:32:04 +0100122 # Use old "this." prefixed member variable declaration syntax (without initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100123 lines =<< trim END
124 vim9script
125 class Something
126 this.count: number
127 endclass
128 END
129 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number', 3)
130
zeertzjqe7102202024-02-13 20:32:04 +0100131 # Use old "this." prefixed member variable declaration syntax (with initialization)
Doug Kearns74da0ee2023-12-14 20:26:26 +0100132 lines =<< trim END
133 vim9script
134 class Something
135 this.count: number = 42
136 endclass
137 END
138 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count: number = 42', 3)
139
140 # Use old "this." prefixed member variable declaration syntax (type inferred)
141 lines =<< trim END
142 vim9script
143 class Something
144 this.count = 42
145 endclass
146 END
147 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.count = 42', 3)
148
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200149 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000150 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200151 vim9script
152 class Something
153 this
154 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000155 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100156 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000157
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200158 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000159 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200160 vim9script
161 class Something
162 this.
163 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000164 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100165 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000166
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200167 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000168 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200169 vim9script
170 class Something
171 this .count
172 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000173 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100174 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000175
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200176 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000177 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200178 vim9script
179 class Something
180 this. count
181 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000182 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100183 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000184
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200185 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000186 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200187 vim9script
188 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100189 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200190 that.count
191 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000192 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200193 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000194
Doug Kearns74da0ee2023-12-14 20:26:26 +0100195 # Use "variable" instead of "var" for member variable declaration (without initialization)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000196 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200197 vim9script
198 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100199 variable count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200200 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000201 END
Doug Kearns74da0ee2023-12-14 20:26:26 +0100202 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number', 3)
203
204 # Use "variable" instead of "var" for member variable declaration (with initialization)
205 lines =<< trim END
206 vim9script
207 class Something
208 variable count: number = 42
209 endclass
210 END
211 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count: number = 42', 3)
212
213 # Use "variable" instead of "var" for member variable declaration (type inferred)
214 lines =<< trim END
215 vim9script
216 class Something
217 variable count = 42
218 endclass
219 END
220 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: variable count = 42', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000221
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200222 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000223 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200224 vim9script
225 class Something
226 def new()
227 this.state = 0
228 enddef
229 endclass
230 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000231 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200232 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000233
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200234 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000235 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200236 vim9script
237 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100238 var count : number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200239 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000240 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200241 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000242
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200243 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000244 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200245 vim9script
246 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100247 var count:number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200248 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000249 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200250 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251
Doug Kearns74da0ee2023-12-14 20:26:26 +0100252 # Missing ":var" in a "var" member variable declaration (without initialization)
253 lines =<< trim END
254 vim9script
255 class Something
256 var: number
257 endclass
258 END
259 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number', 3)
260
261 # Missing ":var" in a "var" member variable declaration (with initialization)
262 lines =<< trim END
263 vim9script
264 class Something
265 var: number = 42
266 endclass
267 END
268 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var: number = 42', 3)
269
270 # Missing ":var" in a "var" member variable declaration (type inferred)
271 lines =<< trim END
272 vim9script
273 class Something
274 var = 42
275 endclass
276 END
277 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: var = 42', 3)
278
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279 # Test for unsupported comment specifier
280 lines =<< trim END
281 vim9script
282 class Something
283 # comment
284 #{
285 endclass
286 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200287 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200288
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200289 # Test for using class as a bool
290 lines =<< trim END
291 vim9script
292 class A
293 endclass
294 if A
295 endif
296 END
Ernie Raele75fde62023-12-21 17:18:54 +0100297 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200298
299 # Test for using object as a bool
300 lines =<< trim END
301 vim9script
302 class A
303 endclass
304 var a = A.new()
305 if a
306 endif
307 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200308 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200309
310 # Test for using class as a float
311 lines =<< trim END
312 vim9script
313 class A
314 endclass
315 sort([1.1, A], 'f')
316 END
Ernie Raelfa831102023-12-14 20:06:39 +0100317 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200318
319 # Test for using object as a float
320 lines =<< trim END
321 vim9script
322 class A
323 endclass
324 var a = A.new()
325 sort([1.1, a], 'f')
326 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200327 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200328
329 # Test for using class as a string
330 lines =<< trim END
331 vim9script
332 class A
333 endclass
334 :exe 'call ' .. A
335 END
Ernie Raele75fde62023-12-21 17:18:54 +0100336 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200337
338 # Test for using object as a string
339 lines =<< trim END
340 vim9script
341 class A
342 endclass
343 var a = A.new()
344 :exe 'call ' .. a
345 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200346 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200347
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200348 # Test creating a class with member variables and methods, calling a object
349 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000350 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200351 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000352
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200353 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100354 var lnum: number
355 var col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000356
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200357 # make a nicely formatted string
358 def ToString(): string
359 return $'({this.lnum}, {this.col})'
360 enddef
361 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000362
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200363 # use the automatically generated new() method
364 var pos = TextPosition.new(2, 12)
365 assert_equal(2, pos.lnum)
366 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000367
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200368 # call an object method
369 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000370
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200371 assert_equal(v:t_class, type(TextPosition))
372 assert_equal(v:t_object, type(pos))
373 assert_equal('class<TextPosition>', typename(TextPosition))
374 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000375 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200376 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200377
378 # When referencing object methods, space cannot be used after a "."
379 lines =<< trim END
380 vim9script
381 class A
382 def Foo(): number
383 return 10
384 enddef
385 endclass
386 var a = A.new()
387 var v = a. Foo()
388 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200389 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200390
391 # Using an object without specifying a method or a member variable
392 lines =<< trim END
393 vim9script
394 class A
395 def Foo(): number
396 return 10
397 enddef
398 endclass
399 var a = A.new()
400 var v = a.
401 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200402 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200403
404 # Error when parsing the arguments of an object method.
405 lines =<< trim END
406 vim9script
407 class A
408 def Foo()
409 enddef
410 endclass
411 var a = A.new()
412 var v = a.Foo(,)
413 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200414 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200415
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200416 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200417 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200418 vim9script
419 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100420 var y = {
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200421 X: 1
422 }
423 endclass
424 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200425 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200426 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000427enddef
428
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200429" Tests for object/class methods in a class
430def Test_class_def_method()
431 # Using the "public" keyword when defining an object method
432 var lines =<< trim END
433 vim9script
434 class A
435 public def Foo()
436 enddef
437 endclass
438 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200439 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200440
441 # Using the "public" keyword when defining a class method
442 lines =<< trim END
443 vim9script
444 class A
445 public static def Foo()
446 enddef
447 endclass
448 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200449 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200450
Ernie Rael03042a22023-11-11 08:53:32 +0100451 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200452 lines =<< trim END
453 vim9script
454 class A
455 public def _Foo()
456 enddef
457 endclass
458 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200459 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200460
Ernie Rael03042a22023-11-11 08:53:32 +0100461 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200462 lines =<< trim END
463 vim9script
464 class A
465 public static def _Foo()
466 enddef
467 endclass
468 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +0200469 v9.CheckSourceFailure(lines, 'E1388: public keyword not supported for a method', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200470
471 # Using a "def" keyword without an object method name
472 lines =<< trim END
473 vim9script
474 class A
475 def
476 enddef
477 endclass
478 END
479 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
480
481 # Using a "def" keyword without a class method name
482 lines =<< trim END
483 vim9script
484 class A
485 static def
486 enddef
487 endclass
488 END
489 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
490enddef
491
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000492def Test_class_defined_twice()
493 # class defined twice should fail
494 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200495 vim9script
496 class There
497 endclass
498 class There
499 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200501 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000502
503 # one class, reload same script twice is OK
504 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200505 vim9script
506 class There
507 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000508 END
509 writefile(lines, 'XclassTwice.vim', 'D')
510 source XclassTwice.vim
511 source XclassTwice.vim
512enddef
513
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000514def Test_returning_null_object()
515 # this was causing an internal error
516 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200517 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000518
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200519 class BufferList
520 def Current(): any
521 return null_object
522 enddef
523 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200525 var buffers = BufferList.new()
526 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000527 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200528 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000529enddef
530
Bram Moolenaard13dd302023-03-11 20:56:35 +0000531def Test_using_null_class()
532 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200533 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200535 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000536enddef
537
Bram Moolenaar657aea72023-01-27 13:16:19 +0000538def Test_class_interface_wrong_end()
539 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200540 vim9script
541 abstract class SomeName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100542 var member = 'text'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200543 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000544 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200545 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000546
547 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200548 vim9script
549 export interface AnotherName
Doug Kearns74da0ee2023-12-14 20:26:26 +0100550 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200551 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000552 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200553 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000554enddef
555
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000556def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200557 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000558 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200559 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000560
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200561 class State
Doug Kearns74da0ee2023-12-14 20:26:26 +0100562 var value = 'xyz'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200563 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000564
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200565 var state: State
566 var db = {'xyz': 789}
567 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000568 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200569 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000570
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200571 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000572 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200573 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000574
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200575 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100576 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200577 def Method1()
578 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000579 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200580 endclass
581
582 var obj: Class
583 def Func()
584 obj.Method1()
585 enddef
586 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200588 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000589
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200590 # Pass an uninitialized object variable to a "new" function and try to call an
591 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000592 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200593 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000594
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200595 class Background
Doug Kearns74da0ee2023-12-14 20:26:26 +0100596 var background = 'dark'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200597 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200599 class Colorscheme
Doug Kearns74da0ee2023-12-14 20:26:26 +0100600 var _bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000601
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200602 def GetBackground(): string
603 return this._bg.background
604 enddef
605 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000606
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200607 var bg: Background # UNINITIALIZED
608 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000609 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200610 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000611
612 # TODO: this should not give an error but be handled at runtime
613 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200614 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000615
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200616 class Class
Doug Kearns74da0ee2023-12-14 20:26:26 +0100617 var id: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200618 def Method1()
619 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000620 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200621 endclass
622
623 var obj = null_object
624 def Func()
625 obj.Method1()
626 enddef
627 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000628 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000630enddef
631
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200632" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200633def Test_null_object_assign_compare()
634 var lines =<< trim END
635 vim9script
636
637 var nullo = null_object
638 def F(): any
639 return nullo
640 enddef
641 assert_equal('object<Unknown>', typename(F()))
642
643 var o0 = F()
644 assert_true(o0 == null_object)
645 assert_true(o0 == null)
646
647 var o1: any = nullo
648 assert_true(o1 == null_object)
649 assert_true(o1 == null)
650
651 def G()
652 var x = null_object
653 enddef
654
655 class C
656 endclass
657 var o2: C
658 assert_true(o2 == null_object)
659 assert_true(o2 == null)
660
661 o2 = null_object
662 assert_true(o2 == null)
663
664 o2 = C.new()
665 assert_true(o2 != null)
666
667 o2 = null_object
668 assert_true(o2 == null)
669 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200670 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200671enddef
672
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200673" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000674def Test_class_member_initializer()
675 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200676 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000677
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200678 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100679 var lnum: number = 1
680 var col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000681
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200682 # constructor with only the line number
683 def new(lnum: number)
684 this.lnum = lnum
685 enddef
686 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000687
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200688 var pos = TextPosition.new(3)
689 assert_equal(3, pos.lnum)
690 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000691
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200692 var instr = execute('disassemble TextPosition.new')
693 assert_match('new\_s*' ..
694 '0 NEW TextPosition size \d\+\_s*' ..
695 '\d PUSHNR 1\_s*' ..
696 '\d STORE_THIS 0\_s*' ..
697 '\d PUSHNR 1\_s*' ..
698 '\d STORE_THIS 1\_s*' ..
699 'this.lnum = lnum\_s*' ..
700 '\d LOAD arg\[-1]\_s*' ..
701 '\d PUSHNR 0\_s*' ..
702 '\d LOAD $0\_s*' ..
703 '\d\+ STOREINDEX object\_s*' ..
704 '\d\+ RETURN object.*',
705 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000706 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200707 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000708enddef
709
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000710def Test_member_any_used_as_object()
711 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000713
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200714 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100715 var value: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200716 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000717
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200718 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100719 var inner: any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200720 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200722 def F(outer: Outer)
723 outer.inner.value = 1
724 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200726 var inner_obj = Inner.new(0)
727 var outer_obj = Outer.new(inner_obj)
728 F(outer_obj)
729 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000730 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200731 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000732
Ernie Rael03042a22023-11-11 08:53:32 +0100733 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200734 lines =<< trim END
735 vim9script
736
737 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100738 var _value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200739 endclass
740
741 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100742 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200743 endclass
744
745 def F(outer: Outer)
746 outer.inner._value = 'b'
747 enddef
748
749 var inner_obj = Inner.new('a')
750 var outer_obj = Outer.new(inner_obj)
751 F(outer_obj)
752 END
Ernie Rael03042a22023-11-11 08:53:32 +0100753 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200754
755 # Try modifying a non-existing variable using an "any" object
756 lines =<< trim END
757 vim9script
758
759 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100760 var value: string = ''
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200761 endclass
762
763 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100764 var inner: any
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200765 endclass
766
767 def F(outer: Outer)
768 outer.inner.someval = 'b'
769 enddef
770
771 var inner_obj = Inner.new('a')
772 var outer_obj = Outer.new(inner_obj)
773 F(outer_obj)
774 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200775 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000776enddef
777
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200778" Nested assignment to a object variable which is of another class type
779def Test_assignment_nested_type()
780 var lines =<< trim END
781 vim9script
782
783 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100784 public var value: number = 0
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200785 endclass
786
787 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100788 var inner: Inner
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200789 endclass
790
791 def F(outer: Outer)
792 outer.inner.value = 1
793 enddef
794
795 def Test_assign_to_nested_typed_member()
796 var inner = Inner.new(0)
797 var outer = Outer.new(inner)
798 F(outer)
799 assert_equal(1, inner.value)
800 enddef
801
802 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200803
804 var script_inner = Inner.new(0)
805 var script_outer = Outer.new(script_inner)
806 script_outer.inner.value = 1
807 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200808 END
809 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200810
811 # Assignment where target item is read only in :def
812 lines =<< trim END
813 vim9script
814
815 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100816 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200817 endclass
818
819 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100820 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200821 endclass
822
823 def F(outer: Outer)
824 outer.inner.value = 1
825 enddef
826
827 def Test_assign_to_nested_typed_member()
828 var inner = Inner.new(0)
829 var outer = Outer.new(inner)
830 F(outer)
831 assert_equal(1, inner.value)
832 enddef
833
834 Test_assign_to_nested_typed_member()
835 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200836 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200837
838 # Assignment where target item is read only script level
839 lines =<< trim END
840 vim9script
841
842 class Inner
Doug Kearns74da0ee2023-12-14 20:26:26 +0100843 var value: number = 0
Ernie Rael98e68c02023-09-20 20:13:06 +0200844 endclass
845
846 class Outer
Doug Kearns74da0ee2023-12-14 20:26:26 +0100847 var inner: Inner
Ernie Rael98e68c02023-09-20 20:13:06 +0200848 endclass
849
850 def F(outer: Outer)
851 outer.inner.value = 1
852 enddef
853
854 var script_inner = Inner.new(0)
855 var script_outer = Outer.new(script_inner)
856 script_outer.inner.value = 1
857 assert_equal(1, script_inner.value)
858 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200859 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200860enddef
861
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000862def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200863 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000864 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200865 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000866
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200867 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +0100868 public var x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000869
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200870 def Add(n: number)
871 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100872 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200873 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100874
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200875 var f = Foo.new(3)
876 f.Add(17)
877 assert_equal(20, f.x)
878
879 def AddToFoo(obj: Foo)
880 obj.x += 3
881 enddef
882
883 AddToFoo(f)
884 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000885 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200886 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000887enddef
888
Bram Moolenaarf4508042023-01-15 16:54:57 +0000889def Test_list_of_objects()
890 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200891 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000892
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200893 class Foo
894 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000895 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200896 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000897
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200898 def ProcessList(fooList: list<Foo>)
899 for foo in fooList
900 foo.Add()
901 endfor
902 enddef
903
904 var l: list<Foo> = [Foo.new()]
905 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000906 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200907 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000908enddef
909
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000910def Test_expr_after_using_object()
911 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200912 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000913
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200914 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +0100915 var label: string = ''
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200916 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000917
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200918 def Foo(): Something
919 var v = Something.new()
920 echo 'in Foo(): ' .. typename(v)
921 return v
922 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000923
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200924 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000925 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200926 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000927enddef
928
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000929def Test_class_default_new()
930 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200931 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000932
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200933 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +0100934 var lnum: number = 1
935 var col: number = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200936 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000937
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200938 var pos = TextPosition.new()
939 assert_equal(1, pos.lnum)
940 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200942 pos = TextPosition.new(v:none, v:none)
943 assert_equal(1, pos.lnum)
944 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000945
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 pos = TextPosition.new(3, 22)
947 assert_equal(3, pos.lnum)
948 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000949
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200950 pos = TextPosition.new(v:none, 33)
951 assert_equal(1, pos.lnum)
952 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000953 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200954 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000955
956 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200957 vim9script
958 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100959 var name: string
960 var age: number = 42
961 var education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000962
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200963 def new(this.name, this.age = v:none, this.education = v:none)
964 enddef
965 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000966
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200967 var piet = Person.new("Piet")
968 assert_equal("Piet", piet.name)
969 assert_equal(42, piet.age)
970 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000971
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200972 var chris = Person.new("Chris", 4, "none")
973 assert_equal("Chris", chris.name)
974 assert_equal(4, chris.age)
975 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000976 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200977 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000978
979 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200980 vim9script
981 class Person
Doug Kearns74da0ee2023-12-14 20:26:26 +0100982 var name: string
983 var age: number = 42
984 var education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000985
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200986 def new(this.name, this.age = v:none, this.education = v:none)
987 enddef
988 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000989
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200990 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000991 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200992 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200993
994 # Using a specific value to initialize an instance variable in the new()
995 # method.
996 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 vim9script
998 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +0100999 var val: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001000 def new(this.val = 'a')
1001 enddef
1002 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001003 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001004 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +00001005enddef
1006
h-east2261c892023-08-16 21:49:54 +09001007def Test_class_new_with_object_member()
1008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001009 vim9script
h-east2261c892023-08-16 21:49:54 +09001010
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001012 var str: string
1013 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001014 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +09001015 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 def newVals(this.str, this.num)
1017 enddef
1018 endclass
h-east2261c892023-08-16 21:49:54 +09001019
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001020 def Check()
1021 try
1022 var c = C.new('cats', 2)
1023 assert_equal('cats', c.str)
1024 assert_equal(2, c.num)
1025
1026 c = C.newVals('dogs', 4)
1027 assert_equal('dogs', c.str)
1028 assert_equal(4, c.num)
1029 catch
1030 assert_report($'Unexpected exception was caught: {v:exception}')
1031 endtry
1032 enddef
1033
1034 Check()
h-east2261c892023-08-16 21:49:54 +09001035 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001036 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +09001037
1038 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +02001039 vim9script
1040
1041 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001042 var str: string
1043 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +02001045 enddef
1046 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001047
1048 def Check()
1049 try
1050 var c = C.new(1, 2)
1051 catch
1052 assert_report($'Unexpected exception was caught: {v:exception}')
1053 endtry
1054 enddef
1055
1056 Check()
h-eastdb385522023-09-28 22:18:19 +02001057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +02001059
1060 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001061 vim9script
h-eastb895b0f2023-09-24 15:46:31 +02001062
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001063 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001064 var str: string
1065 var num: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001066 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +02001067 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001068 endclass
h-eastb895b0f2023-09-24 15:46:31 +02001069
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001070 def Check()
1071 try
1072 var c = C.newVals('dogs', 'apes')
1073 catch
1074 assert_report($'Unexpected exception was caught: {v:exception}')
1075 endtry
1076 enddef
1077
1078 Check()
1079 END
1080 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
1081
1082 lines =<< trim END
1083 vim9script
1084
1085 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01001086 var str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001087 def new(str: any)
1088 enddef
1089 endclass
1090
1091 def Check()
1092 try
1093 var c = C.new(1)
1094 catch
1095 assert_report($'Unexpected exception was caught: {v:exception}')
1096 endtry
1097 enddef
1098
1099 Check()
h-eastb895b0f2023-09-24 15:46:31 +02001100 END
1101 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001102
1103 # Try using "this." argument in a class method
1104 lines =<< trim END
1105 vim9script
1106 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001107 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001108 static def Foo(this.val: number)
1109 enddef
1110 endclass
1111 END
1112 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
1113
1114 # Try using "this." argument in an object method
1115 lines =<< trim END
1116 vim9script
1117 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001118 var val = 10
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02001119 def Foo(this.val: number)
1120 enddef
1121 endclass
1122 END
1123 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001124enddef
1125
Bram Moolenaar74e12742022-12-13 21:14:28 +00001126def Test_class_object_member_inits()
1127 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001128 vim9script
1129 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001130 var lnum: number
1131 var col = 1
1132 var addcol: number = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001134
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001135 var pos = TextPosition.new()
1136 assert_equal(0, pos.lnum)
1137 assert_equal(1, pos.col)
1138 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001139 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001140 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001141
1142 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001143 vim9script
1144 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01001145 var lnum
1146 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001147 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001148 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001149 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001150
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001151 # If the type is not specified for a member, then it should be set during
1152 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001153 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001154 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001155
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001156 var init_count = 0
1157 def Init(): string
1158 init_count += 1
1159 return 'foo'
1160 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001161
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001162 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001163 var str1 = Init()
1164 var str2: string = Init()
1165 var col = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001166 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001167
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001168 assert_equal(init_count, 0)
1169 var a = A.new()
1170 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001171 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001172 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001173
1174 # Test for initializing an object member with an unknown variable/type
1175 lines =<< trim END
1176 vim9script
1177 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001178 var value = init_val
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001179 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001180 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001181 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001182 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001183
1184 # Test for initializing an object member with an special type
1185 lines =<< trim END
1186 vim9script
1187 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001188 var value: void
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001189 endclass
1190 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001191 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001192enddef
1193
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001194" Test for instance variable access
1195def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001196 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001197 vim9script
1198 class Triple
Doug Kearns74da0ee2023-12-14 20:26:26 +01001199 var _one = 1
1200 var two = 2
1201 public var three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001203 def GetOne(): number
1204 return this._one
1205 enddef
1206 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001207
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001208 var trip = Triple.new()
1209 assert_equal(1, trip.GetOne())
1210 assert_equal(2, trip.two)
1211 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001212 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001213
Ernie Rael03042a22023-11-11 08:53:32 +01001214 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001215 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1216 trip.three = 33
1217 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001218
Ernie Raeld4802ec2023-10-20 11:59:00 +02001219 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001220 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001221 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001222
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001223 # Test for a public member variable name beginning with an underscore
1224 lines =<< trim END
1225 vim9script
1226 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001227 public var _val = 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001228 endclass
1229 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001230 v9.CheckSourceFailure(lines, 'E1332: public variable name cannot start with underscore: public var _val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001231
Bram Moolenaar590162c2022-12-24 21:24:06 +00001232 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001233 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001234
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001236 var make: string
1237 var age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001238
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001239 def new(make_arg: string)
1240 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001241 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001242
1243 def GetMake(): string
1244 return $"make = {this.make}"
1245 enddef
1246 def GetAge(): number
1247 return this.age
1248 enddef
1249 endclass
1250
1251 var c = MyCar.new("abc")
1252 assert_equal('make = abc', c.GetMake())
1253
1254 c = MyCar.new("def")
1255 assert_equal('make = def', c.GetMake())
1256
1257 var c2 = MyCar.new("123")
1258 assert_equal('make = 123', c2.GetMake())
1259
1260 def CheckCar()
1261 assert_equal("make = def", c.GetMake())
1262 assert_equal(5, c.GetAge())
1263 enddef
1264 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001265 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001266 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001267
1268 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001269 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001271 class MyCar
Doug Kearns74da0ee2023-12-14 20:26:26 +01001272 var make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001273
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001274 def new(make_arg: string)
1275 this.make = make_arg
1276 enddef
1277 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001278
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001279 var c = MyCar.new("abc")
1280 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001281 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001282 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001283
1284 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001285 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001286
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001287 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001288 var x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001289
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001290 def Add(n: number): any
1291 this.x->add(n)
1292 return this
1293 enddef
1294 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001295
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001296 echo Foo.new().Add(1).Add(2).x
1297 echo Foo.new().Add(1).Add(2)
1298 .x
1299 echo Foo.new().Add(1)
1300 .Add(2).x
1301 echo Foo.new()
1302 .Add(1).Add(2).x
1303 echo Foo.new()
1304 .Add(1)
1305 .Add(2)
1306 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001307 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001309
1310 # Test for "public" cannot be abbreviated
1311 lines =<< trim END
1312 vim9script
1313 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001314 pub var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001315 endclass
1316 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001317 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub var val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001318
Doug Kearns74da0ee2023-12-14 20:26:26 +01001319 # Test for "public" keyword must be followed by "var" or "static".
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001320 lines =<< trim END
1321 vim9script
1322 class Something
1323 public val = 1
1324 endclass
1325 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02001326 v9.CheckSourceFailure(lines, 'E1331: public must be followed by "var" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001327
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001328 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001329 lines =<< trim END
1330 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001331 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001332 public var val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001333 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001334 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001336 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001337
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001338 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001339 lines =<< trim END
1340 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001341 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001342 public var val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001343 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001344 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001345 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001346 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001347
1348 # Modify a instance variable using the class name in a def function
1349 lines =<< trim END
1350 vim9script
1351 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001352 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001353 endclass
1354 def T()
1355 A.val = 1
1356 enddef
1357 T()
1358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001360
1361 # Read a instance variable using the class name in a def function
1362 lines =<< trim END
1363 vim9script
1364 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001365 public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001366 endclass
1367 def T()
1368 var i = A.val
1369 enddef
1370 T()
1371 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001372 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001373
1374 # Access from child class extending a class:
1375 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001376 vim9script
1377 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001378 var ro_obj_var = 10
1379 public var rw_obj_var = 20
1380 var _priv_obj_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001381 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001382
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001383 class B extends A
1384 def Foo()
1385 var x: number
1386 x = this.ro_obj_var
1387 this.ro_obj_var = 0
1388 x = this.rw_obj_var
1389 this.rw_obj_var = 0
1390 x = this._priv_obj_var
1391 this._priv_obj_var = 0
1392 enddef
1393 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001395 var b = B.new()
1396 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001397 END
1398 v9.CheckSourceSuccess(lines)
1399enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001400
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001401" Test for class variable access
1402def Test_class_variable_access()
1403 # Test for "static" cannot be abbreviated
1404 var lines =<< trim END
1405 vim9script
1406 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001407 stat var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001408 endclass
1409 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001410 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat var val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001411
1412 # Test for "static" cannot be followed by "public".
1413 lines =<< trim END
1414 vim9script
1415 class Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01001416 static public var val = 1
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001417 endclass
1418 END
Doug Kearns74da0ee2023-12-14 20:26:26 +01001419 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001420
1421 # A readonly class variable cannot be modified from a child class
1422 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001423 vim9script
1424 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001425 static var ro_class_var = 40
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001426 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001427
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001428 class B extends A
1429 def Foo()
1430 A.ro_class_var = 50
1431 enddef
1432 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001433
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001434 var b = B.new()
1435 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001436 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001437 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001438
Ernie Rael03042a22023-11-11 08:53:32 +01001439 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001440 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001441 vim9script
1442 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001443 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001445
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 class B extends A
1447 def Foo()
1448 var i = A._priv_class_var
1449 enddef
1450 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001451
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001452 var b = B.new()
1453 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001454 END
Ernie Rael03042a22023-11-11 08:53:32 +01001455 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001456
Ernie Rael03042a22023-11-11 08:53:32 +01001457 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001458 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 vim9script
1460 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001461 static var _priv_class_var = 60
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001462 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001463
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001464 class B extends A
1465 def Foo()
1466 A._priv_class_var = 0
1467 enddef
1468 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001469
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001470 var b = B.new()
1471 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001472 END
Ernie Rael03042a22023-11-11 08:53:32 +01001473 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001474
1475 # Access from child class extending a class and from script context
1476 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001477 vim9script
1478 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001479 static var ro_class_var = 10
1480 public static var rw_class_var = 20
1481 static var _priv_class_var = 30
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001482 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001483
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001484 class B extends A
1485 def Foo()
1486 var x: number
1487 x = A.ro_class_var
1488 assert_equal(10, x)
1489 x = A.rw_class_var
1490 assert_equal(25, x)
1491 A.rw_class_var = 20
1492 assert_equal(20, A.rw_class_var)
1493 enddef
1494 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001495
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001496 assert_equal(10, A.ro_class_var)
1497 assert_equal(20, A.rw_class_var)
1498 A.rw_class_var = 25
1499 assert_equal(25, A.rw_class_var)
1500 var b = B.new()
1501 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001502 END
1503 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001504enddef
1505
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001506def Test_class_object_compare()
1507 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 vim9script
1509 class Item
Doug Kearns74da0ee2023-12-14 20:26:26 +01001510 var nr = 0
1511 var name = 'xx'
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001512 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001513 END
1514
1515 # used at the script level and in a compiled function
1516 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001517 var i1 = Item.new()
1518 assert_equal(i1, i1)
1519 assert_true(i1 is i1)
1520 var i2 = Item.new()
1521 assert_equal(i1, i2)
1522 assert_false(i1 is i2)
1523 var i3 = Item.new(0, 'xx')
1524 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001525
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001526 var io1 = Item.new(1, 'xx')
1527 assert_notequal(i1, io1)
1528 var io2 = Item.new(0, 'yy')
1529 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001530 END
1531
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001532 v9.CheckSourceSuccess(class_lines + test_lines)
1533 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001534 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001535
1536 for op in ['>', '>=', '<', '<=', '=~', '!~']
1537 var op_lines = [
1538 'var i1 = Item.new()',
1539 'var i2 = Item.new()',
1540 'echo i1 ' .. op .. ' i2',
1541 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001543 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001544 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001545 endfor
1546enddef
1547
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001548def Test_object_type()
1549 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001550 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001551
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001552 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001553 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 endclass
1555 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001556 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001557 endclass
1558 class TwoMore extends Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001559 var more = 9
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001560 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001561
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001562 var o: One = One.new()
1563 var t: Two = Two.new()
1564 var m: TwoMore = TwoMore.new()
1565 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001566
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001567 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001568 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001569 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001570
1571 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001572 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001573
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001574 class One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001575 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 endclass
1577 class Two
Doug Kearns74da0ee2023-12-14 20:26:26 +01001578 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001579 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001580
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001581 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001582 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001583 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001584
1585 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001587
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 interface One
1589 def GetMember(): number
1590 endinterface
1591 class Two implements One
Doug Kearns74da0ee2023-12-14 20:26:26 +01001592 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 def GetMember(): number
1594 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001595 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001596 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var o: One = Two.new(5)
1599 assert_equal(5, o.GetMember())
1600 END
1601 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001602
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001603 lines =<< trim END
1604 vim9script
1605
1606 class Num
Doug Kearns74da0ee2023-12-14 20:26:26 +01001607 var n: number = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 endclass
1609
1610 def Ref(name: string): func(Num): Num
1611 return (arg: Num): Num => {
1612 return eval(name)(arg)
1613 }
1614 enddef
1615
1616 const Fn = Ref('Double')
1617 var Double = (m: Num): Num => Num.new(m.n * 2)
1618
1619 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001620 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001621 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001622enddef
1623
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001624def Test_class_member()
1625 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001626 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001627 vim9script
1628 class TextPos
Doug Kearns74da0ee2023-12-14 20:26:26 +01001629 var lnum = 1
1630 var col = 1
1631 static var counter = 0
1632 static var _secret = 7
1633 public static var anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001634
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001635 static def AddToCounter(nr: number)
1636 counter += nr
1637 enddef
1638 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001639
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001640 assert_equal(0, TextPos.counter)
1641 TextPos.AddToCounter(3)
1642 assert_equal(3, TextPos.counter)
1643 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001644
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001645 def GetCounter(): number
1646 return TextPos.counter
1647 enddef
1648 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001649
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001650 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1651 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1652 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001653
Ernie Rael03042a22023-11-11 08:53:32 +01001654 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1655 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001656
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001657 assert_equal(42, TextPos.anybody)
1658 TextPos.anybody = 12
1659 assert_equal(12, TextPos.anybody)
1660 TextPos.anybody += 5
1661 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001662 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001663 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001664
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001665 # example in the help
1666 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001667 vim9script
1668 class OtherThing
Doug Kearns74da0ee2023-12-14 20:26:26 +01001669 var size: number
1670 static var totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001671
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001672 def new(this.size)
1673 totalSize += this.size
1674 enddef
1675 endclass
1676 assert_equal(0, OtherThing.totalSize)
1677 var to3 = OtherThing.new(3)
1678 assert_equal(3, OtherThing.totalSize)
1679 var to7 = OtherThing.new(7)
1680 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001681 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001682 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001683
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001684 # using static class member twice
1685 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001687
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001688 class HTML
Doug Kearns74da0ee2023-12-14 20:26:26 +01001689 static var author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001690
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001691 static def MacroSubstitute(s: string): string
1692 return substitute(s, '{{author}}', author, 'gi')
1693 enddef
1694 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001695
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001696 assert_equal('some text', HTML.MacroSubstitute('some text'))
1697 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001698 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001699 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001700
Ernie Rael03042a22023-11-11 08:53:32 +01001701 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001702 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001703 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001704
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001705 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001706 var _x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001707
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 def Add(n: number): number
1709 const F = (): number => this._x + n
1710 return F()
1711 enddef
1712 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001713
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001714 var foo = Foo.new()
1715 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001716 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001717 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001718
Ernie Rael03042a22023-11-11 08:53:32 +01001719 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001720 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001721 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001722
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001723 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01001724 var _x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001725
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001726 def Add(n: number): number
1727 var Lam = () => {
1728 this._x = this._x + n
1729 }
1730 Lam()
1731 return this._x
1732 enddef
1733 endclass
h-east2bd6a092023-05-19 19:01:17 +01001734
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001735 var foo = Foo.new()
1736 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001737 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001738 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001739
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001740 # check shadowing
1741 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001742 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001743
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001744 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001745 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001746 def Method(count: number)
1747 echo count
1748 enddef
1749 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001751 var s = Some.new()
1752 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001753 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001755
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001756 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001757 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001758 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001760 class Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01001761 static var count = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001762 def Method(arg: number)
1763 var count = 3
1764 echo arg count
1765 enddef
1766 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001767
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001768 var s = Some.new()
1769 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001770 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001771 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001772
1773 # Test for using an invalid type for a member variable
1774 lines =<< trim END
1775 vim9script
1776 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001777 var val: xxx
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001778 endclass
1779 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001780 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001781
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001782 # Test for setting a member on a null object
1783 lines =<< trim END
1784 vim9script
1785 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001786 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001787 endclass
1788
1789 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001790 var obj: A
1791 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001792 enddef
1793 F()
1794 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001795 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001796
1797 # Test for accessing a member on a null object
1798 lines =<< trim END
1799 vim9script
1800 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001801 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001802 endclass
1803
1804 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001805 var obj: A
1806 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001807 enddef
1808 F()
1809 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001810 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001811
1812 # Test for setting a member on a null object, at script level
1813 lines =<< trim END
1814 vim9script
1815 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001816 public var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001817 endclass
1818
1819 var obj: A
1820 obj.val = ""
1821 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001822 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001823
1824 # Test for accessing a member on a null object, at script level
1825 lines =<< trim END
1826 vim9script
1827 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001828 var val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001829 endclass
1830
1831 var obj: A
1832 echo obj.val
1833 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001835
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001836 # Test for no space before or after the '=' when initializing a member
1837 # variable
1838 lines =<< trim END
1839 vim9script
1840 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001841 var val: number= 10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001842 endclass
1843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001844 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001845 lines =<< trim END
1846 vim9script
1847 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01001848 var val: number =10
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001849 endclass
1850 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001851 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001852
1853 # Access a non-existing member
1854 lines =<< trim END
1855 vim9script
1856 class A
1857 endclass
1858 var a = A.new()
1859 var v = a.bar
1860 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001861 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001862enddef
1863
Ernie Raele6c9aa52023-10-06 19:55:52 +02001864" These messages should show the defining class of the variable (base class),
1865" not the class that did the reference (super class)
1866def Test_defining_class_message()
1867 var lines =<< trim END
1868 vim9script
1869
1870 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001871 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001872 endclass
1873
1874 class Child extends Base
1875 endclass
1876
1877 var o = Child.new()
1878 var x = o._v1
1879 END
Ernie Rael03042a22023-11-11 08:53:32 +01001880 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001881 lines =<< trim END
1882 vim9script
1883
1884 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001885 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001886 endclass
1887
1888 class Child extends Base
1889 endclass
1890
1891 def F()
1892 var o = Child.new()
1893 var x = o._v1
1894 enddef
1895 F()
1896 END
Ernie Rael03042a22023-11-11 08:53:32 +01001897 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001898 lines =<< trim END
1899 vim9script
1900
1901 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001902 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001903 endclass
1904
1905 class Child extends Base
1906 endclass
1907
1908 var o = Child.new()
1909 o.v1 = []
1910 END
1911 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1912 lines =<< trim END
1913 vim9script
1914
1915 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001916 var v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001917 endclass
1918
1919 class Child extends Base
1920 endclass
1921
1922 def F()
1923 var o = Child.new()
1924 o.v1 = []
1925 enddef
1926 F()
1927 END
1928
Ernie Rael03042a22023-11-11 08:53:32 +01001929 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001930 # of the class hierarchy.
1931 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1932 lines =<< trim END
1933 vim9script
1934
1935 class Base0
1936 endclass
1937
1938 class Base extends Base0
Doug Kearns74da0ee2023-12-14 20:26:26 +01001939 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001940 endclass
1941
1942 class Child extends Base
1943 endclass
1944
1945 def F()
1946 var o = Child.new()
1947 var x = o._v1
1948 enddef
1949 F()
1950 END
Ernie Rael03042a22023-11-11 08:53:32 +01001951 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001952
Ernie Rael03042a22023-11-11 08:53:32 +01001953 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001954 # of the class hierarchy.
1955 lines =<< trim END
1956 vim9script
1957
1958 class Base0
1959 endclass
1960
1961 class Base extends Base0
1962 endclass
1963
1964 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01001965 var _v1: list<list<number>>
Ernie Raele6c9aa52023-10-06 19:55:52 +02001966 endclass
1967
1968 def F()
1969 var o = Child.new()
1970 var x = o._v1
1971 enddef
1972 F()
1973 END
Ernie Rael03042a22023-11-11 08:53:32 +01001974 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001975enddef
1976
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001977func Test_class_garbagecollect()
1978 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001979 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001980
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001981 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01001982 var p = [2, 3]
1983 static var pl = ['a', 'b']
1984 static var pd = {a: 'a', b: 'b'}
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001985 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001986
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001987 echo Point.pl Point.pd
1988 call test_garbagecollect_now()
1989 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001990 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001991 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001992
1993 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001994 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001995
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001996 interface View
1997 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001998
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001999 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01002000 var view: View
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002001 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002002
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002003 class MyView implements View
Doug Kearns74da0ee2023-12-14 20:26:26 +01002004 var widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002005
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002006 def new()
2007 # this will result in a circular reference to this object
Doug Kearns74da0ee2023-12-14 20:26:26 +01002008 var widget = Widget.new(this)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002009 enddef
2010 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002011
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002012 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002014 # overwrite "view", will be garbage-collected next
2015 view = MyView.new()
2016 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01002017 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002018 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00002019endfunc
2020
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002021" Test interface garbage collection
2022func Test_interface_garbagecollect()
2023 let lines =<< trim END
2024 vim9script
2025
2026 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002027 var ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002028
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002029 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002030 endinterface
2031
2032 class A implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01002033 static var ro_class_var: number = 10
2034 public static var rw_class_var: number = 20
2035 static var _priv_class_var: number = 30
2036 var ro_obj_var: number = 40
2037 var _priv_obj_var: number = 60
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002038
2039 static def _ClassBar(): number
2040 return _priv_class_var
2041 enddef
2042
2043 static def ClassFoo(): number
2044 return ro_class_var + rw_class_var + A._ClassBar()
2045 enddef
2046
2047 def _ObjBar(): number
2048 return this._priv_obj_var
2049 enddef
2050
2051 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002052 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002053 enddef
2054 endclass
2055
2056 assert_equal(60, A.ClassFoo())
2057 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002058 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002059 test_garbagecollect_now()
2060 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002061 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002062 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002063 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02002064endfunc
2065
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002066def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002067 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002068 vim9script
2069 class Value
Doug Kearns74da0ee2023-12-14 20:26:26 +01002070 var value = 0
2071 static var objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 def new(v: number)
2074 this.value = v
2075 ++objects
2076 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002077
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002078 static def GetCount(): number
2079 return objects
2080 enddef
2081 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002082
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002083 assert_equal(0, Value.GetCount())
2084 var v1 = Value.new(2)
2085 assert_equal(1, Value.GetCount())
2086 var v2 = Value.new(7)
2087 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002088 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002089 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002090
2091 # Test for cleaning up after a class definition failure when using class
2092 # functions.
2093 lines =<< trim END
2094 vim9script
2095 class A
2096 static def Foo()
2097 enddef
2098 aaa
2099 endclass
2100 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002101 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002102
2103 # Test for calling a class method from another class method without the class
2104 # name prefix.
2105 lines =<< trim END
2106 vim9script
2107 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01002108 static var myList: list<number> = [1]
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02002109 static def Foo(n: number)
2110 myList->add(n)
2111 enddef
2112 static def Bar()
2113 Foo(2)
2114 enddef
2115 def Baz()
2116 Foo(3)
2117 enddef
2118 endclass
2119 A.Bar()
2120 var a = A.new()
2121 a.Baz()
2122 assert_equal([1, 2, 3], A.myList)
2123 END
2124 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002125enddef
2126
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002127def Test_class_defcompile()
2128 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002129 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002130
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002131 class C
2132 def Fo(i: number): string
2133 return i
2134 enddef
2135 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002136
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002137 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002138 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002139 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002140
2141 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002142 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002143
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002144 class C
2145 static def Fc(): number
2146 return 'x'
2147 enddef
2148 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002151 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002152 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002153
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002154 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002155 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002156
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002157 class C
2158 static def new()
2159 enddef
2160 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002161
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002162 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002163 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002164 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002165
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002166 # Trying to compile a function using a non-existing class variable
2167 lines =<< trim END
2168 vim9script
2169 defcompile x.Foo()
2170 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002172
2173 # Trying to compile a function using a variable which is not a class
2174 lines =<< trim END
2175 vim9script
2176 var x: number
2177 defcompile x.Foo()
2178 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002179 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002180
2181 # Trying to compile a function without specifying the name
2182 lines =<< trim END
2183 vim9script
2184 class A
2185 endclass
2186 defcompile A.
2187 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002188 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002189
2190 # Trying to compile a non-existing class object member function
2191 lines =<< trim END
2192 vim9script
2193 class A
2194 endclass
2195 var a = A.new()
2196 defcompile a.Foo()
2197 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002198 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002199enddef
2200
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002201def Test_class_object_to_string()
2202 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 vim9script
2204 class TextPosition
Doug Kearns74da0ee2023-12-14 20:26:26 +01002205 var lnum = 1
2206 var col = 22
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002207 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002208
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002210
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 var pos = TextPosition.new()
2212 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002213 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002214 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002215enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002216
Bram Moolenaar554d0312023-01-05 19:59:18 +00002217def Test_interface_basics()
2218 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 vim9script
2220 interface Something
Doug Kearns74da0ee2023-12-14 20:26:26 +01002221 var ro_var: list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 def GetCount(): number
2223 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002224 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002225 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002226
2227 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002228 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002229 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002230 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002231 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002232 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002233
2234 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002235 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002237 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002238 var value: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002239 def Method(value: number)
2240 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002241 END
h-east61378a12023-04-18 19:07:29 +01002242 # The argument name and the object member name are the same, but this is not a
2243 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002244 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002245
2246 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002247 vim9script
2248 interface somethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002249 static var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002250 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002251 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002252 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002253
2254 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002255 vim9script
2256 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002257 var value: string
2258 var count = 7
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002259 def GetCount(): number
2260 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002262 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002263
2264 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002265 vim9script
2266 interface SomethingWrong
Doug Kearns74da0ee2023-12-14 20:26:26 +01002267 var value: string
2268 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002269 def GetCount(): number
2270 return 5
2271 enddef
2272 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002273 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002274 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002275
Yegappan Lakshmananac773182024-04-27 11:36:12 +02002276 # Additional commands after "interface name"
2277 lines =<< trim END
2278 vim9script
2279 interface Something | var x = 10 | var y = 20
2280 endinterface
2281 END
2282 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = 10", 2)
2283
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002284 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002285 vim9script
2286 export interface EnterExit
2287 def Enter(): void
2288 def Exit(): void
2289 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002290 END
2291 writefile(lines, 'XdefIntf.vim', 'D')
2292
2293 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002294 vim9script
2295 import './XdefIntf.vim' as defIntf
2296 export def With(ee: defIntf.EnterExit, F: func)
2297 ee.Enter()
2298 try
2299 F()
2300 finally
2301 ee.Exit()
2302 endtry
2303 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002304 END
2305 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002306
2307 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002308 vim9script
2309 export abstract class EnterExit
2310 def Enter(): void
2311 enddef
2312 def Exit(): void
2313 enddef
2314 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002315 END
2316 writefile(imported, 'XdefIntf2.vim', 'D')
2317
2318 lines[1] = " import './XdefIntf2.vim' as defIntf"
2319 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002320enddef
2321
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +01002322" Test for using string() with an interface
2323def Test_interface_to_string()
2324 var lines =<< trim END
2325 vim9script
2326 interface Intf
2327 def Method(nr: number)
2328 endinterface
2329 assert_equal("interface Intf", string(Intf))
2330 END
2331 v9.CheckSourceSuccess(lines)
2332enddef
2333
Bram Moolenaar94674f22023-01-06 18:42:20 +00002334def Test_class_implements_interface()
2335 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002336 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002337
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002339 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 def Method(nr: number)
2341 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002342
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002344 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002345 def Method(nr: number)
2346 echo nr
2347 enddef
2348 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002349
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 interface Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002351 var member: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002352 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002353
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002354 class AnotherImpl implements Some, Another
Doug Kearns74da0ee2023-12-14 20:26:26 +01002355 var member = 'abc'
2356 var count = 20
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002357 def Method(nr: number)
2358 echo nr
2359 enddef
2360 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002361 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002362 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002363
2364 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002365 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002366
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002367 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002368 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002370
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002371 class SomeImpl implements Some implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002372 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002373 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002374 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002375 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002376
2377 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002378 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002379
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002380 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002381 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002383
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002384 class SomeImpl implements Some, Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002385 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002386 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002387 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002388 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002389
2390 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002391 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002392
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002393 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002394 var counter: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002395 def Method(nr: number)
2396 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002397
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002399 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002400 def Method(nr: number)
2401 echo nr
2402 enddef
2403 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002404 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002405 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002406
2407 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002408 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002409
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002410 interface Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002411 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002412 def Methods(nr: number)
2413 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002414
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 class SomeImpl implements Some
Doug Kearns74da0ee2023-12-14 20:26:26 +01002416 var count: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002417 def Method(nr: number)
2418 echo nr
2419 enddef
2420 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002422 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002423
2424 # Check different order of members in class and interface works.
2425 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002426 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002427
2428 interface Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002429 var label: string
2430 var errpos: number
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002431 endinterface
2432
2433 # order of members is opposite of interface
2434 class Failure implements Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01002435 public var lnum: number = 5
2436 var errpos: number = 42
2437 var label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002438 endclass
2439
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002440 def Test()
2441 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002442
2443 assert_equal('label', result.label)
2444 assert_equal(42, result.errpos)
2445 enddef
2446
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002447 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002448 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002449 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002450
2451 # Interface name after "extends" doesn't end in a space or NUL character
2452 lines =<< trim END
2453 vim9script
2454 interface A
2455 endinterface
2456 class B extends A"
2457 endclass
2458 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002459 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002460
2461 # Trailing characters after a class name
2462 lines =<< trim END
2463 vim9script
2464 class A bbb
2465 endclass
2466 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002468
2469 # using "implements" with a non-existing class
2470 lines =<< trim END
2471 vim9script
2472 class A implements B
2473 endclass
2474 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002475 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002476
2477 # using "implements" with a regular class
2478 lines =<< trim END
2479 vim9script
2480 class A
2481 endclass
2482 class B implements A
2483 endclass
2484 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002485 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002486
2487 # using "implements" with a variable
2488 lines =<< trim END
2489 vim9script
2490 var T: number = 10
2491 class A implements T
2492 endclass
2493 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002494 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002495
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002496 # implements should be followed by a white space
2497 lines =<< trim END
2498 vim9script
2499 interface A
2500 endinterface
2501 class B implements A;
2502 endclass
2503 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002504 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002505
LemonBoyc5d27442023-08-19 13:02:35 +02002506 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002507 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002508
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002509 interface One
2510 def IsEven(nr: number): bool
2511 endinterface
2512 class Two implements One
2513 def IsEven(nr: number): string
2514 enddef
2515 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002516 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002517 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002518
2519 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002521
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002522 interface One
2523 def IsEven(nr: number): bool
2524 endinterface
2525 class Two implements One
2526 def IsEven(nr: bool): bool
2527 enddef
2528 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002529 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002530 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002531
2532 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002533 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002535 interface One
2536 def IsEven(nr: number): bool
2537 endinterface
2538 class Two implements One
2539 def IsEven(nr: number, ...extra: list<number>): bool
2540 enddef
2541 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002542 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002543 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 +02002544
2545 # access superclass interface members from subclass, mix variable order
2546 lines =<< trim END
2547 vim9script
2548
2549 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002550 var mvar1: number
2551 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002552 endinterface
2553
2554 # NOTE: the order is swapped
2555 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002556 var mvar2: number
2557 var mvar1: number
2558 public static var svar2: number
2559 public static var svar1: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002560 def new()
2561 svar1 = 11
2562 svar2 = 12
2563 this.mvar1 = 111
2564 this.mvar2 = 112
2565 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002566 endclass
2567
2568 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 def new()
2570 this.mvar1 = 121
2571 this.mvar2 = 122
2572 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002573 endclass
2574
2575 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002576 def new()
2577 this.mvar1 = 131
2578 this.mvar2 = 132
2579 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002580 endclass
2581
Ernie Raelcf138d42023-09-06 20:45:03 +02002582 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002583 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002584 enddef
2585
2586 var oa = A.new()
2587 var ob = B.new()
2588 var oc = C.new()
2589
Ernie Raelcf138d42023-09-06 20:45:03 +02002590 assert_equal([111, 112], F2(oa))
2591 assert_equal([121, 122], F2(ob))
2592 assert_equal([131, 132], F2(oc))
2593 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002594 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002595
2596 # Access superclass interface members from subclass, mix variable order.
2597 # Two interfaces, one on A, one on B; each has both kinds of variables
2598 lines =<< trim END
2599 vim9script
2600
2601 interface I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002602 var mvar1: number
2603 var mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002604 endinterface
2605
2606 interface I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002607 var mvar3: number
2608 var mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002609 endinterface
2610
2611 class A implements I1
Doug Kearns74da0ee2023-12-14 20:26:26 +01002612 public static var svar1: number
2613 public static var svar2: number
2614 var mvar1: number
2615 var mvar2: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002616 def new()
2617 svar1 = 11
2618 svar2 = 12
2619 this.mvar1 = 111
2620 this.mvar2 = 112
2621 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002622 endclass
2623
2624 class B extends A implements I2
Doug Kearns74da0ee2023-12-14 20:26:26 +01002625 static var svar3: number
2626 static var svar4: number
2627 var mvar3: number
2628 var mvar4: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002629 def new()
2630 svar3 = 23
2631 svar4 = 24
2632 this.mvar1 = 121
2633 this.mvar2 = 122
2634 this.mvar3 = 123
2635 this.mvar4 = 124
2636 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002637 endclass
2638
2639 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01002640 public static var svar5: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002641 def new()
2642 svar5 = 1001
2643 this.mvar1 = 131
2644 this.mvar2 = 132
2645 this.mvar3 = 133
2646 this.mvar4 = 134
2647 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002648 endclass
2649
Ernie Raelcf138d42023-09-06 20:45:03 +02002650 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002651 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002652 enddef
2653
Ernie Raelcf138d42023-09-06 20:45:03 +02002654 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002655 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002656 enddef
2657
Ernie Raelcf138d42023-09-06 20:45:03 +02002658 var oa = A.new()
2659 var ob = B.new()
2660 var oc = C.new()
2661
Ernie Raelcf138d42023-09-06 20:45:03 +02002662 assert_equal([[111, 112]], [F2(oa)])
2663 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2664 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002665 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002666 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002667
2668 # Using two interface names without a space after the ","
2669 lines =<< trim END
2670 vim9script
2671 interface A
2672 endinterface
2673 interface B
2674 endinterface
2675 class C implements A,B
2676 endclass
2677 END
2678 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2679
2680 # No interface name after a comma
2681 lines =<< trim END
2682 vim9script
2683 interface A
2684 endinterface
2685 class B implements A,
2686 endclass
2687 END
2688 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2689
2690 # No interface name after implements
2691 lines =<< trim END
2692 vim9script
2693 class A implements
2694 endclass
2695 END
2696 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002697enddef
2698
Bram Moolenaard0200c82023-01-28 15:19:40 +00002699def Test_call_interface_method()
2700 var lines =<< trim END
2701 vim9script
2702 interface Base
2703 def Enter(): void
2704 endinterface
2705
2706 class Child implements Base
2707 def Enter(): void
2708 g:result ..= 'child'
2709 enddef
2710 endclass
2711
2712 def F(obj: Base)
2713 obj.Enter()
2714 enddef
2715
2716 g:result = ''
2717 F(Child.new())
2718 assert_equal('child', g:result)
2719 unlet g:result
2720 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002721 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002722
2723 lines =<< trim END
2724 vim9script
2725 class Base
2726 def Enter(): void
2727 g:result ..= 'base'
2728 enddef
2729 endclass
2730
2731 class Child extends Base
2732 def Enter(): void
2733 g:result ..= 'child'
2734 enddef
2735 endclass
2736
2737 def F(obj: Base)
2738 obj.Enter()
2739 enddef
2740
2741 g:result = ''
2742 F(Child.new())
2743 assert_equal('child', g:result)
2744 unlet g:result
2745 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002746 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002747
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002748 # method of interface returns a value
2749 lines =<< trim END
2750 vim9script
2751 interface Base
2752 def Enter(): string
2753 endinterface
2754
2755 class Child implements Base
2756 def Enter(): string
2757 g:result ..= 'child'
2758 return "/resource"
2759 enddef
2760 endclass
2761
2762 def F(obj: Base)
2763 var r = obj.Enter()
2764 g:result ..= r
2765 enddef
2766
2767 g:result = ''
2768 F(Child.new())
2769 assert_equal('child/resource', g:result)
2770 unlet g:result
2771 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002772 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002773
2774 lines =<< trim END
2775 vim9script
2776 class Base
2777 def Enter(): string
2778 return null_string
2779 enddef
2780 endclass
2781
2782 class Child extends Base
2783 def Enter(): string
2784 g:result ..= 'child'
2785 return "/resource"
2786 enddef
2787 endclass
2788
2789 def F(obj: Base)
2790 var r = obj.Enter()
2791 g:result ..= r
2792 enddef
2793
2794 g:result = ''
2795 F(Child.new())
2796 assert_equal('child/resource', g:result)
2797 unlet g:result
2798 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002799 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002800
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002801 # No class that implements the interface.
2802 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002803 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002804
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002805 interface IWithEE
2806 def Enter(): any
2807 def Exit(): void
2808 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002809
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002810 def With1(ee: IWithEE, F: func)
2811 var r = ee.Enter()
2812 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002813
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002814 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002815 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002816 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002817enddef
2818
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002819def Test_class_used_as_type()
2820 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002821 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002822
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002823 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002824 var x = 0
2825 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002826 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002827
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002828 var p: Point
2829 p = Point.new(2, 33)
2830 assert_equal(2, p.x)
2831 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002832 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002833 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002834
2835 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002836 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002837
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002838 interface HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002839 var x: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002840 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002841
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002842 class Point implements HasX
Doug Kearns74da0ee2023-12-14 20:26:26 +01002843 var x = 0
2844 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002845 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002846
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002847 var p: Point
2848 p = Point.new(2, 33)
2849 var hx = p
2850 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002851 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002852 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002853
2854 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002855 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002856
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002857 class Point
Doug Kearns74da0ee2023-12-14 20:26:26 +01002858 var x = 0
2859 var y = 0
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002860 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002862 var p: Point
2863 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002864 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002865 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002866enddef
2867
Bram Moolenaar83677162023-01-08 19:54:10 +00002868def Test_class_extends()
2869 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002870 vim9script
2871 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002872 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002873 def GetOne(): number
2874 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002875 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002876 endclass
2877 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002878 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002879 def GetTotal(): number
2880 return this.one + this.two
2881 enddef
2882 endclass
2883 var o = Child.new()
2884 assert_equal(1, o.one)
2885 assert_equal(2, o.two)
2886 assert_equal(1, o.GetOne())
2887 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002888 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002889 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002890
2891 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002892 vim9script
2893 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002894 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002895 endclass
2896 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002897 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002898 endclass
2899 var o = Child.new(3, 44)
2900 assert_equal(3, o.one)
2901 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002903 v9.CheckSourceSuccess(lines)
2904
2905 lines =<< trim END
2906 vim9script
2907 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002908 var one = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002909 endclass
2910 class Child extends Base extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002911 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002912 endclass
2913 END
2914 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2915
2916 lines =<< trim END
2917 vim9script
2918 class Child extends BaseClass
Doug Kearns74da0ee2023-12-14 20:26:26 +01002919 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002920 endclass
2921 END
2922 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2923
2924 lines =<< trim END
2925 vim9script
2926 var SomeVar = 99
2927 class Child extends SomeVar
Doug Kearns74da0ee2023-12-14 20:26:26 +01002928 var two = 2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 endclass
2930 END
2931 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2932
2933 lines =<< trim END
2934 vim9script
2935 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002936 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002937 def ToString(): string
2938 return this.name
2939 enddef
2940 endclass
2941
2942 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002943 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002944 def ToString(): string
2945 return super.ToString() .. ': ' .. this.age
2946 enddef
2947 endclass
2948
2949 var o = Child.new('John', 42)
2950 assert_equal('John: 42', o.ToString())
2951 END
2952 v9.CheckSourceSuccess(lines)
2953
2954 lines =<< trim END
2955 vim9script
2956 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002957 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 def ToString(): number
2959 return this.age
2960 enddef
2961 def ToString(): string
2962 return this.age
2963 enddef
2964 endclass
2965 END
2966 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2967
2968 lines =<< trim END
2969 vim9script
2970 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01002971 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002972 def ToString(): string
2973 return super .ToString() .. ': ' .. this.age
2974 enddef
2975 endclass
2976 var o = Child.new(42)
2977 echo o.ToString()
2978 END
2979 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2980
2981 lines =<< trim END
2982 vim9script
2983 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01002984 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002985 def ToString(): string
2986 return this.name
2987 enddef
2988 endclass
2989
2990 var age = 42
2991 def ToString(): string
2992 return super.ToString() .. ': ' .. age
2993 enddef
2994 echo ToString()
2995 END
2996 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2997
2998 lines =<< trim END
2999 vim9script
3000 class Child
Doug Kearns74da0ee2023-12-14 20:26:26 +01003001 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003002 def ToString(): string
3003 return super.ToString() .. ': ' .. this.age
3004 enddef
3005 endclass
3006 var o = Child.new(42)
3007 echo o.ToString()
3008 END
3009 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
3010
3011 lines =<< trim END
3012 vim9script
3013 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003014 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003015 static def ToString(): string
3016 return 'Base class'
3017 enddef
3018 endclass
3019
3020 class Child extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003021 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003022 def ToString(): string
3023 return Base.ToString() .. ': ' .. this.age
3024 enddef
3025 endclass
3026
3027 var o = Child.new('John', 42)
3028 assert_equal('Base class: 42', o.ToString())
3029 END
3030 v9.CheckSourceSuccess(lines)
3031
3032 lines =<< trim END
3033 vim9script
3034 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003035 var value = 1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003036 def new(init: number)
3037 this.value = number + 1
3038 enddef
3039 endclass
3040 class Child extends Base
3041 def new()
3042 this.new(3)
3043 enddef
3044 endclass
3045 var c = Child.new()
3046 END
3047 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003048
3049 # base class with more than one object member
3050 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003051 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003052
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003053 class Result
Doug Kearns74da0ee2023-12-14 20:26:26 +01003054 var success: bool
3055 var value: any = null
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003056 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003057
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003058 class Success extends Result
3059 def new(this.value = v:none)
3060 this.success = true
3061 enddef
3062 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003063
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003064 var v = Success.new('asdf')
3065 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00003066 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003067 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003068
3069 # class name after "extends" doesn't end in a space or NUL character
3070 lines =<< trim END
3071 vim9script
3072 class A
3073 endclass
3074 class B extends A"
3075 endclass
3076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003077 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00003078enddef
3079
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003080def Test_using_base_class()
3081 var lines =<< trim END
3082 vim9script
3083
3084 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 def Enter(): any
3086 return null
3087 enddef
3088 def Exit(resource: any): void
3089 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003090 endclass
3091
3092 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003093 def Enter(): any
3094 return 42
3095 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003096
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003097 def Exit(resource: number): void
3098 g:result ..= '/exit'
3099 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003100 endclass
3101
3102 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003103 var r = ee.Enter()
3104 try
3105 g:result ..= r
3106 finally
3107 g:result ..= '/finally'
3108 ee.Exit(r)
3109 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003110 enddef
3111
3112 g:result = ''
3113 With(ChildEE.new())
3114 assert_equal('42/finally/exit', g:result)
3115 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003116 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003117 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01003118
3119 # Using super, Child invokes Base method which has optional arg. #12471
3120 lines =<< trim END
3121 vim9script
3122
3123 class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003124 var success: bool = false
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003125 def Method(arg = 0)
3126 this.success = true
3127 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003128 endclass
3129
3130 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 def new()
3132 super.Method()
3133 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01003134 endclass
3135
3136 var obj = Child.new()
3137 assert_equal(true, obj.success)
3138 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003139 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003140enddef
3141
Bram Moolenaara86655a2023-01-12 17:06:27 +00003142def Test_class_import()
3143 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003144 vim9script
3145 export class Animal
Doug Kearns74da0ee2023-12-14 20:26:26 +01003146 var kind: string
3147 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003148 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003149 END
3150 writefile(lines, 'Xanimal.vim', 'D')
3151
3152 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003153 vim9script
3154 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003155
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003156 var a: animal.Animal
3157 a = animal.Animal.new('fish', 'Eric')
3158 assert_equal('fish', a.kind)
3159 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003160
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003161 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3162 assert_equal('cat', b.kind)
3163 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003164 END
3165 v9.CheckScriptSuccess(lines)
3166enddef
3167
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003168" Test for importing a class into a legacy script and calling the class method
3169def Test_class_method_from_legacy_script()
3170 var lines =<< trim END
3171 vim9script
3172 export class A
3173 static var name: string = 'a'
3174 static def SetName(n: string)
3175 name = n
3176 enddef
3177 endclass
3178 END
3179 writefile(lines, 'Xvim9export.vim', 'D')
3180
3181 lines =<< trim END
3182 import './Xvim9export.vim' as vim9
3183
3184 call s:vim9.A.SetName('b')
3185 call assert_equal('b', s:vim9.A.name)
3186 END
3187 v9.CheckScriptSuccess(lines)
3188enddef
3189
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003190" Test for implementing an imported interface
3191def Test_implement_imported_interface()
3192 var lines =<< trim END
3193 vim9script
3194 export interface Imp_Intf1
3195 def Fn1(): number
3196 endinterface
3197 export interface Imp_Intf2
3198 def Fn2(): number
3199 endinterface
3200 END
3201 writefile(lines, 'Ximportinterface.vim', 'D')
3202
3203 lines =<< trim END
3204 vim9script
3205 import './Ximportinterface.vim' as Xintf
3206
3207 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3208 def Fn1(): number
3209 return 10
3210 enddef
3211 def Fn2(): number
3212 return 20
3213 enddef
3214 endclass
3215 var a = A.new()
3216 assert_equal(10, a.Fn1())
3217 assert_equal(20, a.Fn2())
3218 END
3219 v9.CheckScriptSuccess(lines)
3220enddef
3221
3222" Test for extending an imported class
3223def Test_extend_imported_class()
3224 var lines =<< trim END
3225 vim9script
3226 export class Imp_C1
3227 def Fn1(): number
3228 return 5
3229 enddef
3230 endclass
3231 END
3232 writefile(lines, 'Xextendimportclass.vim', 'D')
3233
3234 lines =<< trim END
3235 vim9script
3236 import './Xextendimportclass.vim' as XClass
3237
3238 class A extends XClass.Imp_C1
3239 endclass
3240 var a = A.new()
3241 assert_equal(5, a.Fn1())
3242 END
3243 v9.CheckScriptSuccess(lines)
3244enddef
3245
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003246def Test_abstract_class()
3247 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003248 vim9script
3249 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003250 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003251 endclass
3252 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003253 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003254 endclass
3255 var p: Base = Person.new('Peter', 42)
3256 assert_equal('Peter', p.name)
3257 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003258 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003259 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003260
3261 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003262 vim9script
3263 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003264 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003265 endclass
3266 class Person extends Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003267 var age: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003268 endclass
3269 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003270 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003271 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003272
3273 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003274 abstract class Base
Doug Kearns74da0ee2023-12-14 20:26:26 +01003275 var name: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003276 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003278 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003279
Yegappan Lakshmananac773182024-04-27 11:36:12 +02003280 # Additional commands after "abstract class"
3281 lines =<< trim END
3282 vim9script
3283 abstract class Something | var x = []
3284 endclass
3285 END
3286 v9.CheckSourceFailure(lines, "E488: Trailing characters: | var x = []", 2)
3287
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003288 # Abstract class cannot have a "new" function
3289 lines =<< trim END
3290 vim9script
3291 abstract class Base
3292 def new()
3293 enddef
3294 endclass
3295 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003296 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Yegappan Lakshmananf1750ca2024-04-02 20:41:04 +02003297
3298 # extending an abstract class with class methods and variables
3299 lines =<< trim END
3300 vim9script
3301 abstract class A
3302 static var s: string = 'vim'
3303 static def Fn(): list<number>
3304 return [10]
3305 enddef
3306 endclass
3307 class B extends A
3308 endclass
3309 var b = B.new()
3310 assert_equal('vim', A.s)
3311 assert_equal([10], A.Fn())
3312 END
3313 v9.CheckScriptSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003314enddef
3315
Bram Moolenaar486fc252023-01-18 14:51:07 +00003316def Test_closure_in_class()
3317 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003318 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003319
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003320 class Foo
Doug Kearns74da0ee2023-12-14 20:26:26 +01003321 var y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003322
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003323 def new()
3324 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3325 enddef
3326 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003327
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003328 Foo.new()
3329 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003330 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003331 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003332enddef
3333
Ernie Rael9ed53752023-12-11 17:40:46 +01003334def Test_construct_object_from_legacy()
3335 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003336 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003337 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003338
Ernie Rael9ed53752023-12-11 17:40:46 +01003339 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003340
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003341 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003342 def new(arg: string)
3343 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003344 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003345 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003346
Ernie Rael9ed53752023-12-11 17:40:46 +01003347 export def CreateA(...args: list<any>): A
3348 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003349 enddef
3350
Ernie Rael9ed53752023-12-11 17:40:46 +01003351 g:P = CreateA
3352 legacy call g:P('some_arg')
3353 assert_equal(true, newCalled)
3354 unlet g:P
3355 END
3356 v9.CheckSourceSuccess(lines)
3357
3358 lines =<< trim END
3359 vim9script
3360
3361 var newCalled = false
3362
3363 class A
3364 static def CreateA(options = {}): any
3365 return A.new()
3366 enddef
3367 def new()
3368 newCalled = true
3369 enddef
3370 endclass
3371
3372 g:P = A.CreateA
3373 legacy call g:P()
3374 assert_equal(true, newCalled)
3375 unlet g:P
3376 END
3377 v9.CheckSourceSuccess(lines)
3378
3379 # This also tests invoking "new()" with "call"
3380 lines =<< trim END
3381 vim9script
3382
3383 var createdObject: any
3384
3385 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003386 var val1: number
3387 var val2: number
Ernie Rael9ed53752023-12-11 17:40:46 +01003388 static def CreateA(...args: list<any>): any
3389 createdObject = call(A.new, args)
3390 return createdObject
3391 enddef
3392 endclass
3393
3394 g:P = A.CreateA
3395 legacy call g:P(3, 5)
3396 assert_equal(3, createdObject.val1)
3397 assert_equal(5, createdObject.val2)
3398 legacy call g:P()
3399 assert_equal(0, createdObject.val1)
3400 assert_equal(0, createdObject.val2)
3401 legacy call g:P(7)
3402 assert_equal(7, createdObject.val1)
3403 assert_equal(0, createdObject.val2)
3404 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003405 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003406 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003407enddef
3408
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003409def Test_defer_with_object()
3410 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003411 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003412
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003413 class CWithEE
3414 def Enter()
3415 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003416 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003417 def Exit()
3418 g:result ..= "exited"
3419 enddef
3420 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003421
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003422 def With(ee: CWithEE, F: func)
3423 ee.Enter()
3424 defer ee.Exit()
3425 F()
3426 enddef
3427
3428 g:result = ''
3429 var obj = CWithEE.new()
3430 obj->With(() => {
3431 g:result ..= "called/"
3432 })
3433 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003434 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003435 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003436 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003437
3438 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003439 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003441 class BaseWithEE
3442 def Enter()
3443 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003444 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003445 def Exit()
3446 g:result ..= "exited-base"
3447 enddef
3448 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003449
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003450 class CWithEE extends BaseWithEE
3451 def Enter()
3452 g:result ..= "entered-child/"
3453 enddef
3454 def Exit()
3455 g:result ..= "exited-child"
3456 enddef
3457 endclass
3458
3459 def With(ee: BaseWithEE, F: func)
3460 ee.Enter()
3461 defer ee.Exit()
3462 F()
3463 enddef
3464
3465 g:result = ''
3466 var obj = CWithEE.new()
3467 obj->With(() => {
3468 g:result ..= "called/"
3469 })
3470 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003471 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003472 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003473 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003474enddef
3475
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003476" The following test used to crash Vim (Github issue #12676)
3477def Test_extends_method_crashes_vim()
3478 var lines =<< trim END
3479 vim9script
3480
3481 class Observer
3482 endclass
3483
3484 class Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003485 var value: any
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003486
3487 def Set(v: any)
3488 if v != this.value
3489 this.value = v
3490 endif
3491 enddef
3492
3493 def Register(observer: Observer)
3494 enddef
3495 endclass
3496
3497 class Bool extends Property
Doug Kearns74da0ee2023-12-14 20:26:26 +01003498 var value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003499 endclass
3500
3501 def Observe(obj: Property, who: Observer)
3502 obj.Register(who)
3503 enddef
3504
3505 var p = Bool.new(false)
3506 var myObserver = Observer.new()
3507
3508 Observe(p, myObserver)
3509
3510 p.Set(true)
3511 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003512 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003513enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003514
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003515" Test for calling a method in a class that is extended
3516def Test_call_method_in_extended_class()
3517 var lines =<< trim END
3518 vim9script
3519
3520 var prop_init_called = false
3521 var prop_register_called = false
3522
3523 class Property
3524 def Init()
3525 prop_init_called = true
3526 enddef
3527
3528 def Register()
3529 prop_register_called = true
3530 enddef
3531 endclass
3532
3533 class Bool extends Property
3534 endclass
3535
3536 def Observe(obj: Property)
3537 obj.Register()
3538 enddef
3539
3540 var p = Property.new()
3541 Observe(p)
3542
3543 p.Init()
3544 assert_true(prop_init_called)
3545 assert_true(prop_register_called)
3546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003547 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003548enddef
3549
LemonBoyafe04662023-08-23 21:08:11 +02003550def Test_instanceof()
3551 var lines =<< trim END
3552 vim9script
3553
3554 class Base1
3555 endclass
3556
3557 class Base2 extends Base1
3558 endclass
3559
3560 interface Intf1
3561 endinterface
3562
3563 class Mix1 implements Intf1
3564 endclass
3565
3566 class Base3 extends Mix1
3567 endclass
3568
Ernie Rael2025af12023-12-12 16:58:00 +01003569 type AliasBase1 = Base1
3570 type AliasBase2 = Base2
3571 type AliasIntf1 = Intf1
3572 type AliasMix1 = Mix1
3573
LemonBoyafe04662023-08-23 21:08:11 +02003574 var b1 = Base1.new()
3575 var b2 = Base2.new()
3576 var b3 = Base3.new()
3577
3578 assert_true(instanceof(b1, Base1))
3579 assert_true(instanceof(b2, Base1))
3580 assert_false(instanceof(b1, Base2))
3581 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003582 assert_true(instanceof(b3, Base1, Base2, Intf1))
3583
3584 assert_true(instanceof(b1, AliasBase1))
3585 assert_true(instanceof(b2, AliasBase1))
3586 assert_false(instanceof(b1, AliasBase2))
3587 assert_true(instanceof(b3, AliasMix1))
3588 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003589
3590 def Foo()
3591 var a1 = Base1.new()
3592 var a2 = Base2.new()
3593 var a3 = Base3.new()
3594
3595 assert_true(instanceof(a1, Base1))
3596 assert_true(instanceof(a2, Base1))
3597 assert_false(instanceof(a1, Base2))
3598 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003599 assert_true(instanceof(a3, Base1, Base2, Intf1))
3600
3601 assert_true(instanceof(a1, AliasBase1))
3602 assert_true(instanceof(a2, AliasBase1))
3603 assert_false(instanceof(a1, AliasBase2))
3604 assert_true(instanceof(a3, AliasMix1))
3605 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003606 enddef
3607 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003608
3609 var o_null: Base1
3610 assert_false(instanceof(o_null, Base1))
3611
LemonBoyafe04662023-08-23 21:08:11 +02003612 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003613 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003614
3615 lines =<< trim END
3616 vim9script
3617
3618 class Base1
3619 endclass
3620 instanceof(Base1.new())
3621 END
3622 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3623
3624 lines =<< trim END
3625 vim9script
3626
3627 class Base1
3628 endclass
3629 def F()
3630 instanceof(Base1.new())
3631 enddef
3632 F()
3633 END
3634 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3635
3636 lines =<< trim END
3637 vim9script
3638
3639 class Base1
3640 endclass
3641
3642 class Base2
3643 endclass
3644
3645 var o = Base2.new()
3646 instanceof(o, Base1, Base2, 3)
3647 END
3648 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3649
3650 lines =<< trim END
3651 vim9script
3652
3653 class Base1
3654 endclass
3655
3656 class Base2
3657 endclass
3658
3659 def F()
3660 var o = Base2.new()
3661 instanceof(o, Base1, Base2, 3)
3662 enddef
3663 F()
3664 END
3665 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003666enddef
3667
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003668" Test for calling a method in the parent class that is extended partially.
3669" This used to fail with the 'E118: Too many arguments for function: Text' error
3670" message (Github issue #12524).
3671def Test_call_method_in_parent_class()
3672 var lines =<< trim END
3673 vim9script
3674
3675 class Widget
Doug Kearns74da0ee2023-12-14 20:26:26 +01003676 var _lnum: number = 1
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003677
3678 def SetY(lnum: number)
3679 this._lnum = lnum
3680 enddef
3681
3682 def Text(): string
3683 return ''
3684 enddef
3685 endclass
3686
3687 class Foo extends Widget
3688 def Text(): string
3689 return '<Foo>'
3690 enddef
3691 endclass
3692
3693 def Stack(w1: Widget, w2: Widget): list<Widget>
3694 w1.SetY(1)
3695 w2.SetY(2)
3696 return [w1, w2]
3697 enddef
3698
3699 var foo1 = Foo.new()
3700 var foo2 = Foo.new()
3701 var l = Stack(foo1, foo2)
3702 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003703 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003704enddef
3705
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003706" Test for calling methods from three levels of classes
3707def Test_multi_level_method_call()
3708 var lines =<< trim END
3709 vim9script
3710
3711 var A_func1: number = 0
3712 var A_func2: number = 0
3713 var A_func3: number = 0
3714 var B_func2: number = 0
3715 var B_func3: number = 0
3716 var C_func3: number = 0
3717
3718 class A
3719 def Func1()
3720 A_func1 += 1
3721 enddef
3722
3723 def Func2()
3724 A_func2 += 1
3725 enddef
3726
3727 def Func3()
3728 A_func3 += 1
3729 enddef
3730 endclass
3731
3732 class B extends A
3733 def Func2()
3734 B_func2 += 1
3735 enddef
3736
3737 def Func3()
3738 B_func3 += 1
3739 enddef
3740 endclass
3741
3742 class C extends B
3743 def Func3()
3744 C_func3 += 1
3745 enddef
3746 endclass
3747
3748 def A_CallFuncs(a: A)
3749 a.Func1()
3750 a.Func2()
3751 a.Func3()
3752 enddef
3753
3754 def B_CallFuncs(b: B)
3755 b.Func1()
3756 b.Func2()
3757 b.Func3()
3758 enddef
3759
3760 def C_CallFuncs(c: C)
3761 c.Func1()
3762 c.Func2()
3763 c.Func3()
3764 enddef
3765
3766 var cobj = C.new()
3767 A_CallFuncs(cobj)
3768 B_CallFuncs(cobj)
3769 C_CallFuncs(cobj)
3770 assert_equal(3, A_func1)
3771 assert_equal(0, A_func2)
3772 assert_equal(0, A_func3)
3773 assert_equal(3, B_func2)
3774 assert_equal(0, B_func3)
3775 assert_equal(3, C_func3)
3776 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003777 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003778enddef
3779
3780" Test for using members from three levels of classes
3781def Test_multi_level_member_access()
3782 var lines =<< trim END
3783 vim9script
3784
3785 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003786 public var val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003787 endclass
3788
3789 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003790 public var val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003791 endclass
3792
3793 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01003794 public var val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003795 endclass
3796
3797 def A_members(a: A)
3798 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003799 enddef
3800
3801 def B_members(b: B)
3802 b.val1 += 1
3803 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003804 enddef
3805
3806 def C_members(c: C)
3807 c.val1 += 1
3808 c.val2 += 1
3809 c.val3 += 1
3810 enddef
3811
3812 var cobj = C.new()
3813 A_members(cobj)
3814 B_members(cobj)
3815 C_members(cobj)
3816 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003817 assert_equal(2, cobj.val2)
3818 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003819 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003820 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003821enddef
3822
LemonBoy0ffc17a2023-08-20 18:09:11 +02003823" Test expansion of <stack> with class methods.
3824def Test_stack_expansion_with_methods()
3825 var lines =<< trim END
3826 vim9script
3827
3828 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003829 def M1()
3830 F0()
3831 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003832 endclass
3833
3834 def F0()
Ernie Rael16cdfa62024-04-02 19:05:39 +02003835 assert_match('<SNR>\d\+_F\[1\]\.\.<SNR>\d\+_C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
LemonBoy0ffc17a2023-08-20 18:09:11 +02003836 enddef
3837
3838 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003839 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003840 enddef
3841
3842 F()
3843 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003844 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003845enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003846
3847" Test the return type of the new() constructor
3848def Test_new_return_type()
3849 # new() uses the default return type and there is no return statement
3850 var lines =<< trim END
3851 vim9script
3852
3853 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003854 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003855
3856 def new(this._bufnr)
3857 if !bufexists(this._bufnr)
3858 this._bufnr = -1
3859 endif
3860 enddef
3861 endclass
3862
3863 var c = C.new(12345)
3864 assert_equal('object<C>', typename(c))
3865
3866 var v1: C
3867 v1 = C.new(12345)
3868 assert_equal('object<C>', typename(v1))
3869
3870 def F()
3871 var v2: C
3872 v2 = C.new(12345)
3873 assert_equal('object<C>', typename(v2))
3874 enddef
3875 F()
3876 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003877 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003878
3879 # new() uses the default return type and an empty 'return' statement
3880 lines =<< trim END
3881 vim9script
3882
3883 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003884 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003885
3886 def new(this._bufnr)
3887 if !bufexists(this._bufnr)
3888 this._bufnr = -1
3889 return
3890 endif
3891 enddef
3892 endclass
3893
3894 var c = C.new(12345)
3895 assert_equal('object<C>', typename(c))
3896
3897 var v1: C
3898 v1 = C.new(12345)
3899 assert_equal('object<C>', typename(v1))
3900
3901 def F()
3902 var v2: C
3903 v2 = C.new(12345)
3904 assert_equal('object<C>', typename(v2))
3905 enddef
3906 F()
3907 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003908 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003909
3910 # new() uses "any" return type and returns "this"
3911 lines =<< trim END
3912 vim9script
3913
3914 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003915 var _bufnr: number
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003916
3917 def new(this._bufnr): any
3918 if !bufexists(this._bufnr)
3919 this._bufnr = -1
3920 return this
3921 endif
3922 enddef
3923 endclass
3924 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003925 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003926
3927 # new() uses 'Dict' return type and returns a Dict
3928 lines =<< trim END
3929 vim9script
3930
3931 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003932 var _state: dict<any>
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003933
3934 def new(): dict<any>
3935 this._state = {}
3936 return this._state
3937 enddef
3938 endclass
3939
3940 var c = C.new()
3941 assert_equal('object<C>', typename(c))
3942 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003943 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003944enddef
3945
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003946" Test for checking a member initialization type at run time.
3947def Test_runtime_type_check_for_member_init()
3948 var lines =<< trim END
3949 vim9script
3950
3951 var retnum: bool = false
3952
3953 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003954 retnum = !retnum
3955 if retnum
3956 return 1
3957 else
3958 return "hello"
3959 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003960 enddef
3961
3962 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003963 var _foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003964 endclass
3965
3966 var c1 = C.new()
3967 var c2 = C.new()
3968 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003969 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003970enddef
3971
3972" Test for locking a variable referring to an object and reassigning to another
3973" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003974def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003975 var lines =<< trim END
3976 vim9script
3977
3978 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01003979 var val: number
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003980 def new(this.val)
3981 enddef
3982 endclass
3983
3984 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3985 lockvar 2 some_dict
3986
3987 var current: C
3988 current = some_dict['c']
3989 assert_equal(3, current.val)
3990 current = some_dict['b']
3991 assert_equal(2, current.val)
3992
3993 def F()
3994 current = some_dict['c']
3995 enddef
3996
3997 def G()
3998 current = some_dict['b']
3999 enddef
4000
4001 F()
4002 assert_equal(3, current.val)
4003 G()
4004 assert_equal(2, current.val)
4005 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004006 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02004007enddef
4008
Ernie Raelee865f32023-09-29 19:53:55 +02004009" Test trying to lock an object variable from various places
4010def Test_lockvar_object_variable()
4011 # An object variable lockvar has several cases:
4012 # object method, scriptlevel, scriplevel from :def, :def arg
4013 # method arg, static method arg.
4014 # Also different depths
4015
Ernie Raelee865f32023-09-29 19:53:55 +02004016 #
4017 # lockvar of read-only object variable
4018 #
4019
4020 # read-only lockvar from object method
4021 var lines =<< trim END
4022 vim9script
4023
4024 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004025 var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004026 def Lock()
4027 lockvar this.val1
4028 enddef
4029 endclass
4030 var o = C.new(3)
4031 o.Lock()
4032 END
Ernie Rael64885642023-10-04 20:16:22 +02004033 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004034
4035 # read-only lockvar from scriptlevel
4036 lines =<< trim END
4037 vim9script
4038
4039 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004040 var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004041 endclass
4042 var o = C.new(3)
4043 lockvar o.val2
4044 END
4045 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
4046
4047 # read-only lockvar of scriptlevel variable from def
4048 lines =<< trim END
4049 vim9script
4050
4051 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004052 var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004053 endclass
4054 var o = C.new(3)
4055 def Lock()
4056 lockvar o.val3
4057 enddef
4058 Lock()
4059 END
4060 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
4061
4062 # read-only lockvar of def argument variable
4063 lines =<< trim END
4064 vim9script
4065
4066 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004067 var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004068 endclass
4069 def Lock(o: C)
4070 lockvar o.val4
4071 enddef
4072 Lock(C.new(3))
4073 END
4074 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
4075
4076 # TODO: the following tests use type "any" for argument. Need a run time
4077 # check for access. Probably OK as is for now.
4078
4079 # read-only lockvar from object method arg
4080 lines =<< trim END
4081 vim9script
4082
4083 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004084 var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004085 def Lock(o_any: any)
4086 lockvar o_any.val5
4087 enddef
4088 endclass
4089 var o = C.new(3)
4090 o.Lock(C.new(5))
4091 END
Ernie Rael64885642023-10-04 20:16:22 +02004092 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004093
4094 # read-only lockvar from class method arg
4095 lines =<< trim END
4096 vim9script
4097
4098 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004099 var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004100 static def Lock(o_any: any)
4101 lockvar o_any.val6
4102 enddef
4103 endclass
4104 var o = C.new(3)
4105 C.Lock(o)
4106 END
Ernie Rael64885642023-10-04 20:16:22 +02004107 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004108
4109 #
4110 # lockvar of public object variable
4111 #
4112
4113 # lockvar from object method
4114 lines =<< trim END
4115 vim9script
4116
4117 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004118 public var val1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004119 def Lock()
4120 lockvar this.val1
4121 enddef
4122 endclass
4123 var o = C.new(3)
4124 o.Lock()
4125 END
4126 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
4127
4128 # lockvar from scriptlevel
4129 lines =<< trim END
4130 vim9script
4131
4132 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004133 public var val2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004134 endclass
4135 var o = C.new(3)
4136 lockvar o.val2
4137 END
4138 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
4139
4140 # lockvar of scriptlevel variable from def
4141 lines =<< trim END
4142 vim9script
4143
4144 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004145 public var val3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004146 endclass
4147 var o = C.new(3)
4148 def Lock()
4149 lockvar o.val3
4150 enddef
4151 Lock()
4152 END
4153 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
4154
4155 # lockvar of def argument variable
4156 lines =<< trim END
4157 vim9script
4158
4159 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004160 public var val4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004161 endclass
4162 def Lock(o: C)
4163 lockvar o.val4
4164 enddef
4165 Lock(C.new(3))
4166 END
4167 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
4168
4169 # lockvar from object method arg
4170 lines =<< trim END
4171 vim9script
4172
4173 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004174 public var val5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004175 def Lock(o_any: any)
4176 lockvar o_any.val5
4177 enddef
4178 endclass
4179 var o = C.new(3)
4180 o.Lock(C.new(5))
4181 END
4182 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4183
4184 # lockvar from class method arg
4185 lines =<< trim END
4186 vim9script
4187
4188 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004189 public var val6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004190 static def Lock(o_any: any)
4191 lockvar o_any.val6
4192 enddef
4193 endclass
4194 var o = C.new(3)
4195 C.Lock(o)
4196 END
4197 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4198enddef
4199
4200" Test trying to lock a class variable from various places
4201def Test_lockvar_class_variable()
4202
4203 # lockvar bare static from object method
4204 var lines =<< trim END
4205 vim9script
4206
4207 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004208 public static var sval1: number
Ernie Raelee865f32023-09-29 19:53:55 +02004209 def Lock()
4210 lockvar sval1
4211 enddef
4212 endclass
4213 var o = C.new()
4214 o.Lock()
4215 END
4216 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4217
4218 # lockvar C.static from object method
4219 lines =<< trim END
4220 vim9script
4221
4222 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004223 public static var sval2: number
Ernie Raelee865f32023-09-29 19:53:55 +02004224 def Lock()
4225 lockvar C.sval2
4226 enddef
4227 endclass
4228 var o = C.new()
4229 o.Lock()
4230 END
4231 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4232
4233 # lockvar bare static from class method
4234 lines =<< trim END
4235 vim9script
4236
4237 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004238 public static var sval3: number
Ernie Raelee865f32023-09-29 19:53:55 +02004239 static def Lock()
4240 lockvar sval3
4241 enddef
4242 endclass
4243 C.Lock()
4244 END
4245 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4246
4247 # lockvar C.static from class method
4248 lines =<< trim END
4249 vim9script
4250
4251 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004252 public static var sval4: number
Ernie Raelee865f32023-09-29 19:53:55 +02004253 static def Lock()
4254 lockvar C.sval4
4255 enddef
4256 endclass
4257 C.Lock()
4258 END
4259 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4260
4261 # lockvar C.static from script level
4262 lines =<< trim END
4263 vim9script
4264
4265 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004266 public static var sval5: number
Ernie Raelee865f32023-09-29 19:53:55 +02004267 endclass
4268 lockvar C.sval5
4269 END
4270 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4271
4272 # lockvar o.static from script level
4273 lines =<< trim END
4274 vim9script
4275
4276 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004277 public static var sval6: number
Ernie Raelee865f32023-09-29 19:53:55 +02004278 endclass
4279 var o = C.new()
4280 lockvar o.sval6
4281 END
4282 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4283enddef
4284
4285" Test locking an argument to :def
4286def Test_lockvar_argument()
4287 # Lockvar a function arg
4288 var lines =<< trim END
4289 vim9script
4290
4291 def Lock(val: any)
4292 lockvar val
4293 enddef
4294
4295 var d = {a: 1, b: 2}
4296 Lock(d)
4297
4298 d->extend({c: 3})
4299 END
4300 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4301
4302 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4303 # class member in "C". This tests lval_root_is_arg.
4304 lines =<< trim END
4305 vim9script
4306
4307 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004308 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004309 endclass
4310
4311 def Lock2(sval: any)
4312 lockvar sval
4313 enddef
4314
4315 var o = C.new()
4316 Lock2(o)
4317 END
4318 v9.CheckSourceSuccess(lines)
4319
4320 # Lock a class.
4321 lines =<< trim END
4322 vim9script
4323
4324 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004325 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004326 endclass
4327
4328 def Lock2(sval: any)
4329 lockvar sval
4330 enddef
4331
4332 Lock2(C)
4333 END
Ernie Raelb077b582023-12-14 20:11:44 +01004334 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004335
4336 # Lock an object.
4337 lines =<< trim END
4338 vim9script
4339
4340 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004341 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004342 endclass
4343
4344 def Lock2(sval: any)
4345 lockvar sval
4346 enddef
4347
4348 Lock2(C.new())
4349 END
4350 v9.CheckSourceSuccess(lines)
4351
4352 # In this case (unlike previous) "lockvar sval" is a class member.
4353 lines =<< trim END
4354 vim9script
4355
4356 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004357 public static var sval: list<number>
Ernie Raelee865f32023-09-29 19:53:55 +02004358 def Lock2()
4359 lockvar sval
4360 enddef
4361 endclass
4362
4363
4364 var o = C.new()
4365 o.Lock2()
4366 END
4367 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4368enddef
4369
4370" Test that this can be locked without error
4371def Test_lockvar_this()
4372 # lockvar this
4373 var lines =<< trim END
4374 vim9script
4375 class C
4376 def TLock()
4377 lockvar this
4378 enddef
4379 endclass
4380 var o = C.new()
4381 o.TLock()
4382 END
4383 v9.CheckSourceSuccess(lines)
4384
4385 # lockvar four (four letter word, but not this)
4386 lines =<< trim END
4387 vim9script
4388 class C
4389 def TLock4()
4390 var four: number
4391 lockvar four
4392 enddef
4393 endclass
4394 var o = C.new()
4395 o.TLock4()
4396 END
4397 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4398
4399 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4400 lines =<< trim END
4401 vim9script
4402 class C
4403 def TLock5()
4404 var this5: number
4405 lockvar this5
4406 enddef
4407 endclass
4408 var o = C.new()
4409 o.TLock5()
4410 END
4411 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4412enddef
4413
4414" Test some general lockvar cases
4415def Test_lockvar_general()
4416 # lockvar an object and a class. It does nothing
4417 var lines =<< trim END
4418 vim9script
4419 class C
4420 endclass
4421 var o = C.new()
4422 lockvar o
4423 lockvar C
4424 END
4425 v9.CheckSourceSuccess(lines)
4426
4427 # Lock a list element that's nested in an object variable from a :def
4428 lines =<< trim END
4429 vim9script
4430
4431 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004432 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004433 endclass
4434 def Lock2(obj: any)
4435 lockvar obj.val[1]
4436 enddef
4437
4438 var o = C.new()
4439 Lock2(o)
4440 o.val[0] = [9]
4441 assert_equal([ [9], [2], [3] ], o.val)
4442 try
4443 o.val[1] = [999]
4444 call assert_false(true, 'assign should have failed')
4445 catch
4446 assert_exception('E741:')
4447 endtry
4448 o.val[2] = [8]
4449 assert_equal([ [9], [2], [8] ], o.val)
4450 END
4451 v9.CheckSourceSuccess(lines)
4452
4453 # Lock a list element that's nested in an object variable from scriptlevel
4454 lines =<< trim END
4455 vim9script
4456
4457 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004458 public var val: list<list<number>> = [ [1], [2], [3] ]
Ernie Raelee865f32023-09-29 19:53:55 +02004459 endclass
4460
4461 var o = C.new()
4462 lockvar o.val[1]
4463 o.val[0] = [9]
4464 assert_equal([ [9], [2], [3] ], o.val)
4465 try
4466 o.val[1] = [999]
4467 call assert_false(true, 'assign should have failed')
4468 catch
4469 assert_exception('E741:')
4470 endtry
4471 o.val[2] = [8]
4472 assert_equal([ [9], [2], [8] ], o.val)
4473 END
4474 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004475
4476 # lock a script level variable from an object method
4477 lines =<< trim END
4478 vim9script
4479
4480 class C
4481 def Lock()
4482 lockvar l
4483 enddef
4484 endclass
4485
4486 var l = [1]
4487 C.new().Lock()
4488 l[0] = 11
4489 END
4490 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4491
Ernie Rael03042a22023-11-11 08:53:32 +01004492 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004493 # in an object fetched via a script level list
4494 lines =<< trim END
4495 vim9script
4496
4497 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004498 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004499 def Lock()
4500 lockvar lc[0]._v1[1]
4501 enddef
4502 endclass
4503
4504 var l = [[1], [2], [3]]
4505 var o = C.new(l)
4506 var lc: list<C> = [ o ]
4507
4508 o.Lock()
4509 l[0] = [22]
4510 l[1] = [33]
4511 END
4512 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4513
4514 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004515 # in a class that does not own the protected variable.
4516 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004517 # the same name.
4518 lines =<< trim END
4519 vim9script
4520
4521 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004522 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004523 def Lock(obj: any)
4524 lockvar lc[0]._v1[1]
4525 enddef
4526 endclass
4527
4528 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004529 var _v1: list<list<number>>
Ernie Rael64885642023-10-04 20:16:22 +02004530 endclass
4531
4532 var l = [[1], [2], [3]]
4533 var o = C.new(l)
4534 var lc: list<C> = [ o ]
4535
4536 var o2 = C2.new()
4537 o2.Lock(o)
4538 END
Ernie Rael03042a22023-11-11 08:53:32 +01004539 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004540enddef
4541
Ernie Rael9771b2a2023-10-07 22:05:40 +02004542" Test builtin islocked()
4543def Test_lockvar_islocked()
4544 # Can't lock class/object variable
4545 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004546 # Lock item of variable's value (a list item)
4547 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004548 var lines =<< trim END
4549 vim9script
4550
4551 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004552 var o0: list<list<number>> = [ [0], [1], [2]]
4553 var o1: list<list<number>> = [[10], [11], [12]]
4554 static var c0: list<list<number>> = [[20], [21], [22]]
4555 static var c1: list<list<number>> = [[30], [31], [32]]
Ernie Rael9771b2a2023-10-07 22:05:40 +02004556 endclass
4557
4558 def LockIt(arg: any)
4559 lockvar arg
4560 enddef
4561
4562 def UnlockIt(arg: any)
4563 unlockvar arg
4564 enddef
4565
4566 var obj = C.new()
4567 #lockvar obj.o1 # can't lock something you can't write to
4568
4569 try
4570 lockvar obj.o1 # can't lock something you can't write to
4571 call assert_false(1, '"lockvar obj.o1" should have failed')
4572 catch
4573 call assert_exception('E1335:')
4574 endtry
4575
4576 LockIt(obj.o1) # but can lock it's value
4577 assert_equal(1, islocked("obj.o1"))
4578 assert_equal(1, islocked("obj.o1[0]"))
4579 assert_equal(1, islocked("obj.o1[1]"))
4580 UnlockIt(obj.o1)
4581 assert_equal(0, islocked("obj.o1"))
4582 assert_equal(0, islocked("obj.o1[0]"))
4583
4584 lockvar obj.o1[0]
4585 assert_equal(0, islocked("obj.o1"))
4586 assert_equal(1, islocked("obj.o1[0]"))
4587 assert_equal(0, islocked("obj.o1[1]"))
4588 unlockvar obj.o1[0]
4589 assert_equal(0, islocked("obj.o1"))
4590 assert_equal(0, islocked("obj.o1[0]"))
4591
4592 # Same thing, but with a static
4593
4594 try
4595 lockvar C.c1 # can't lock something you can't write to
4596 call assert_false(1, '"lockvar C.c1" should have failed')
4597 catch
4598 call assert_exception('E1335:')
4599 endtry
4600
4601 LockIt(C.c1) # but can lock it's value
4602 assert_equal(1, islocked("C.c1"))
4603 assert_equal(1, islocked("C.c1[0]"))
4604 assert_equal(1, islocked("C.c1[1]"))
4605 UnlockIt(C.c1)
4606 assert_equal(0, islocked("C.c1"))
4607 assert_equal(0, islocked("C.c1[0]"))
4608
4609 lockvar C.c1[0]
4610 assert_equal(0, islocked("C.c1"))
4611 assert_equal(1, islocked("C.c1[0]"))
4612 assert_equal(0, islocked("C.c1[1]"))
4613 unlockvar C.c1[0]
4614 assert_equal(0, islocked("C.c1"))
4615 assert_equal(0, islocked("C.c1[0]"))
4616 END
4617 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004618
4619 # Do islocked() from an object method
4620 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004621 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004622 vim9script
4623
4624 var l0o0 = [ [0], [1], [2]]
4625 var l0o1 = [ [10], [11], [12]]
4626 var l0c0 = [[120], [121], [122]]
4627 var l0c1 = [[130], [131], [132]]
4628
4629 class C0
Doug Kearns74da0ee2023-12-14 20:26:26 +01004630 var o0: list<list<number>> = l0o0
4631 var o1: list<list<number>> = l0o1
4632 static var c0: list<list<number>> = l0c0
4633 static var c1: list<list<number>> = l0c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004634 def Islocked(arg: string): number
4635 return islocked(arg)
4636 enddef
4637 static def SIslocked(arg: string): number
4638 return islocked(arg)
4639 enddef
4640 endclass
4641
4642 var l2o0 = [[20000], [20001], [20002]]
4643 var l2o1 = [[20010], [20011], [20012]]
4644 var l2c0 = [[20120], [20121], [20122]]
4645 var l2c1 = [[20130], [20131], [20132]]
4646
4647 class C2
Doug Kearns74da0ee2023-12-14 20:26:26 +01004648 var o0: list<list<number>> = l2o0
4649 var o1: list<list<number>> = l2o1
4650 static var c0: list<list<number>> = l2c0
4651 static var c1: list<list<number>> = l2c1
Ernie Rael4c8da022023-10-11 21:35:11 +02004652 def Islocked(arg: string): number
4653 return islocked(arg)
4654 enddef
4655 static def SIslocked(arg: string): number
4656 return islocked(arg)
4657 enddef
4658 endclass
4659
4660 var obj0 = C0.new()
4661 var obj2 = C2.new()
4662
4663 var l = [ obj0, null_object, obj2 ]
4664
4665 # lock list, object func access through script var expr
4666 assert_equal(0, obj0.Islocked("l[0].o0"))
4667 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4668 lockvar l0o0
4669 assert_equal(1, obj0.Islocked("l[0].o0"))
4670 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4671
4672 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4673
4674 # lock list element, object func access through script var expr
4675 lockvar l0o1[1]
4676 assert_equal(0, obj0.Islocked("this.o1[0]"))
4677 assert_equal(1, obj0.Islocked("this.o1[1]"))
4678
4679 assert_equal(0, obj0.Islocked("this.o1"))
4680 lockvar l0o1
4681 assert_equal(1, obj0.Islocked("this.o1"))
4682 unlockvar l0o1
4683
4684 lockvar l0c1[1]
4685
4686 # static by class name member expr from same class
4687 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4688 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4689 # static by bare name member expr from same class
4690 assert_equal(0, obj0.Islocked("c1[0]"))
4691 assert_equal(1, obj0.Islocked("c1[1]"))
4692
4693 # static by class name member expr from other class
4694 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4695 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4696 # static by bare name member expr from other class
4697 assert_equal(0, obj2.Islocked("c1[0]"))
4698 assert_equal(0, obj2.Islocked("c1[1]"))
4699
4700
4701 # static by bare name in same class
4702 assert_equal(0, obj0.Islocked("c0"))
4703 lockvar l0c0
4704 assert_equal(1, obj0.Islocked("c0"))
4705
4706 #
4707 # similar stuff, but use static method
4708 #
4709
4710 unlockvar l0o0
4711
4712 # lock list, object func access through script var expr
4713 assert_equal(0, C0.SIslocked("l[0].o0"))
4714 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4715 lockvar l0o0
4716 assert_equal(1, C0.SIslocked("l[0].o0"))
4717 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4718
4719 unlockvar l0o1
4720
4721 # can't access "this" from class method
4722 try
4723 C0.SIslocked("this.o1[0]")
4724 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4725 catch
4726 call assert_exception('E121: Undefined variable: this')
4727 endtry
4728
4729 lockvar l0c1[1]
4730
4731 # static by class name member expr from same class
4732 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4733 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4734 # static by bare name member expr from same class
4735 assert_equal(0, C0.SIslocked("c1[0]"))
4736 assert_equal(1, C0.SIslocked("c1[1]"))
4737
4738 # static by class name member expr from other class
4739 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4740 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4741 # static by bare name member expr from other class
4742 assert_equal(0, C2.SIslocked("c1[0]"))
4743 assert_equal(0, C2.SIslocked("c1[1]"))
4744
4745
4746 # static by bare name in same class
4747 unlockvar l0c0
4748 assert_equal(0, C0.SIslocked("c0"))
4749 lockvar l0c0
4750 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004751 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004752 v9.CheckSourceSuccess(lines)
4753
4754 # Check islocked class/object from various places.
4755 lines =<< trim END
4756 vim9script
4757
4758 class C
4759 def Islocked(arg: string): number
4760 return islocked(arg)
4761 enddef
4762 static def SIslocked(arg: string): number
4763 return islocked(arg)
4764 enddef
4765 endclass
4766 var obj = C.new()
4767
4768 # object method
4769 assert_equal(0, obj.Islocked("this"))
4770 assert_equal(0, obj.Islocked("C"))
4771
4772 # class method
4773 ### assert_equal(0, C.SIslocked("this"))
4774 assert_equal(0, C.SIslocked("C"))
4775
4776 #script level
4777 var v: number
4778 v = islocked("C")
4779 assert_equal(0, v)
4780 v = islocked("obj")
4781 assert_equal(0, v)
4782 END
4783 v9.CheckSourceSuccess(lines)
4784enddef
4785
4786def Test_lockvar_islocked_notfound()
4787 # Try non-existent things
4788 var lines =<< trim END
4789 vim9script
4790
4791 class C
4792 def Islocked(arg: string): number
4793 return islocked(arg)
4794 enddef
4795 static def SIslocked(arg: string): number
4796 return islocked(arg)
4797 enddef
4798 endclass
4799 var obj = C.new()
4800 assert_equal(-1, obj.Islocked("anywhere"))
4801 assert_equal(-1, C.SIslocked("notanywhere"))
4802 END
4803 v9.CheckSourceSuccess(lines)
4804
4805 # Something not found of the form "name1.name2" is an error
4806 lines =<< trim END
4807 vim9script
4808
4809 islocked("one.two")
4810 END
4811 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4812
4813 lines =<< trim END
4814 vim9script
4815
4816 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01004817 var val = { key: "value" }
Ernie Rael4c8da022023-10-11 21:35:11 +02004818 def Islocked(arg: string): number
4819 return islocked(arg)
4820 enddef
4821 endclass
4822 var obj = C.new()
4823 obj.Islocked("this.val.not_there"))
4824 END
4825 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4826
4827 lines =<< trim END
4828 vim9script
4829
4830 class C
4831 def Islocked(arg: string): number
4832 return islocked(arg)
4833 enddef
4834 endclass
4835 var obj = C.new()
4836 obj.Islocked("this.notobjmember")
4837 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004838 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004839
4840 # access a script variable through methods
4841 lines =<< trim END
4842 vim9script
4843
4844 var l = [1]
4845 class C
4846 def Islocked(arg: string): number
4847 return islocked(arg)
4848 enddef
4849 static def SIslocked(arg: string): number
4850 return islocked(arg)
4851 enddef
4852 endclass
4853 var obj = C.new()
4854 assert_equal(0, obj.Islocked("l"))
4855 assert_equal(0, C.SIslocked("l"))
4856 lockvar l
4857 assert_equal(1, obj.Islocked("l"))
4858 assert_equal(1, C.SIslocked("l"))
4859 END
4860 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004861enddef
4862
Ernie Rael03042a22023-11-11 08:53:32 +01004863" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004864def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004865 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004866 var lines =<< trim END
4867 vim9script
4868
4869 class A
4870 def _Foo(): number
4871 return 1234
4872 enddef
4873 endclass
4874 var a = A.new()
4875 a._Foo()
4876 END
Ernie Rael03042a22023-11-11 08:53:32 +01004877 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004878
Ernie Rael03042a22023-11-11 08:53:32 +01004879 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004880 lines =<< trim END
4881 vim9script
4882
4883 class A
4884 def _Foo(): number
4885 return 1234
4886 enddef
4887 endclass
4888 def T()
4889 var a = A.new()
4890 a._Foo()
4891 enddef
4892 T()
4893 END
Ernie Rael03042a22023-11-11 08:53:32 +01004894 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004895
Ernie Rael03042a22023-11-11 08:53:32 +01004896 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004897 lines =<< trim END
4898 vim9script
4899
4900 class A
4901 def _Foo(): number
4902 return 1234
4903 enddef
4904 def Bar(): number
4905 return this._Foo()
4906 enddef
4907 endclass
4908 var a = A.new()
4909 assert_equal(1234, a.Bar())
4910 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004911 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004912
Ernie Rael03042a22023-11-11 08:53:32 +01004913 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004914 lines =<< trim END
4915 vim9script
4916
4917 class A
4918 def _Foo(): number
4919 return 1234
4920 enddef
4921 def Bar(): number
4922 return this._Foo()
4923 enddef
4924 endclass
4925 def T()
4926 var a = A.new()
4927 assert_equal(1234, a.Bar())
4928 enddef
4929 T()
4930 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004931 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004932
Ernie Rael03042a22023-11-11 08:53:32 +01004933 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004934 lines =<< trim END
4935 vim9script
4936
4937 class A
4938 def _Foo(): number
4939 return 1234
4940 enddef
4941 def Bar(): number
4942 return _Foo()
4943 enddef
4944 endclass
4945 var a = A.new()
4946 a.Bar()
4947 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004948 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004949
Ernie Rael03042a22023-11-11 08:53:32 +01004950 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004951 lines =<< trim END
4952 vim9script
4953
4954 class A
4955 def _Foo(): number
4956 return 1234
4957 enddef
4958 endclass
4959 A._Foo()
4960 END
Ernie Rael03042a22023-11-11 08:53:32 +01004961 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004962
Ernie Rael03042a22023-11-11 08:53:32 +01004963 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004964 lines =<< trim END
4965 vim9script
4966
4967 class A
4968 def _Foo()
4969 enddef
4970 def _Foo()
4971 enddef
4972 endclass
4973 var a = A.new()
4974 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004975 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004976
Ernie Rael03042a22023-11-11 08:53:32 +01004977 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004978 lines =<< trim END
4979 vim9script
4980
4981 class A
4982 def _Foo()
4983 enddef
4984 def Foo()
4985 enddef
4986 endclass
4987 var a = A.new()
4988 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004989 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004990
Ernie Rael03042a22023-11-11 08:53:32 +01004991 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004992 lines =<< trim END
4993 vim9script
4994
4995 class A
4996 def Foo()
4997 enddef
4998 def _Foo()
4999 enddef
5000 endclass
5001 var a = A.new()
5002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005003 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005004
Ernie Rael03042a22023-11-11 08:53:32 +01005005 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005006 lines =<< trim END
5007 vim9script
5008
5009 class A
5010 def Foo(): number
5011 return 100
5012 enddef
5013 def _Bar(): number
5014 return 200
5015 enddef
5016 def _Baz()
5017 assert_equal(100, this.Foo())
5018 assert_equal(200, this._Bar())
5019 enddef
5020 def T()
5021 this._Baz()
5022 enddef
5023 endclass
5024 var a = A.new()
5025 a.T()
5026 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005027 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005028
Ernie Rael03042a22023-11-11 08:53:32 +01005029 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005030 lines =<< trim END
5031 vim9script
5032
5033 class A
5034 def _Foo(): number
5035 return 100
5036 enddef
5037 endclass
5038 class B
5039 def Foo(): number
5040 var a = A.new()
5041 a._Foo()
5042 enddef
5043 endclass
5044 var b = B.new()
5045 b.Foo()
5046 END
Ernie Rael03042a22023-11-11 08:53:32 +01005047 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005048
Ernie Rael03042a22023-11-11 08:53:32 +01005049 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005050 lines =<< trim END
5051 vim9script
5052 class A
5053 def _Foo(): number
5054 return 1234
5055 enddef
5056 endclass
5057 class B extends A
5058 def Bar()
5059 enddef
5060 endclass
5061 class C extends B
5062 def Baz(): number
5063 return this._Foo()
5064 enddef
5065 endclass
5066 var c = C.new()
5067 assert_equal(1234, c.Baz())
5068 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005069 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005070
Ernie Rael03042a22023-11-11 08:53:32 +01005071 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005072 lines =<< trim END
5073 vim9script
5074 class A
5075 def _Foo(): number
5076 return 1234
5077 enddef
5078 endclass
5079 class B extends A
5080 def Bar()
5081 enddef
5082 endclass
5083 class C extends B
5084 def Baz(): number
5085 enddef
5086 endclass
5087 var c = C.new()
5088 assert_equal(1234, c._Foo())
5089 END
Ernie Rael03042a22023-11-11 08:53:32 +01005090 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005091
5092 # Using "_" prefix in a method name should fail outside of a class
5093 lines =<< trim END
5094 vim9script
5095 def _Foo(): number
5096 return 1234
5097 enddef
5098 var a = _Foo()
5099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005100 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005101enddef
5102
Ernie Rael03042a22023-11-11 08:53:32 +01005103" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005104def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01005105 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005106 var lines =<< trim END
5107 vim9script
5108
5109 class A
5110 static def _Foo(): number
5111 return 1234
5112 enddef
5113 endclass
5114 A._Foo()
5115 END
Ernie Rael03042a22023-11-11 08:53:32 +01005116 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005117
Ernie Rael03042a22023-11-11 08:53:32 +01005118 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005119 lines =<< trim END
5120 vim9script
5121
5122 class A
5123 static def _Foo(): number
5124 return 1234
5125 enddef
5126 endclass
5127 def T()
5128 A._Foo()
5129 enddef
5130 T()
5131 END
Ernie Rael03042a22023-11-11 08:53:32 +01005132 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005133
Ernie Rael03042a22023-11-11 08:53:32 +01005134 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005135 lines =<< trim END
5136 vim9script
5137
5138 class A
5139 static def _Foo(): number
5140 return 1234
5141 enddef
5142 endclass
5143 var a = A.new()
5144 a._Foo()
5145 END
Ernie Rael03042a22023-11-11 08:53:32 +01005146 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005147
Ernie Rael03042a22023-11-11 08:53:32 +01005148 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005149 lines =<< trim END
5150 vim9script
5151
5152 class A
5153 static def _Foo(): number
5154 return 1234
5155 enddef
5156 endclass
5157 def T()
5158 var a = A.new()
5159 a._Foo()
5160 enddef
5161 T()
5162 END
Ernie Rael03042a22023-11-11 08:53:32 +01005163 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005164
Ernie Rael03042a22023-11-11 08:53:32 +01005165 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005166 lines =<< trim END
5167 vim9script
5168
5169 class A
5170 static def _Foo(): number
5171 return 1234
5172 enddef
5173 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005174 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005175 enddef
5176 endclass
5177 var a = A.new()
5178 a.Bar()
5179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005181
Ernie Rael03042a22023-11-11 08:53:32 +01005182 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005183 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005184 lines =<< trim END
5185 vim9script
5186
5187 class A
5188 static def _Foo1(): number
5189 return 1234
5190 enddef
5191 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005192 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005193 enddef
5194 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005195 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005196 enddef
5197 endclass
5198 var a = A.new()
5199 a.Bar()
5200 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005201 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005202
Ernie Rael03042a22023-11-11 08:53:32 +01005203 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005204 lines =<< trim END
5205 vim9script
5206
5207 class A
5208 static def _Foo()
5209 enddef
5210 static def Foo()
5211 enddef
5212 endclass
5213 var a = A.new()
5214 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005215 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005216
Ernie Rael03042a22023-11-11 08:53:32 +01005217 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005218 lines =<< trim END
5219 vim9script
5220
5221 class A
5222 static def _Foo(): number
5223 return 1234
5224 enddef
5225 endclass
5226 class B
5227 def Foo(): number
5228 return A._Foo()
5229 enddef
5230 endclass
5231 var b = B.new()
5232 assert_equal(1234, b.Foo())
5233 END
Ernie Rael03042a22023-11-11 08:53:32 +01005234 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005235
Ernie Rael03042a22023-11-11 08:53:32 +01005236 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005237 lines =<< trim END
5238 vim9script
5239 class A
5240 static def _Foo(): number
5241 return 1234
5242 enddef
5243 endclass
5244 class B extends A
5245 def Bar()
5246 enddef
5247 endclass
5248 class C extends B
5249 def Baz(): number
5250 return A._Foo()
5251 enddef
5252 endclass
5253 var c = C.new()
5254 assert_equal(1234, c.Baz())
5255 END
Ernie Rael03042a22023-11-11 08:53:32 +01005256 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005257
Ernie Rael03042a22023-11-11 08:53:32 +01005258 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005259 lines =<< trim END
5260 vim9script
5261 class A
5262 static def _Foo(): number
5263 return 1234
5264 enddef
5265 endclass
5266 class B extends A
5267 def Bar()
5268 enddef
5269 endclass
5270 class C extends B
5271 static def Baz(): number
5272 return A._Foo()
5273 enddef
5274 endclass
5275 assert_equal(1234, C.Baz())
5276 END
Ernie Rael03042a22023-11-11 08:53:32 +01005277 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005278
Ernie Rael03042a22023-11-11 08:53:32 +01005279 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005280 lines =<< trim END
5281 vim9script
5282 class A
5283 static def _Foo(): number
5284 return 1234
5285 enddef
5286 endclass
5287 class B extends A
5288 def Bar()
5289 enddef
5290 endclass
5291 class C extends B
5292 def Baz(): number
5293 enddef
5294 endclass
5295 var c = C.new()
5296 assert_equal(1234, C._Foo())
5297 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005298 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005299enddef
5300
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005301" Test for using the return value of a class/object method as a function
5302" argument.
5303def Test_objmethod_funcarg()
5304 var lines =<< trim END
5305 vim9script
5306
5307 class C
5308 def Foo(): string
5309 return 'foo'
5310 enddef
5311 endclass
5312
5313 def Bar(a: number, s: string): string
5314 return s
5315 enddef
5316
5317 def Baz(c: C)
5318 assert_equal('foo', Bar(10, c.Foo()))
5319 enddef
5320
5321 var t = C.new()
5322 Baz(t)
5323 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005324 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005325
5326 lines =<< trim END
5327 vim9script
5328
5329 class C
5330 static def Foo(): string
5331 return 'foo'
5332 enddef
5333 endclass
5334
5335 def Bar(a: number, s: string): string
5336 return s
5337 enddef
5338
5339 def Baz()
5340 assert_equal('foo', Bar(10, C.Foo()))
5341 enddef
5342
5343 Baz()
5344 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005345 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005346enddef
5347
Ernie Raelcf138d42023-09-06 20:45:03 +02005348def Test_static_inheritence()
5349 # subclasses get their own static copy
5350 var lines =<< trim END
5351 vim9script
5352
5353 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005354 static var _svar: number
5355 var _mvar: number
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005356 def new()
5357 _svar = 1
5358 this._mvar = 101
5359 enddef
5360 def AccessObject(): number
5361 return this._mvar
5362 enddef
5363 def AccessStaticThroughObject(): number
5364 return _svar
5365 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005366 endclass
5367
5368 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005369 def new()
5370 this._mvar = 102
5371 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005372 endclass
5373
5374 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005375 def new()
5376 this._mvar = 103
5377 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005378
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005379 def AccessPrivateStaticThroughClassName(): number
5380 assert_equal(1, A._svar)
5381 return 444
5382 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005383 endclass
5384
5385 var oa = A.new()
5386 var ob = B.new()
5387 var oc = C.new()
5388 assert_equal(101, oa.AccessObject())
5389 assert_equal(102, ob.AccessObject())
5390 assert_equal(103, oc.AccessObject())
5391
Ernie Rael03042a22023-11-11 08:53:32 +01005392 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005393
5394 # verify object properly resolves to correct static
5395 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005396 assert_equal(1, ob.AccessStaticThroughObject())
5397 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005398 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005399 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005400enddef
5401
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005402" Test for declaring duplicate object and class members
5403def Test_dup_member_variable()
5404 # Duplicate member variable
5405 var lines =<< trim END
5406 vim9script
5407 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005408 var val = 10
5409 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005410 endclass
5411 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005412 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005413
Ernie Rael03042a22023-11-11 08:53:32 +01005414 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005415 lines =<< trim END
5416 vim9script
5417 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005418 var _val = 10
5419 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005420 endclass
5421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005422 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005423
5424 # Duplicate public member variable
5425 lines =<< trim END
5426 vim9script
5427 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005428 public var val = 10
5429 public var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005430 endclass
5431 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005432 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005433
Ernie Rael03042a22023-11-11 08:53:32 +01005434 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005435 lines =<< trim END
5436 vim9script
5437 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005438 var val = 10
5439 var _val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005440 endclass
5441 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005442 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005443
Ernie Rael03042a22023-11-11 08:53:32 +01005444 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005445 lines =<< trim END
5446 vim9script
5447 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005448 var _val = 20
5449 public var val = 10
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005450 endclass
5451 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005452 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005453
5454 # Duplicate class member variable
5455 lines =<< trim END
5456 vim9script
5457 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005458 static var s: string = "abc"
5459 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005460 endclass
5461 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005462 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005463
Ernie Rael03042a22023-11-11 08:53:32 +01005464 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005465 lines =<< trim END
5466 vim9script
5467 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005468 public static var s: string = "abc"
5469 static var _s: string = "def"
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005470 endclass
5471 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005472 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005473
5474 # Duplicate class and object member variable
5475 lines =<< trim END
5476 vim9script
5477 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01005478 static var val = 10
5479 var val = 20
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005480 def new()
5481 enddef
5482 endclass
5483 var c = C.new()
5484 assert_equal(10, C.val)
5485 assert_equal(20, c.val)
5486 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005487 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005488
5489 # Duplicate object member variable in a derived class
5490 lines =<< trim END
5491 vim9script
5492 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005493 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005494 endclass
5495 class B extends A
5496 endclass
5497 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005498 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005499 endclass
5500 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005501 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005502
Ernie Rael03042a22023-11-11 08:53:32 +01005503 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005504 lines =<< trim END
5505 vim9script
5506 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005507 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005508 endclass
5509 class B extends A
5510 endclass
5511 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005512 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005513 endclass
5514 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005515 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005516
Ernie Rael03042a22023-11-11 08:53:32 +01005517 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005518 lines =<< trim END
5519 vim9script
5520 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005521 var val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005522 endclass
5523 class B extends A
5524 endclass
5525 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005526 var _val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005527 endclass
5528 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005529 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005530
5531 # Duplicate object member variable in a derived class
5532 lines =<< trim END
5533 vim9script
5534 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005535 var _val = 10
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005536 endclass
5537 class B extends A
5538 endclass
5539 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01005540 var val = 20
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005541 endclass
5542 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005543 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005544
5545 # Two member variables with a common prefix
5546 lines =<< trim END
5547 vim9script
5548 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005549 public static var svar2: number
5550 public static var svar: number
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005551 endclass
5552 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005553 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005554enddef
5555
Ernie Rael03042a22023-11-11 08:53:32 +01005556" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005557def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005558 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005559 var lines =<< trim END
5560 vim9script
5561 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005562 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005563 def GetVal(): number
5564 return this._val
5565 enddef
5566 endclass
5567 def T()
5568 var a = A.new()
5569 a._val = 20
5570 enddef
5571 T()
5572 END
Ernie Rael03042a22023-11-11 08:53:32 +01005573 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005574
Ernie Rael03042a22023-11-11 08:53:32 +01005575 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005576 lines =<< trim END
5577 vim9script
5578 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005579 var _val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005580 endclass
5581 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005582 var a = A.new()
5583 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005584 enddef
5585 T()
5586 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005587 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005588
Ernie Rael03042a22023-11-11 08:53:32 +01005589 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005590 lines =<< trim END
5591 vim9script
5592 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005593 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005594 endclass
5595 def T()
5596 var a = A.new()
5597 var x = a._val
5598 enddef
5599 T()
5600 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005601 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005602
Ernie Rael03042a22023-11-11 08:53:32 +01005603 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005604 lines =<< trim END
5605 vim9script
5606 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005607 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005608 endclass
5609 def T()
5610 var a = A.new()
5611 a._val = 3
5612 enddef
5613 T()
5614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005615 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005616
Ernie Rael03042a22023-11-11 08:53:32 +01005617 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005618 lines =<< trim END
5619 vim9script
5620 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005621 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005622 endclass
5623 def T()
5624 var x = A._val
5625 enddef
5626 T()
5627 END
Ernie Rael03042a22023-11-11 08:53:32 +01005628 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005629
Ernie Rael03042a22023-11-11 08:53:32 +01005630 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005631 lines =<< trim END
5632 vim9script
5633 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005634 static var _val = 10
Ernie Rael18143d32023-09-04 22:30:41 +02005635 endclass
5636 def T()
5637 A._val = 3
5638 enddef
5639 T()
5640 END
Ernie Rael03042a22023-11-11 08:53:32 +01005641 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005642enddef
5643
5644" Test for changing the member access of an interface in a implementation class
5645def Test_change_interface_member_access()
5646 var lines =<< trim END
5647 vim9script
5648 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005649 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005650 endinterface
5651 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005652 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005653 endclass
5654 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005655 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005656
5657 lines =<< trim END
5658 vim9script
5659 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005660 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005661 endinterface
5662 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005663 public var val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005664 endclass
5665 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005666 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005667enddef
5668
5669" Test for trying to change a readonly member from a def function
5670def Test_readonly_member_change_in_def_func()
5671 var lines =<< trim END
5672 vim9script
5673 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005674 var val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005675 endclass
5676 def T()
5677 var a = A.new()
5678 a.val = 20
5679 enddef
5680 T()
5681 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005682 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005683enddef
5684
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005685" Test for reading and writing a class member from a def function
5686def Test_modify_class_member_from_def_function()
5687 var lines =<< trim END
5688 vim9script
5689 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005690 var var1: number = 10
5691 public static var var2: list<number> = [1, 2]
5692 public static var var3: dict<number> = {a: 1, b: 2}
5693 static var _priv_var4: number = 40
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005694 endclass
5695 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005696 assert_equal([1, 2], A.var2)
5697 assert_equal({a: 1, b: 2}, A.var3)
5698 A.var2 = [3, 4]
5699 A.var3 = {c: 3, d: 4}
5700 assert_equal([3, 4], A.var2)
5701 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005702 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005703 enddef
5704 T()
5705 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005706 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005707enddef
5708
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005709" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005710def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005711 var lines =<< trim END
5712 vim9script
5713 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005714 public static var svar1: list<number> = [1]
5715 public static var svar2: list<number> = [2]
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005716 endclass
5717
5718 A.svar1->add(3)
5719 A.svar2->add(4)
5720 assert_equal([1, 3], A.svar1)
5721 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005722
5723 def Foo()
5724 A.svar1->add(7)
5725 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005726 assert_equal([1, 3, 7], A.svar1)
5727 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005728 enddef
5729 Foo()
5730 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005731 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005732
5733 # Cannot read from a class variable using an object in script context
5734 lines =<< trim END
5735 vim9script
5736 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005737 public var var1: number
5738 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005739 endclass
5740
5741 var a = A.new()
5742 echo a.svar2
5743 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005744 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005745
5746 # Cannot write to a class variable using an object in script context
5747 lines =<< trim END
5748 vim9script
5749 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005750 public var var1: number
5751 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005752 endclass
5753
5754 var a = A.new()
5755 a.svar2 = [2]
5756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005757 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005758
5759 # Cannot read from a class variable using an object in def method context
5760 lines =<< trim END
5761 vim9script
5762 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005763 public var var1: number
5764 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005765 endclass
5766
5767 def T()
5768 var a = A.new()
5769 echo a.svar2
5770 enddef
5771 T()
5772 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005773 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005774
5775 # Cannot write to a class variable using an object in def method context
5776 lines =<< trim END
5777 vim9script
5778 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01005779 public var var1: number
5780 public static var svar2: list<number> = [1]
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005781 endclass
5782
5783 def T()
5784 var a = A.new()
5785 a.svar2 = [2]
5786 enddef
5787 T()
5788 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005789 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005790enddef
5791
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005792" Test for using a interface method using a child object
5793def Test_interface_method_from_child()
5794 var lines =<< trim END
5795 vim9script
5796
5797 interface A
5798 def Foo(): string
5799 endinterface
5800
5801 class B implements A
5802 def Foo(): string
5803 return 'foo'
5804 enddef
5805 endclass
5806
5807 class C extends B
5808 def Bar(): string
5809 return 'bar'
5810 enddef
5811 endclass
5812
5813 def T1(a: A)
5814 assert_equal('foo', a.Foo())
5815 enddef
5816
5817 def T2(b: B)
5818 assert_equal('foo', b.Foo())
5819 enddef
5820
5821 var c = C.new()
5822 T1(c)
5823 T2(c)
5824 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005825 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005826enddef
5827
5828" Test for using an interface method using a child object when it is overridden
5829" by the child class.
5830" FIXME: This test fails.
5831" def Test_interface_overridden_method_from_child()
5832" var lines =<< trim END
5833" vim9script
5834"
5835" interface A
5836" def Foo(): string
5837" endinterface
5838"
5839" class B implements A
5840" def Foo(): string
5841" return 'b-foo'
5842" enddef
5843" endclass
5844"
5845" class C extends B
5846" def Bar(): string
5847" return 'bar'
5848" enddef
5849" def Foo(): string
5850" return 'c-foo'
5851" enddef
5852" endclass
5853"
5854" def T1(a: A)
5855" assert_equal('c-foo', a.Foo())
5856" enddef
5857"
5858" def T2(b: B)
5859" assert_equal('c-foo', b.Foo())
5860" enddef
5861"
5862" var c = C.new()
5863" T1(c)
5864" T2(c)
5865" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005866" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005867" enddef
5868
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005869" Test for abstract methods
5870def Test_abstract_method()
5871 # Use two abstract methods
5872 var lines =<< trim END
5873 vim9script
5874 abstract class A
5875 def M1(): number
5876 return 10
5877 enddef
5878 abstract def M2(): number
5879 abstract def M3(): number
5880 endclass
5881 class B extends A
5882 def M2(): number
5883 return 20
5884 enddef
5885 def M3(): number
5886 return 30
5887 enddef
5888 endclass
5889 var b = B.new()
5890 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5891 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005892 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005893
5894 # Don't define an abstract method
5895 lines =<< trim END
5896 vim9script
5897 abstract class A
5898 abstract def Foo()
5899 endclass
5900 class B extends A
5901 endclass
5902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005903 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005904
5905 # Use abstract method in a concrete class
5906 lines =<< trim END
5907 vim9script
5908 class A
5909 abstract def Foo()
5910 endclass
5911 class B extends A
5912 endclass
5913 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005914 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005915
5916 # Use abstract method in an interface
5917 lines =<< trim END
5918 vim9script
5919 interface A
5920 abstract def Foo()
5921 endinterface
5922 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005923 def Foo()
5924 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005925 endclass
5926 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005927 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5928
5929 # Use abstract static method in an interface
5930 lines =<< trim END
5931 vim9script
5932 interface A
5933 abstract static def Foo()
5934 enddef
5935 endinterface
5936 END
5937 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5938
5939 # Use abstract static variable in an interface
5940 lines =<< trim END
5941 vim9script
5942 interface A
5943 abstract static foo: number = 10
5944 endinterface
5945 END
5946 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005947
5948 # Abbreviate the "abstract" keyword
5949 lines =<< trim END
5950 vim9script
5951 class A
5952 abs def Foo()
5953 endclass
5954 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005955 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005956
5957 # Use "abstract" with a member variable
5958 lines =<< trim END
5959 vim9script
5960 abstract class A
5961 abstract this.val = 10
5962 endclass
5963 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005964 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005965
5966 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005967 lines =<< trim END
5968 vim9script
5969 abstract class A
5970 abstract static def Foo(): number
5971 endclass
5972 END
5973 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005974
5975 # Type mismatch between abstract method and concrete method
5976 lines =<< trim END
5977 vim9script
5978 abstract class A
5979 abstract def Foo(a: string, b: number): list<number>
5980 endclass
5981 class B extends A
5982 def Foo(a: number, b: string): list<string>
5983 return []
5984 enddef
5985 endclass
5986 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005987 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 +02005988
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005989 # Invoke an abstract method from a def function
5990 lines =<< trim END
5991 vim9script
5992 abstract class A
5993 abstract def Foo(): list<number>
5994 endclass
5995 class B extends A
5996 def Foo(): list<number>
5997 return [3, 5]
5998 enddef
5999 endclass
6000 def Bar(c: B)
6001 assert_equal([3, 5], c.Foo())
6002 enddef
6003 var b = B.new()
6004 Bar(b)
6005 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006006 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01006007
6008 # Use a static method in an abstract class
6009 lines =<< trim END
6010 vim9script
6011 abstract class A
6012 static def Foo(): string
6013 return 'foo'
6014 enddef
6015 endclass
6016 assert_equal('foo', A.Foo())
6017 END
6018 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006019enddef
6020
6021" Test for calling a class method from a subclass
6022def Test_class_method_call_from_subclass()
6023 # class method call from a subclass
6024 var lines =<< trim END
6025 vim9script
6026
6027 class A
6028 static def Foo()
6029 echo "foo"
6030 enddef
6031 endclass
6032
6033 class B extends A
6034 def Bar()
6035 Foo()
6036 enddef
6037 endclass
6038
6039 var b = B.new()
6040 b.Bar()
6041 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006042 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02006043enddef
6044
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006045" Test for calling a class method using an object in a def function context and
6046" script context.
6047def Test_class_method_call_using_object()
6048 # script context
6049 var lines =<< trim END
6050 vim9script
6051 class A
6052 static def Foo(): list<string>
6053 return ['a', 'b']
6054 enddef
6055 def Bar()
6056 assert_equal(['a', 'b'], A.Foo())
6057 assert_equal(['a', 'b'], Foo())
6058 enddef
6059 endclass
6060
6061 def T()
6062 assert_equal(['a', 'b'], A.Foo())
6063 var t_a = A.new()
6064 t_a.Bar()
6065 enddef
6066
6067 assert_equal(['a', 'b'], A.Foo())
6068 var a = A.new()
6069 a.Bar()
6070 T()
6071 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006072 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006073
6074 # script context
6075 lines =<< trim END
6076 vim9script
6077 class A
6078 static def Foo(): string
6079 return 'foo'
6080 enddef
6081 endclass
6082
6083 var a = A.new()
6084 assert_equal('foo', a.Foo())
6085 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006086 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006087
6088 # def function context
6089 lines =<< trim END
6090 vim9script
6091 class A
6092 static def Foo(): string
6093 return 'foo'
6094 enddef
6095 endclass
6096
6097 def T()
6098 var a = A.new()
6099 assert_equal('foo', a.Foo())
6100 enddef
6101 T()
6102 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006103 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006104enddef
6105
6106def Test_class_variable()
6107 var lines =<< trim END
6108 vim9script
6109
6110 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006111 public static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006112 static def ClassFunc()
6113 assert_equal(10, val)
6114 enddef
6115 def ObjFunc()
6116 assert_equal(10, val)
6117 enddef
6118 endclass
6119
6120 class B extends A
6121 endclass
6122
6123 assert_equal(10, A.val)
6124 A.ClassFunc()
6125 var a = A.new()
6126 a.ObjFunc()
6127 var b = B.new()
6128 b.ObjFunc()
6129
6130 def T1(a1: A)
6131 a1.ObjFunc()
6132 A.ClassFunc()
6133 enddef
6134 T1(b)
6135
6136 A.val = 20
6137 assert_equal(20, A.val)
6138 END
6139 v9.CheckSourceSuccess(lines)
6140
6141 # Modifying a parent class variable from a child class method
6142 lines =<< trim END
6143 vim9script
6144
6145 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006146 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006147 endclass
6148
6149 class B extends A
6150 static def ClassFunc()
6151 val = 20
6152 enddef
6153 endclass
6154 B.ClassFunc()
6155 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006156 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006157
6158 # Reading a parent class variable from a child class method
6159 lines =<< trim END
6160 vim9script
6161
6162 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006163 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006164 endclass
6165
6166 class B extends A
6167 static def ClassFunc()
6168 var i = val
6169 enddef
6170 endclass
6171 B.ClassFunc()
6172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006173 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006174
6175 # Modifying a parent class variable from a child object method
6176 lines =<< trim END
6177 vim9script
6178
6179 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006180 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006181 endclass
6182
6183 class B extends A
6184 def ObjFunc()
6185 val = 20
6186 enddef
6187 endclass
6188 var b = B.new()
6189 b.ObjFunc()
6190 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006191 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006192
6193 # Reading a parent class variable from a child object method
6194 lines =<< trim END
6195 vim9script
6196
6197 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006198 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006199 endclass
6200
6201 class B extends A
6202 def ObjFunc()
6203 var i = val
6204 enddef
6205 endclass
6206 var b = B.new()
6207 b.ObjFunc()
6208 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006209 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006210
6211 # Modifying a class variable using an object at script level
6212 lines =<< trim END
6213 vim9script
6214
6215 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006216 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006217 endclass
6218 var a = A.new()
6219 a.val = 20
6220 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006221 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006222
6223 # Reading a class variable using an object at script level
6224 lines =<< trim END
6225 vim9script
6226
6227 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006228 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006229 endclass
6230 var a = A.new()
6231 var i = a.val
6232 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006233 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006234
6235 # Modifying a class variable using an object at function level
6236 lines =<< trim END
6237 vim9script
6238
6239 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006240 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006241 endclass
6242
6243 def T()
6244 var a = A.new()
6245 a.val = 20
6246 enddef
6247 T()
6248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006249 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006250
6251 # Reading a class variable using an object at function level
6252 lines =<< trim END
6253 vim9script
6254
6255 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006256 static var val: number = 10
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006257 endclass
6258 def T()
6259 var a = A.new()
6260 var i = a.val
6261 enddef
6262 T()
6263 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006264 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Doug Kearns74da0ee2023-12-14 20:26:26 +01006265
6266 # Use old implicit var declaration syntax (without initialization)
6267 lines =<< trim END
6268 vim9script
6269
6270 class A
6271 static val: number
6272 endclass
6273 END
6274 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6275
6276 # Use old implicit var declaration syntax (with initialization)
6277 lines =<< trim END
6278 vim9script
6279
6280 class A
6281 static val: number = 10
6282 endclass
6283 END
6284 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6285
6286 # Use old implicit var declaration syntax (type inferred)
6287 lines =<< trim END
6288 vim9script
6289
6290 class A
6291 static val = 10
6292 endclass
6293 END
6294 v9.CheckSourceFailure(lines, 'E1368: Static must be followed by "var" or "def"', 4)
6295
6296 # Missing ":var" in "var" class variable declaration (without initialization)
6297 lines =<< trim END
6298 vim9script
6299
6300 class A
6301 static var: number
6302 endclass
6303 END
6304 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number', 4)
6305
6306 # Missing ":var" in "var" class variable declaration (with initialization)
6307 lines =<< trim END
6308 vim9script
6309
6310 class A
6311 static var: number = 10
6312 endclass
6313 END
6314 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var: number = 10', 4)
6315
6316 # Missing ":var" in "var" class variable declaration (type inferred)
6317 lines =<< trim END
6318 vim9script
6319
6320 class A
6321 static var = 10
6322 endclass
6323 END
6324 v9.CheckSourceFailure(lines, 'E1329: Invalid class variable declaration: static var = 10', 4)
6325
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006326enddef
6327
6328" Test for using a duplicate class method and class variable in a child class
6329def Test_dup_class_member()
6330 # duplicate class variable, class method and overridden object method
6331 var lines =<< trim END
6332 vim9script
6333 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006334 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006335 static def Check()
6336 assert_equal(100, sval)
6337 enddef
6338 def GetVal(): number
6339 return sval
6340 enddef
6341 endclass
6342
6343 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006344 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006345 static def Check()
6346 assert_equal(200, sval)
6347 enddef
6348 def GetVal(): number
6349 return sval
6350 enddef
6351 endclass
6352
6353 def T1(aa: A): number
6354 return aa.GetVal()
6355 enddef
6356
6357 def T2(bb: B): number
6358 return bb.GetVal()
6359 enddef
6360
6361 assert_equal(100, A.sval)
6362 assert_equal(200, B.sval)
6363 var a = A.new()
6364 assert_equal(100, a.GetVal())
6365 var b = B.new()
6366 assert_equal(200, b.GetVal())
6367 assert_equal(200, T1(b))
6368 assert_equal(200, T2(b))
6369 END
6370 v9.CheckSourceSuccess(lines)
6371
6372 # duplicate class variable and class method
6373 lines =<< trim END
6374 vim9script
6375 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006376 static var sval = 100
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006377 static def Check()
6378 assert_equal(100, sval)
6379 enddef
6380 def GetVal(): number
6381 return sval
6382 enddef
6383 endclass
6384
6385 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006386 static var sval = 200
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006387 static def Check()
6388 assert_equal(200, sval)
6389 enddef
6390 endclass
6391
6392 def T1(aa: A): number
6393 return aa.GetVal()
6394 enddef
6395
6396 def T2(bb: B): number
6397 return bb.GetVal()
6398 enddef
6399
6400 assert_equal(100, A.sval)
6401 assert_equal(200, B.sval)
6402 var a = A.new()
6403 assert_equal(100, a.GetVal())
6404 var b = B.new()
6405 assert_equal(100, b.GetVal())
6406 assert_equal(100, T1(b))
6407 assert_equal(100, T2(b))
6408 END
6409 v9.CheckSourceSuccess(lines)
6410enddef
6411
6412" Test for calling an instance method using the class
6413def Test_instance_method_call_using_class()
6414 # Invoke an object method using a class in script context
6415 var lines =<< trim END
6416 vim9script
6417 class A
6418 def Foo()
6419 echo "foo"
6420 enddef
6421 endclass
6422 A.Foo()
6423 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006424 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006425
6426 # Invoke an object method using a class in def function context
6427 lines =<< trim END
6428 vim9script
6429 class A
6430 def Foo()
6431 echo "foo"
6432 enddef
6433 endclass
6434 def T()
6435 A.Foo()
6436 enddef
6437 T()
6438 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006439 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006440enddef
6441
6442" Test for duplicate class method and instance method
6443def Test_dup_classmethod_objmethod()
6444 # Duplicate instance method
6445 var lines =<< trim END
6446 vim9script
6447 class A
6448 static def Foo()
6449 enddef
6450 def Foo()
6451 enddef
6452 endclass
6453 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006454 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006455
Ernie Rael03042a22023-11-11 08:53:32 +01006456 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006457 lines =<< trim END
6458 vim9script
6459 class A
6460 static def Foo()
6461 enddef
6462 def _Foo()
6463 enddef
6464 endclass
6465 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006466 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006467
6468 # Duplicate class method
6469 lines =<< trim END
6470 vim9script
6471 class A
6472 def Foo()
6473 enddef
6474 static def Foo()
6475 enddef
6476 endclass
6477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006478 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006479
Ernie Rael03042a22023-11-11 08:53:32 +01006480 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006481 lines =<< trim END
6482 vim9script
6483 class A
6484 def Foo()
6485 enddef
6486 static def _Foo()
6487 enddef
6488 endclass
6489 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006490 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006491
Ernie Rael03042a22023-11-11 08:53:32 +01006492 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006493 lines =<< trim END
6494 vim9script
6495 class A
6496 def _Foo()
6497 enddef
6498 static def _Foo()
6499 enddef
6500 endclass
6501 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006502 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006503enddef
6504
6505" Test for an instance method access level comparison with parent instance
6506" methods.
6507def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006508 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006509 var lines =<< trim END
6510 vim9script
6511 class A
6512 def Foo()
6513 enddef
6514 endclass
6515 class B extends A
6516 endclass
6517 class C extends B
6518 def _Foo()
6519 enddef
6520 endclass
6521 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006522 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006523
6524 # Public method in subclass
6525 lines =<< trim END
6526 vim9script
6527 class A
6528 def _Foo()
6529 enddef
6530 endclass
6531 class B extends A
6532 endclass
6533 class C extends B
6534 def Foo()
6535 enddef
6536 endclass
6537 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006538 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006539enddef
6540
6541def Test_extend_empty_class()
6542 var lines =<< trim END
6543 vim9script
6544 class A
6545 endclass
6546 class B extends A
6547 endclass
6548 class C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006549 public static var rw_class_var = 1
6550 public var rw_obj_var = 2
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006551 static def ClassMethod(): number
6552 return 3
6553 enddef
6554 def ObjMethod(): number
6555 return 4
6556 enddef
6557 endclass
6558 assert_equal(1, C.rw_class_var)
6559 assert_equal(3, C.ClassMethod())
6560 var c = C.new()
6561 assert_equal(2, c.rw_obj_var)
6562 assert_equal(4, c.ObjMethod())
6563 END
6564 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006565enddef
6566
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006567" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006568" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006569def Test_interface_with_unsupported_members()
6570 var lines =<< trim END
6571 vim9script
6572 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006573 static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006574 endinterface
6575 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006576 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006577
6578 lines =<< trim END
6579 vim9script
6580 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006581 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006582 endinterface
6583 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006584 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006585
6586 lines =<< trim END
6587 vim9script
6588 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006589 public static var num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006590 endinterface
6591 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006592 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006593
6594 lines =<< trim END
6595 vim9script
6596 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006597 public static var num: number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006598 endinterface
6599 END
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +02006600 v9.CheckSourceFailure(lines, 'E1387: public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006601
6602 lines =<< trim END
6603 vim9script
6604 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006605 static var _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006606 endinterface
6607 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006608 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006609
6610 lines =<< trim END
6611 vim9script
6612 interface A
6613 static def Foo(d: dict<any>): list<string>
6614 endinterface
6615 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006616 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006617
6618 lines =<< trim END
6619 vim9script
6620 interface A
6621 static def _Foo(d: dict<any>): list<string>
6622 endinterface
6623 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006624 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006625
6626 lines =<< trim END
6627 vim9script
6628 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006629 var _Foo: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006630 endinterface
6631 END
Ernie Rael03042a22023-11-11 08:53:32 +01006632 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006633
6634 lines =<< trim END
6635 vim9script
6636 interface A
6637 def _Foo(d: dict<any>): list<string>
6638 endinterface
6639 END
Ernie Rael03042a22023-11-11 08:53:32 +01006640 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006641enddef
6642
6643" Test for extending an interface
6644def Test_extend_interface()
6645 var lines =<< trim END
6646 vim9script
6647 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006648 var var1: list<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006649 def Foo()
6650 endinterface
6651 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006652 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006653 def Bar()
6654 endinterface
6655 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006656 var var1 = [1, 2]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006657 def Foo()
6658 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006659 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006660 def Bar()
6661 enddef
6662 endclass
6663 END
6664 v9.CheckSourceSuccess(lines)
6665
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006666 # extending empty interface
6667 lines =<< trim END
6668 vim9script
6669 interface A
6670 endinterface
6671 interface B extends A
6672 endinterface
6673 class C implements B
6674 endclass
6675 END
6676 v9.CheckSourceSuccess(lines)
6677
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006678 lines =<< trim END
6679 vim9script
6680 interface A
6681 def Foo()
6682 endinterface
6683 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006684 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006685 endinterface
6686 class C implements A, B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006687 var var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006688 endclass
6689 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006690 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006691
6692 lines =<< trim END
6693 vim9script
6694 interface A
6695 def Foo()
6696 endinterface
6697 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006698 var var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006699 endinterface
6700 class C implements A, B
6701 def Foo()
6702 enddef
6703 endclass
6704 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006705 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006706
6707 # interface cannot extend a class
6708 lines =<< trim END
6709 vim9script
6710 class A
6711 endclass
6712 interface B extends A
6713 endinterface
6714 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006715 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006716
6717 # class cannot extend an interface
6718 lines =<< trim END
6719 vim9script
6720 interface A
6721 endinterface
6722 class B extends A
6723 endclass
6724 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006725 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006726
6727 # interface cannot implement another interface
6728 lines =<< trim END
6729 vim9script
6730 interface A
6731 endinterface
6732 interface B implements A
6733 endinterface
6734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006735 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006736
6737 # interface cannot extend multiple interfaces
6738 lines =<< trim END
6739 vim9script
6740 interface A
6741 endinterface
6742 interface B
6743 endinterface
6744 interface C extends A, B
6745 endinterface
6746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006747 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006748
6749 # Variable type in an extended interface is of different type
6750 lines =<< trim END
6751 vim9script
6752 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006753 var val1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006754 endinterface
6755 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006756 var val2: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006757 endinterface
6758 interface C extends B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006759 var val1: string
6760 var val2: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006761 endinterface
6762 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006763 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006764enddef
6765
6766" Test for a child class implementing an interface when some of the methods are
6767" defined in the parent class.
6768def Test_child_class_implements_interface()
6769 var lines =<< trim END
6770 vim9script
6771
6772 interface Intf
6773 def F1(): list<list<number>>
6774 def F2(): list<list<number>>
6775 def F3(): list<list<number>>
Doug Kearns74da0ee2023-12-14 20:26:26 +01006776 var var1: list<dict<number>>
6777 var var2: list<dict<number>>
6778 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006779 endinterface
6780
6781 class A
6782 def A1()
6783 enddef
6784 def F3(): list<list<number>>
6785 return [[3]]
6786 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006787 var v1: list<list<number>> = [[0]]
6788 var var3 = [{c: 30}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006789 endclass
6790
6791 class B extends A
6792 def B1()
6793 enddef
6794 def F2(): list<list<number>>
6795 return [[2]]
6796 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006797 var v2: list<list<number>> = [[0]]
6798 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006799 endclass
6800
6801 class C extends B implements Intf
6802 def C1()
6803 enddef
6804 def F1(): list<list<number>>
6805 return [[1]]
6806 enddef
Doug Kearns74da0ee2023-12-14 20:26:26 +01006807 var v3: list<list<number>> = [[0]]
6808 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006809 endclass
6810
6811 def T(if: Intf)
6812 assert_equal([[1]], if.F1())
6813 assert_equal([[2]], if.F2())
6814 assert_equal([[3]], if.F3())
6815 assert_equal([{a: 10}], if.var1)
6816 assert_equal([{b: 20}], if.var2)
6817 assert_equal([{c: 30}], if.var3)
6818 enddef
6819
6820 var c = C.new()
6821 T(c)
6822 assert_equal([[1]], c.F1())
6823 assert_equal([[2]], c.F2())
6824 assert_equal([[3]], c.F3())
6825 assert_equal([{a: 10}], c.var1)
6826 assert_equal([{b: 20}], c.var2)
6827 assert_equal([{c: 30}], c.var3)
6828 END
6829 v9.CheckSourceSuccess(lines)
6830
6831 # One of the interface methods is not found
6832 lines =<< trim END
6833 vim9script
6834
6835 interface Intf
6836 def F1()
6837 def F2()
6838 def F3()
6839 endinterface
6840
6841 class A
6842 def A1()
6843 enddef
6844 endclass
6845
6846 class B extends A
6847 def B1()
6848 enddef
6849 def F2()
6850 enddef
6851 endclass
6852
6853 class C extends B implements Intf
6854 def C1()
6855 enddef
6856 def F1()
6857 enddef
6858 endclass
6859 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006860 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006861
6862 # One of the interface methods is of different type
6863 lines =<< trim END
6864 vim9script
6865
6866 interface Intf
6867 def F1()
6868 def F2()
6869 def F3()
6870 endinterface
6871
6872 class A
6873 def F3(): number
6874 return 0
6875 enddef
6876 def A1()
6877 enddef
6878 endclass
6879
6880 class B extends A
6881 def B1()
6882 enddef
6883 def F2()
6884 enddef
6885 endclass
6886
6887 class C extends B implements Intf
6888 def C1()
6889 enddef
6890 def F1()
6891 enddef
6892 endclass
6893 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006894 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006895
6896 # One of the interface variables is not present
6897 lines =<< trim END
6898 vim9script
6899
6900 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006901 var var1: list<dict<number>>
6902 var var2: list<dict<number>>
6903 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006904 endinterface
6905
6906 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006907 var v1: list<list<number>> = [[0]]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006908 endclass
6909
6910 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006911 var v2: list<list<number>> = [[0]]
6912 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006913 endclass
6914
6915 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006916 var v3: list<list<number>> = [[0]]
6917 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006918 endclass
6919 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006920 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006921
6922 # One of the interface variables is of different type
6923 lines =<< trim END
6924 vim9script
6925
6926 interface Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006927 var var1: list<dict<number>>
6928 var var2: list<dict<number>>
6929 var var3: list<dict<number>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006930 endinterface
6931
6932 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006933 var v1: list<list<number>> = [[0]]
6934 var var3: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006935 endclass
6936
6937 class B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006938 var v2: list<list<number>> = [[0]]
6939 var var2 = [{b: 20}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006940 endclass
6941
6942 class C extends B implements Intf
Doug Kearns74da0ee2023-12-14 20:26:26 +01006943 var v3: list<list<number>> = [[0]]
6944 var var1 = [{a: 10}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006945 endclass
6946 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006947 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 +02006948enddef
6949
6950" Test for extending an interface with duplicate variables and methods
6951def Test_interface_extends_with_dup_members()
6952 var lines =<< trim END
6953 vim9script
6954 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006955 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006956 def Foo1(): number
6957 endinterface
6958 interface B extends A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006959 var n2: number
6960 var n1: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006961 def Foo2(): number
6962 def Foo1(): number
6963 endinterface
6964 class C implements B
Doug Kearns74da0ee2023-12-14 20:26:26 +01006965 var n1 = 10
6966 var n2 = 20
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006967 def Foo1(): number
6968 return 30
6969 enddef
6970 def Foo2(): number
6971 return 40
6972 enddef
6973 endclass
6974 def T1(a: A)
6975 assert_equal(10, a.n1)
6976 assert_equal(30, a.Foo1())
6977 enddef
6978 def T2(b: B)
6979 assert_equal(10, b.n1)
6980 assert_equal(20, b.n2)
6981 assert_equal(30, b.Foo1())
6982 assert_equal(40, b.Foo2())
6983 enddef
6984 var c = C.new()
6985 T1(c)
6986 T2(c)
6987 END
6988 v9.CheckSourceSuccess(lines)
6989enddef
6990
6991" Test for using "any" type for a variable in a sub-class while it has a
6992" concrete type in the interface
6993def Test_implements_using_var_type_any()
6994 var lines =<< trim END
6995 vim9script
6996 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01006997 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006998 endinterface
6999 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007000 var val = [{a: '1'}, {b: '2'}]
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007001 endclass
7002 var b = B.new()
7003 assert_equal([{a: '1'}, {b: '2'}], b.val)
7004 END
7005 v9.CheckSourceSuccess(lines)
7006
7007 # initialize instance variable using a different type
7008 lines =<< trim END
7009 vim9script
7010 interface A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007011 var val: list<dict<string>>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007012 endinterface
7013 class B implements A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007014 var val = {a: 1, b: 2}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007015 endclass
7016 var b = B.new()
7017 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007018 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02007019enddef
7020
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007021" Test for assigning to a member variable in a nested class
7022def Test_nested_object_assignment()
7023 var lines =<< trim END
7024 vim9script
7025
7026 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007027 var value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007028 endclass
7029
7030 class B
Doug Kearns74da0ee2023-12-14 20:26:26 +01007031 var a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007032 endclass
7033
7034 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007035 var b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007036 endclass
7037
7038 class D
Doug Kearns74da0ee2023-12-14 20:26:26 +01007039 var c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007040 endclass
7041
7042 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007043 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007044 enddef
7045
7046 var d = D.new()
7047 T(d)
7048 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02007049 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007050enddef
7051
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007052" Test for calling methods using a null object
7053def Test_null_object_method_call()
7054 # Calling a object method using a null object in script context
7055 var lines =<< trim END
7056 vim9script
7057
7058 class C
7059 def Foo()
7060 assert_report('This method should not be executed')
7061 enddef
7062 endclass
7063
7064 var o: C
7065 o.Foo()
7066 END
7067 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
7068
7069 # Calling a object method using a null object in def function context
7070 lines =<< trim END
7071 vim9script
7072
7073 class C
7074 def Foo()
7075 assert_report('This method should not be executed')
7076 enddef
7077 endclass
7078
7079 def T()
7080 var o: C
7081 o.Foo()
7082 enddef
7083 T()
7084 END
7085 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7086
7087 # Calling a object method through another class method using a null object in
7088 # script context
7089 lines =<< trim END
7090 vim9script
7091
7092 class C
7093 def Foo()
7094 assert_report('This method should not be executed')
7095 enddef
7096
7097 static def Bar(o_any: any)
7098 var o_typed: C = o_any
7099 o_typed.Foo()
7100 enddef
7101 endclass
7102
7103 var o: C
7104 C.Bar(o)
7105 END
7106 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7107
7108 # Calling a object method through another class method using a null object in
7109 # def function context
7110 lines =<< trim END
7111 vim9script
7112
7113 class C
7114 def Foo()
7115 assert_report('This method should not be executed')
7116 enddef
7117
7118 static def Bar(o_any: any)
7119 var o_typed: C = o_any
7120 o_typed.Foo()
7121 enddef
7122 endclass
7123
7124 def T()
7125 var o: C
7126 C.Bar(o)
7127 enddef
7128 T()
7129 END
7130 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
7131enddef
7132
7133" Test for using a dict as an object member
7134def Test_dict_object_member()
7135 var lines =<< trim END
7136 vim9script
7137
7138 class Context
Doug Kearns74da0ee2023-12-14 20:26:26 +01007139 public var state: dict<number> = {}
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02007140 def GetState(): dict<number>
7141 return this.state
7142 enddef
7143 endclass
7144
7145 var ctx = Context.new()
7146 ctx.state->extend({a: 1})
7147 ctx.state['b'] = 2
7148 assert_equal({a: 1, b: 2}, ctx.GetState())
7149
7150 def F()
7151 ctx.state['c'] = 3
7152 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
7153 enddef
7154 F()
7155 assert_equal(3, ctx.state.c)
7156 ctx.state.c = 4
7157 assert_equal(4, ctx.state.c)
7158 END
7159 v9.CheckSourceSuccess(lines)
7160enddef
7161
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02007162" The following test was failing after 9.0.1914. This was caused by using a
7163" freed object from a previous method call.
7164def Test_freed_object_from_previous_method_call()
7165 var lines =<< trim END
7166 vim9script
7167
7168 class Context
7169 endclass
7170
7171 class Result
7172 endclass
7173
7174 def Failure(): Result
7175 return Result.new()
7176 enddef
7177
7178 def GetResult(ctx: Context): Result
7179 return Failure()
7180 enddef
7181
7182 def Test_GetResult()
7183 var ctx = Context.new()
7184 var result = GetResult(ctx)
7185 enddef
7186
7187 Test_GetResult()
7188 END
7189 v9.CheckSourceSuccess(lines)
7190enddef
7191
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007192" Test for duplicate object and class variable
7193def Test_duplicate_variable()
7194 # Object variable name is same as the class variable name
7195 var lines =<< trim END
7196 vim9script
7197 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007198 public static var sval: number
7199 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007200 endclass
7201 var a = A.new()
7202 END
7203 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7204
7205 # Duplicate variable name and calling a class method
7206 lines =<< trim END
7207 vim9script
7208 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007209 public static var sval: number
7210 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007211 def F1()
7212 echo this.sval
7213 enddef
7214 static def F2()
7215 echo sval
7216 enddef
7217 endclass
7218 A.F2()
7219 END
7220 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7221
7222 # Duplicate variable with an empty constructor
7223 lines =<< trim END
7224 vim9script
7225 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007226 public static var sval: number
7227 public var sval: number
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007228 def new()
7229 enddef
7230 endclass
7231 var a = A.new()
7232 END
7233 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
7234enddef
7235
7236" Test for using a reserved keyword as a variable name
7237def Test_reserved_varname()
7238 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
7239 'null_function', 'null_list', 'null_partial', 'null_string',
7240 'null_channel', 'null_job', 'super', 'this']
7241
7242 var lines =<< trim eval END
7243 vim9script
7244 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007245 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007246 endclass
7247 var o = C.new()
7248 END
7249 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7250
7251 lines =<< trim eval END
7252 vim9script
7253 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007254 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007255 def new()
7256 enddef
7257 endclass
7258 var o = C.new()
7259 END
7260 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7261
7262 lines =<< trim eval END
7263 vim9script
7264 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007265 public var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007266 def new()
7267 enddef
7268 def F()
7269 echo this.{kword}
7270 enddef
7271 endclass
7272 var o = C.new()
7273 o.F()
7274 END
7275 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007276
7277 # class variable name
7278 if kword != 'this'
7279 lines =<< trim eval END
7280 vim9script
7281 class C
Doug Kearns74da0ee2023-12-14 20:26:26 +01007282 public static var {kword}: list<number> = [1, 2, 3]
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007283 endclass
7284 END
7285 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7286 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007287 endfor
7288enddef
7289
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007290" Test for checking the type of the arguments and the return value of a object
7291" method in an extended class.
7292def Test_extended_obj_method_type_check()
7293 var lines =<< trim END
7294 vim9script
7295
7296 class A
7297 endclass
7298 class B extends A
7299 endclass
7300 class C extends B
7301 endclass
7302
7303 class Foo
7304 def Doit(p: B): B
7305 return B.new()
7306 enddef
7307 endclass
7308
7309 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007310 def Doit(p: C): B
7311 return B.new()
7312 enddef
7313 endclass
7314 END
7315 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7316
7317 lines =<< trim END
7318 vim9script
7319
7320 class A
7321 endclass
7322 class B extends A
7323 endclass
7324 class C extends B
7325 endclass
7326
7327 class Foo
7328 def Doit(p: B): B
7329 return B.new()
7330 enddef
7331 endclass
7332
7333 class Bar extends Foo
7334 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007335 return C.new()
7336 enddef
7337 endclass
7338 END
7339 v9.CheckSourceSuccess(lines)
7340
7341 lines =<< trim END
7342 vim9script
7343
7344 class A
7345 endclass
7346 class B extends A
7347 endclass
7348 class C extends B
7349 endclass
7350
7351 class Foo
7352 def Doit(p: B): B
7353 return B.new()
7354 enddef
7355 endclass
7356
7357 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007358 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007359 return B.new()
7360 enddef
7361 endclass
7362 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007363 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 +02007364
7365 lines =<< trim END
7366 vim9script
7367
7368 class A
7369 endclass
7370 class B extends A
7371 endclass
7372 class C extends B
7373 endclass
7374
7375 class Foo
7376 def Doit(p: B): B
7377 return B.new()
7378 enddef
7379 endclass
7380
7381 class Bar extends Foo
7382 def Doit(p: B): A
7383 return A.new()
7384 enddef
7385 endclass
7386 END
7387 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 +02007388
7389 # check varargs type mismatch
7390 lines =<< trim END
7391 vim9script
7392
7393 class B
7394 def F(...xxx: list<any>)
7395 enddef
7396 endclass
7397 class C extends B
7398 def F(xxx: list<any>)
7399 enddef
7400 endclass
7401 END
7402 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 +02007403enddef
7404
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007405" Test type checking for class variable in assignments
7406func Test_class_variable_complex_type_check()
7407 " class variable with a specific type. Try assigning a different type at
7408 " script level.
7409 let lines =<< trim END
7410 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007411 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007412 return {}
7413 enddef
7414 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007415 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007416 endclass
7417 test_garbagecollect_now()
7418 A.Fn = "abc"
7419 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007420 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 +02007421
7422 " class variable with a specific type. Try assigning a different type at
7423 " class def method level.
7424 let lines =<< trim END
7425 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007426 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007427 return {}
7428 enddef
7429 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007430 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007431 def Bar()
7432 Fn = "abc"
7433 enddef
7434 endclass
7435 var a = A.new()
7436 test_garbagecollect_now()
7437 a.Bar()
7438 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007439 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 +02007440
7441 " class variable with a specific type. Try assigning a different type at
7442 " script def method level.
7443 let lines =<< trim END
7444 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007445 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007446 return {}
7447 enddef
7448 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007449 public static var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007450 endclass
7451 def Bar()
7452 A.Fn = "abc"
7453 enddef
7454 test_garbagecollect_now()
7455 Bar()
7456 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007457 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 +02007458
7459 " class variable without any type. Should be set to the initialization
7460 " expression type. Try assigning a different type from script level.
7461 let lines =<< trim END
7462 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007463 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007464 return {}
7465 enddef
7466 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007467 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007468 endclass
7469 test_garbagecollect_now()
7470 A.Fn = "abc"
7471 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007472 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 +02007473
7474 " class variable without any type. Should be set to the initialization
7475 " expression type. Try assigning a different type at class def level.
7476 let lines =<< trim END
7477 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007478 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007479 return {}
7480 enddef
7481 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007482 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007483 def Bar()
7484 Fn = "abc"
7485 enddef
7486 endclass
7487 var a = A.new()
7488 test_garbagecollect_now()
7489 a.Bar()
7490 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007491 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 +02007492
7493 " class variable without any type. Should be set to the initialization
7494 " expression type. Try assigning a different type at script def level.
7495 let lines =<< trim END
7496 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007497 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007498 return {}
7499 enddef
7500 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007501 public static var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007502 endclass
7503 def Bar()
7504 A.Fn = "abc"
7505 enddef
7506 test_garbagecollect_now()
7507 Bar()
7508 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007509 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 +02007510
7511 " class variable with 'any" type. Can be assigned different types.
7512 let lines =<< trim END
7513 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007514 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007515 return {}
7516 enddef
7517 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007518 public static var Fn: any = Foo
7519 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007520 endclass
7521 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007522 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007523 A.Fn = "abc"
7524 test_garbagecollect_now()
7525 assert_equal('string', typename(A.Fn))
7526 A.Fn2 = Foo
7527 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007528 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007529 A.Fn2 = "xyz"
7530 test_garbagecollect_now()
7531 assert_equal('string', typename(A.Fn2))
7532 END
7533 call v9.CheckSourceSuccess(lines)
7534
7535 " class variable with 'any" type. Can be assigned different types.
7536 let lines =<< trim END
7537 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007538 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007539 return {}
7540 enddef
7541 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007542 public static var Fn: any = Foo
7543 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007544
7545 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007546 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007547 Fn = "abc"
7548 assert_equal('string', typename(Fn))
7549 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007550 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007551 Fn2 = "xyz"
7552 assert_equal('string', typename(Fn2))
7553 enddef
7554 endclass
7555 var a = A.new()
7556 test_garbagecollect_now()
7557 a.Bar()
7558 test_garbagecollect_now()
7559 A.Fn = Foo
7560 a.Bar()
7561 END
7562 call v9.CheckSourceSuccess(lines)
7563
7564 " class variable with 'any" type. Can be assigned different types.
7565 let lines =<< trim END
7566 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007567 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007568 return {}
7569 enddef
7570 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007571 public static var Fn: any = Foo
7572 public static var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007573 endclass
7574
7575 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007576 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007577 A.Fn = "abc"
7578 assert_equal('string', typename(A.Fn))
7579 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007580 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007581 A.Fn2 = "xyz"
7582 assert_equal('string', typename(A.Fn2))
7583 enddef
7584 Bar()
7585 test_garbagecollect_now()
7586 A.Fn = Foo
7587 Bar()
7588 END
7589 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007590
7591 let lines =<< trim END
7592 vim9script
7593 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007594 public static var foo = [0z10, 0z20]
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007595 endclass
7596 assert_equal([0z10, 0z20], A.foo)
7597 A.foo = [0z30]
7598 assert_equal([0z30], A.foo)
7599 var a = A.foo
7600 assert_equal([0z30], a)
7601 END
7602 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007603endfunc
7604
7605" Test type checking for object variable in assignments
7606func Test_object_variable_complex_type_check()
7607 " object variable with a specific type. Try assigning a different type at
7608 " script level.
7609 let lines =<< trim END
7610 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007611 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007612 return {}
7613 enddef
7614 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007615 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007616 endclass
7617 var a = A.new()
7618 test_garbagecollect_now()
7619 a.Fn = "abc"
7620 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007621 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 +02007622
7623 " object variable with a specific type. Try assigning a different type at
7624 " object def method level.
7625 let lines =<< trim END
7626 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007627 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007628 return {}
7629 enddef
7630 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007631 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007632 def Bar()
7633 this.Fn = "abc"
7634 this.Fn = Foo
7635 enddef
7636 endclass
7637 var a = A.new()
7638 test_garbagecollect_now()
7639 a.Bar()
7640 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007641 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 +02007642
7643 " object variable with a specific type. Try assigning a different type at
7644 " script def method level.
7645 let lines =<< trim END
7646 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007647 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007648 return {}
7649 enddef
7650 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007651 public var Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007652 endclass
7653 def Bar()
7654 var a = A.new()
7655 a.Fn = "abc"
7656 a.Fn = Foo
7657 enddef
7658 test_garbagecollect_now()
7659 Bar()
7660 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007661 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 +02007662
7663 " object variable without any type. Should be set to the initialization
7664 " expression type. Try assigning a different type from script level.
7665 let lines =<< trim END
7666 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007667 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007668 return {}
7669 enddef
7670 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007671 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007672 endclass
7673 var a = A.new()
7674 test_garbagecollect_now()
7675 a.Fn = "abc"
7676 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007677 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 +02007678
7679 " object variable without any type. Should be set to the initialization
7680 " expression type. Try assigning a different type at object def level.
7681 let lines =<< trim END
7682 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007683 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007684 return {}
7685 enddef
7686 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007687 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007688 def Bar()
7689 this.Fn = "abc"
7690 this.Fn = Foo
7691 enddef
7692 endclass
7693 var a = A.new()
7694 test_garbagecollect_now()
7695 a.Bar()
7696 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007697 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 +02007698
7699 " object variable without any type. Should be set to the initialization
7700 " expression type. Try assigning a different type at script def level.
7701 let lines =<< trim END
7702 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007703 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007704 return {}
7705 enddef
7706 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007707 public var Fn = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007708 endclass
7709 def Bar()
7710 var a = A.new()
7711 a.Fn = "abc"
7712 a.Fn = Foo
7713 enddef
7714 test_garbagecollect_now()
7715 Bar()
7716 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007717 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 +02007718
7719 " object variable with 'any" type. Can be assigned different types.
7720 let lines =<< trim END
7721 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007722 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007723 return {}
7724 enddef
7725 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007726 public var Fn: any = Foo
7727 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007728 endclass
7729
7730 var a = A.new()
7731 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007732 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007733 a.Fn = "abc"
7734 test_garbagecollect_now()
7735 assert_equal('string', typename(a.Fn))
7736 a.Fn2 = Foo
7737 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007738 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007739 a.Fn2 = "xyz"
7740 test_garbagecollect_now()
7741 assert_equal('string', typename(a.Fn2))
7742 END
7743 call v9.CheckSourceSuccess(lines)
7744
7745 " object variable with 'any" type. Can be assigned different types.
7746 let lines =<< trim END
7747 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007748 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007749 return {}
7750 enddef
7751 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007752 public var Fn: any = Foo
7753 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007754
7755 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007756 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007757 this.Fn = "abc"
7758 assert_equal('string', typename(this.Fn))
7759 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007760 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007761 this.Fn2 = "xyz"
7762 assert_equal('string', typename(this.Fn2))
7763 enddef
7764 endclass
7765
7766 var a = A.new()
7767 test_garbagecollect_now()
7768 a.Bar()
7769 test_garbagecollect_now()
7770 a.Fn = Foo
7771 a.Bar()
7772 END
7773 call v9.CheckSourceSuccess(lines)
7774
7775 " object variable with 'any" type. Can be assigned different types.
7776 let lines =<< trim END
7777 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007778 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007779 return {}
7780 enddef
7781 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007782 public var Fn: any = Foo
7783 public var Fn2: any
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007784 endclass
7785
7786 def Bar()
7787 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007788 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007789 a.Fn = "abc"
7790 assert_equal('string', typename(a.Fn))
7791 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007792 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007793 a.Fn2 = "xyz"
7794 assert_equal('string', typename(a.Fn2))
7795 enddef
7796 test_garbagecollect_now()
7797 Bar()
7798 test_garbagecollect_now()
7799 Bar()
7800 END
7801 call v9.CheckSourceSuccess(lines)
7802endfunc
7803
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007804" Test for recursively calling an object method. This used to cause an
7805" use-after-free error.
7806def Test_recursive_object_method_call()
7807 var lines =<< trim END
7808 vim9script
7809 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007810 var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007811 def Foo(): number
7812 if this.val >= 90
7813 return this.val
7814 endif
7815 this.val += 1
7816 return this.Foo()
7817 enddef
7818 endclass
7819 var a = A.new()
7820 assert_equal(90, a.Foo())
7821 END
7822 v9.CheckSourceSuccess(lines)
7823enddef
7824
7825" Test for recursively calling a class method.
7826def Test_recursive_class_method_call()
7827 var lines =<< trim END
7828 vim9script
7829 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007830 static var val: number = 0
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007831 static def Foo(): number
7832 if val >= 90
7833 return val
7834 endif
7835 val += 1
7836 return Foo()
7837 enddef
7838 endclass
7839 assert_equal(90, A.Foo())
7840 END
7841 v9.CheckSourceSuccess(lines)
7842enddef
7843
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007844" Test for checking the argument types and the return type when assigning a
7845" funcref to make sure the invariant class type is used.
7846def Test_funcref_argtype_returntype_check()
7847 var lines =<< trim END
7848 vim9script
7849 class A
7850 endclass
7851 class B extends A
7852 endclass
7853
7854 def Foo(p: B): B
7855 return B.new()
7856 enddef
7857
7858 var Bar: func(A): A = Foo
7859 END
7860 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7861
7862 lines =<< trim END
7863 vim9script
7864 class A
7865 endclass
7866 class B extends A
7867 endclass
7868
7869 def Foo(p: B): B
7870 return B.new()
7871 enddef
7872
7873 def Baz()
7874 var Bar: func(A): A = Foo
7875 enddef
7876 Baz()
7877 END
7878 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7879enddef
7880
Ernie Rael96952b22023-10-17 18:15:01 +02007881def Test_funcref_argtype_invariance_check()
7882 var lines =<< trim END
7883 vim9script
7884
7885 class A
7886 endclass
7887 class B extends A
7888 endclass
7889 class C extends B
7890 endclass
7891
7892 var Func: func(B): number
7893 Func = (o: B): number => 3
7894 assert_equal(3, Func(B.new()))
7895 END
7896 v9.CheckSourceSuccess(lines)
7897
7898 lines =<< trim END
7899 vim9script
7900
7901 class A
7902 endclass
7903 class B extends A
7904 endclass
7905 class C extends B
7906 endclass
7907
7908 var Func: func(B): number
7909 Func = (o: A): number => 3
7910 END
7911 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7912
7913 lines =<< trim END
7914 vim9script
7915
7916 class A
7917 endclass
7918 class B extends A
7919 endclass
7920 class C extends B
7921 endclass
7922
7923 var Func: func(B): number
7924 Func = (o: C): number => 3
7925 END
7926 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7927enddef
7928
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007929" Test for using an operator (e.g. +) with an assignment
7930def Test_op_and_assignment()
7931 # Using += with a class variable
7932 var lines =<< trim END
7933 vim9script
7934 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007935 public static var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007936 static def Foo(): list<number>
7937 val += [1]
7938 return val
7939 enddef
7940 endclass
7941 def Bar(): list<number>
7942 A.val += [2]
7943 return A.val
7944 enddef
7945 assert_equal([1], A.Foo())
7946 assert_equal([1, 2], Bar())
7947 A.val += [3]
7948 assert_equal([1, 2, 3], A.val)
7949 END
7950 v9.CheckSourceSuccess(lines)
7951
7952 # Using += with an object variable
7953 lines =<< trim END
7954 vim9script
7955 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01007956 public var val: list<number> = []
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007957 def Foo(): list<number>
7958 this.val += [1]
7959 return this.val
7960 enddef
7961 endclass
7962 def Bar(bar_a: A): list<number>
7963 bar_a.val += [2]
7964 return bar_a.val
7965 enddef
7966 var a = A.new()
7967 assert_equal([1], a.Foo())
7968 assert_equal([1, 2], Bar(a))
7969 a.val += [3]
7970 assert_equal([1, 2, 3], a.val)
7971 END
7972 v9.CheckSourceSuccess(lines)
7973enddef
7974
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007975" Test for using an object method as a funcref
7976def Test_object_funcref()
7977 # Using object method funcref from a def function
7978 var lines =<< trim END
7979 vim9script
7980 class A
7981 def Foo(): list<number>
7982 return [3, 2, 1]
7983 enddef
7984 endclass
7985 def Bar()
7986 var a = A.new()
7987 var Fn = a.Foo
7988 assert_equal([3, 2, 1], Fn())
7989 enddef
7990 Bar()
7991 END
7992 v9.CheckSourceSuccess(lines)
7993
7994 # Using object method funcref at the script level
7995 lines =<< trim END
7996 vim9script
7997 class A
7998 def Foo(): dict<number>
7999 return {a: 1, b: 2}
8000 enddef
8001 endclass
8002 var a = A.new()
8003 var Fn = a.Foo
8004 assert_equal({a: 1, b: 2}, Fn())
8005 END
8006 v9.CheckSourceSuccess(lines)
8007
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008008 # Using object method funcref at the script level
8009 lines =<< trim END
8010 vim9script
8011 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008012 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008013 def Foo(): number
8014 return this.val
8015 enddef
8016 endclass
8017 var a = A.new(345)
8018 var Fn = a.Foo
8019 assert_equal(345, Fn())
8020 END
8021 v9.CheckSourceSuccess(lines)
8022
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008023 # Using object method funcref from another object method
8024 lines =<< trim END
8025 vim9script
8026 class A
8027 def Foo(): list<number>
8028 return [3, 2, 1]
8029 enddef
8030 def Bar()
8031 var Fn = this.Foo
8032 assert_equal([3, 2, 1], Fn())
8033 enddef
8034 endclass
8035 var a = A.new()
8036 a.Bar()
8037 END
8038 v9.CheckSourceSuccess(lines)
8039
8040 # Using function() to get a object method funcref
8041 lines =<< trim END
8042 vim9script
8043 class A
8044 def Foo(l: list<any>): list<any>
8045 return l
8046 enddef
8047 endclass
8048 var a = A.new()
8049 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
8050 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8051 END
8052 v9.CheckSourceSuccess(lines)
8053
8054 # Use an object method with a function returning a funcref and then call the
8055 # funcref.
8056 lines =<< trim END
8057 vim9script
8058
8059 def Map(F: func(number): number): func(number): number
8060 return (n: number) => F(n)
8061 enddef
8062
8063 class Math
8064 def Double(n: number): number
8065 return 2 * n
8066 enddef
8067 endclass
8068
8069 const math = Math.new()
8070 assert_equal(48, Map(math.Double)(24))
8071 END
8072 v9.CheckSourceSuccess(lines)
8073
Ernie Rael03042a22023-11-11 08:53:32 +01008074 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008075 lines =<< trim END
8076 vim9script
8077 class A
8078 def _Foo()
8079 enddef
8080 endclass
8081 def Bar()
8082 var a = A.new()
8083 var Fn = a._Foo
8084 enddef
8085 Bar()
8086 END
Ernie Rael03042a22023-11-11 08:53:32 +01008087 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008088
Ernie Rael03042a22023-11-11 08:53:32 +01008089 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008090 lines =<< trim END
8091 vim9script
8092 class A
8093 def _Foo()
8094 enddef
8095 endclass
8096 var a = A.new()
8097 var Fn = a._Foo
8098 END
Ernie Rael03042a22023-11-11 08:53:32 +01008099 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008100
Ernie Rael03042a22023-11-11 08:53:32 +01008101 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008102 lines =<< trim END
8103 vim9script
8104 class A
8105 def _Foo(): list<number>
8106 return [3, 2, 1]
8107 enddef
8108 def Bar()
8109 var Fn = this._Foo
8110 assert_equal([3, 2, 1], Fn())
8111 enddef
8112 endclass
8113 var a = A.new()
8114 a.Bar()
8115 END
8116 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008117
8118 # Using object method funcref using call()
8119 lines =<< trim END
8120 vim9script
8121 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008122 var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008123 def Foo(): number
8124 return this.val
8125 enddef
8126 endclass
8127
8128 def Bar(obj: A)
8129 assert_equal(123, call(obj.Foo, []))
8130 enddef
8131
8132 var a = A.new(123)
8133 Bar(a)
8134 assert_equal(123, call(a.Foo, []))
8135 END
8136 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008137enddef
8138
8139" Test for using a class method as a funcref
8140def Test_class_funcref()
8141 # Using class method funcref in a def function
8142 var lines =<< trim END
8143 vim9script
8144 class A
8145 static def Foo(): list<number>
8146 return [3, 2, 1]
8147 enddef
8148 endclass
8149 def Bar()
8150 var Fn = A.Foo
8151 assert_equal([3, 2, 1], Fn())
8152 enddef
8153 Bar()
8154 END
8155 v9.CheckSourceSuccess(lines)
8156
8157 # Using class method funcref at script level
8158 lines =<< trim END
8159 vim9script
8160 class A
8161 static def Foo(): dict<number>
8162 return {a: 1, b: 2}
8163 enddef
8164 endclass
8165 var Fn = A.Foo
8166 assert_equal({a: 1, b: 2}, Fn())
8167 END
8168 v9.CheckSourceSuccess(lines)
8169
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008170 # Using class method funcref at the script level
8171 lines =<< trim END
8172 vim9script
8173 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008174 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008175 static def Foo(): number
8176 return val
8177 enddef
8178 endclass
8179 A.val = 567
8180 var Fn = A.Foo
8181 assert_equal(567, Fn())
8182 END
8183 v9.CheckSourceSuccess(lines)
8184
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008185 # Using function() to get a class method funcref
8186 lines =<< trim END
8187 vim9script
8188 class A
8189 static def Foo(l: list<any>): list<any>
8190 return l
8191 enddef
8192 endclass
8193 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
8194 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
8195 END
8196 v9.CheckSourceSuccess(lines)
8197
8198 # Using a class method funcref from another class method
8199 lines =<< trim END
8200 vim9script
8201 class A
8202 static def Foo(): list<number>
8203 return [3, 2, 1]
8204 enddef
8205 static def Bar()
8206 var Fn = Foo
8207 assert_equal([3, 2, 1], Fn())
8208 enddef
8209 endclass
8210 A.Bar()
8211 END
8212 v9.CheckSourceSuccess(lines)
8213
8214 # Use a class method with a function returning a funcref and then call the
8215 # funcref.
8216 lines =<< trim END
8217 vim9script
8218
8219 def Map(F: func(number): number): func(number): number
8220 return (n: number) => F(n)
8221 enddef
8222
8223 class Math
8224 static def StaticDouble(n: number): number
8225 return 2 * n
8226 enddef
8227 endclass
8228
8229 assert_equal(48, Map(Math.StaticDouble)(24))
8230 END
8231 v9.CheckSourceSuccess(lines)
8232
Ernie Rael03042a22023-11-11 08:53:32 +01008233 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008234 lines =<< trim END
8235 vim9script
8236 class A
8237 static def _Foo()
8238 enddef
8239 endclass
8240 def Bar()
8241 var Fn = A._Foo
8242 enddef
8243 Bar()
8244 END
Ernie Rael03042a22023-11-11 08:53:32 +01008245 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008246
Ernie Rael03042a22023-11-11 08:53:32 +01008247 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008248 lines =<< trim END
8249 vim9script
8250 class A
8251 static def _Foo()
8252 enddef
8253 endclass
8254 var Fn = A._Foo
8255 END
Ernie Rael03042a22023-11-11 08:53:32 +01008256 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008257
Ernie Rael03042a22023-11-11 08:53:32 +01008258 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008259 lines =<< trim END
8260 vim9script
8261 class A
8262 static def _Foo(): list<number>
8263 return [3, 2, 1]
8264 enddef
8265 static def Bar()
8266 var Fn = _Foo
8267 assert_equal([3, 2, 1], Fn())
8268 enddef
8269 endclass
8270 A.Bar()
8271 END
8272 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008273
8274 # Using class method funcref using call()
8275 lines =<< trim END
8276 vim9script
8277 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008278 public static var val: number
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008279 static def Foo(): number
8280 return val
8281 enddef
8282 endclass
8283
8284 def Bar()
8285 A.val = 468
8286 assert_equal(468, call(A.Foo, []))
8287 enddef
8288 Bar()
8289 assert_equal(468, call(A.Foo, []))
8290 END
8291 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008292enddef
8293
8294" Test for using an object member as a funcref
8295def Test_object_member_funcref()
8296 # Using a funcref object variable in an object method
8297 var lines =<< trim END
8298 vim9script
8299 def Foo(n: number): number
8300 return n * 10
8301 enddef
8302
8303 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008304 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008305 def Bar()
8306 assert_equal(200, this.Cb(20))
8307 enddef
8308 endclass
8309
8310 var a = A.new()
8311 a.Bar()
8312 END
8313 v9.CheckSourceSuccess(lines)
8314
8315 # Using a funcref object variable in a def method
8316 lines =<< trim END
8317 vim9script
8318 def Foo(n: number): number
8319 return n * 10
8320 enddef
8321
8322 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008323 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008324 endclass
8325
8326 def Bar()
8327 var a = A.new()
8328 assert_equal(200, a.Cb(20))
8329 enddef
8330 Bar()
8331 END
8332 v9.CheckSourceSuccess(lines)
8333
8334 # Using a funcref object variable at script level
8335 lines =<< trim END
8336 vim9script
8337 def Foo(n: number): number
8338 return n * 10
8339 enddef
8340
8341 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008342 var Cb: func(number): number = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008343 endclass
8344
8345 var a = A.new()
8346 assert_equal(200, a.Cb(20))
8347 END
8348 v9.CheckSourceSuccess(lines)
8349
8350 # Using a funcref object variable pointing to an object method in an object
8351 # method.
8352 lines =<< trim END
8353 vim9script
8354 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008355 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008356 def Foo(n: number): number
8357 return n * 10
8358 enddef
8359 def Bar()
8360 assert_equal(200, this.Cb(20))
8361 enddef
8362 endclass
8363
8364 var a = A.new()
8365 a.Bar()
8366 END
8367 v9.CheckSourceSuccess(lines)
8368
8369 # Using a funcref object variable pointing to an object method in a def
8370 # method.
8371 lines =<< trim END
8372 vim9script
8373 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008374 var Cb: func(number): number = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008375 def Foo(n: number): number
8376 return n * 10
8377 enddef
8378 endclass
8379
8380 def Bar()
8381 var a = A.new()
8382 assert_equal(200, a.Cb(20))
8383 enddef
8384 Bar()
8385 END
8386 v9.CheckSourceSuccess(lines)
8387
8388 # Using a funcref object variable pointing to an object method at script
8389 # level.
8390 lines =<< trim END
8391 vim9script
8392 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008393 var Cb = this.Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008394 def Foo(n: number): number
8395 return n * 10
8396 enddef
8397 endclass
8398
8399 var a = A.new()
8400 assert_equal(200, a.Cb(20))
8401 END
8402 v9.CheckSourceSuccess(lines)
8403enddef
8404
8405" Test for using a class member as a funcref
8406def Test_class_member_funcref()
8407 # Using a funcref class variable in a class method
8408 var lines =<< trim END
8409 vim9script
8410 def Foo(n: number): number
8411 return n * 10
8412 enddef
8413
8414 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008415 static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008416 static def Bar()
8417 assert_equal(200, Cb(20))
8418 enddef
8419 endclass
8420
8421 A.Bar()
8422 END
8423 v9.CheckSourceSuccess(lines)
8424
8425 # Using a funcref class variable in a def method
8426 lines =<< trim END
8427 vim9script
8428 def Foo(n: number): number
8429 return n * 10
8430 enddef
8431
8432 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008433 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008434 endclass
8435
8436 def Bar()
8437 assert_equal(200, A.Cb(20))
8438 enddef
8439 Bar()
8440 END
8441 v9.CheckSourceSuccess(lines)
8442
8443 # Using a funcref class variable at script level
8444 lines =<< trim END
8445 vim9script
8446 def Foo(n: number): number
8447 return n * 10
8448 enddef
8449
8450 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008451 public static var Cb = Foo
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008452 endclass
8453
8454 assert_equal(200, A.Cb(20))
8455 END
8456 v9.CheckSourceSuccess(lines)
8457
8458 # Using a funcref class variable pointing to a class method in a class
8459 # method.
8460 lines =<< trim END
8461 vim9script
8462 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008463 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008464 static def Foo(n: number): number
8465 return n * 10
8466 enddef
8467 static def Init()
8468 Cb = Foo
8469 enddef
8470 static def Bar()
8471 assert_equal(200, Cb(20))
8472 enddef
8473 endclass
8474
8475 A.Init()
8476 A.Bar()
8477 END
8478 v9.CheckSourceSuccess(lines)
8479
8480 # Using a funcref class variable pointing to a class method in a def method.
8481 lines =<< trim END
8482 vim9script
8483 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008484 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008485 static def Foo(n: number): number
8486 return n * 10
8487 enddef
8488 static def Init()
8489 Cb = Foo
8490 enddef
8491 endclass
8492
8493 def Bar()
8494 A.Init()
8495 assert_equal(200, A.Cb(20))
8496 enddef
8497 Bar()
8498 END
8499 v9.CheckSourceSuccess(lines)
8500
8501 # Using a funcref class variable pointing to a class method at script level.
8502 lines =<< trim END
8503 vim9script
8504 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008505 static var Cb: func(number): number
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008506 static def Foo(n: number): number
8507 return n * 10
8508 enddef
8509 static def Init()
8510 Cb = Foo
8511 enddef
8512 endclass
8513
8514 A.Init()
8515 assert_equal(200, A.Cb(20))
8516 END
8517 v9.CheckSourceSuccess(lines)
8518enddef
8519
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008520" Test for using object methods as popup callback functions
8521def Test_objmethod_popup_callback()
8522 # Use the popup from the script level
8523 var lines =<< trim END
8524 vim9script
8525
8526 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008527 var selection: number = -1
8528 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008529
8530 def PopupFilter(id: number, key: string): bool
8531 add(this.filterkeys, key)
8532 return popup_filter_yesno(id, key)
8533 enddef
8534
8535 def PopupCb(id: number, result: number)
8536 this.selection = result ? 100 : 200
8537 enddef
8538 endclass
8539
8540 var a = A.new()
8541 feedkeys('', 'xt')
8542 var winid = popup_create('Y/N?',
8543 {filter: a.PopupFilter, callback: a.PopupCb})
8544 feedkeys('y', 'xt')
8545 popup_close(winid)
8546 assert_equal(100, a.selection)
8547 assert_equal(['y'], a.filterkeys)
8548 feedkeys('', 'xt')
8549 winid = popup_create('Y/N?',
8550 {filter: a.PopupFilter, callback: a.PopupCb})
8551 feedkeys('n', 'xt')
8552 popup_close(winid)
8553 assert_equal(200, a.selection)
8554 assert_equal(['y', 'n'], a.filterkeys)
8555 END
8556 v9.CheckSourceSuccess(lines)
8557
8558 # Use the popup from a def function
8559 lines =<< trim END
8560 vim9script
8561
8562 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008563 var selection: number = -1
8564 var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008565
8566 def PopupFilter(id: number, key: string): bool
8567 add(this.filterkeys, key)
8568 return popup_filter_yesno(id, key)
8569 enddef
8570
8571 def PopupCb(id: number, result: number)
8572 this.selection = result ? 100 : 200
8573 enddef
8574 endclass
8575
8576 def Foo()
8577 var a = A.new()
8578 feedkeys('', 'xt')
8579 var winid = popup_create('Y/N?',
8580 {filter: a.PopupFilter, callback: a.PopupCb})
8581 feedkeys('y', 'xt')
8582 popup_close(winid)
8583 assert_equal(100, a.selection)
8584 assert_equal(['y'], a.filterkeys)
8585 feedkeys('', 'xt')
8586 winid = popup_create('Y/N?',
8587 {filter: a.PopupFilter, callback: a.PopupCb})
8588 feedkeys('n', 'xt')
8589 popup_close(winid)
8590 assert_equal(200, a.selection)
8591 assert_equal(['y', 'n'], a.filterkeys)
8592 enddef
8593 Foo()
8594 END
8595 v9.CheckSourceSuccess(lines)
8596enddef
8597
8598" Test for using class methods as popup callback functions
8599def Test_classmethod_popup_callback()
8600 # Use the popup from the script level
8601 var lines =<< trim END
8602 vim9script
8603
8604 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008605 static var selection: number = -1
8606 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008607
8608 static def PopupFilter(id: number, key: string): bool
8609 add(filterkeys, key)
8610 return popup_filter_yesno(id, key)
8611 enddef
8612
8613 static def PopupCb(id: number, result: number)
8614 selection = result ? 100 : 200
8615 enddef
8616 endclass
8617
8618 feedkeys('', 'xt')
8619 var winid = popup_create('Y/N?',
8620 {filter: A.PopupFilter, callback: A.PopupCb})
8621 feedkeys('y', 'xt')
8622 popup_close(winid)
8623 assert_equal(100, A.selection)
8624 assert_equal(['y'], A.filterkeys)
8625 feedkeys('', 'xt')
8626 winid = popup_create('Y/N?',
8627 {filter: A.PopupFilter, callback: A.PopupCb})
8628 feedkeys('n', 'xt')
8629 popup_close(winid)
8630 assert_equal(200, A.selection)
8631 assert_equal(['y', 'n'], A.filterkeys)
8632 END
8633 v9.CheckSourceSuccess(lines)
8634
8635 # Use the popup from a def function
8636 lines =<< trim END
8637 vim9script
8638
8639 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008640 static var selection: number = -1
8641 static var filterkeys: list<string> = []
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008642
8643 static def PopupFilter(id: number, key: string): bool
8644 add(filterkeys, key)
8645 return popup_filter_yesno(id, key)
8646 enddef
8647
8648 static def PopupCb(id: number, result: number)
8649 selection = result ? 100 : 200
8650 enddef
8651 endclass
8652
8653 def Foo()
8654 feedkeys('', 'xt')
8655 var winid = popup_create('Y/N?',
8656 {filter: A.PopupFilter, callback: A.PopupCb})
8657 feedkeys('y', 'xt')
8658 popup_close(winid)
8659 assert_equal(100, A.selection)
8660 assert_equal(['y'], A.filterkeys)
8661 feedkeys('', 'xt')
8662 winid = popup_create('Y/N?',
8663 {filter: A.PopupFilter, callback: A.PopupCb})
8664 feedkeys('n', 'xt')
8665 popup_close(winid)
8666 assert_equal(200, A.selection)
8667 assert_equal(['y', 'n'], A.filterkeys)
8668 enddef
8669 Foo()
8670 END
8671 v9.CheckSourceSuccess(lines)
8672enddef
8673
8674" Test for using an object method as a timer callback function
8675def Test_objmethod_timer_callback()
8676 # Use the timer callback from script level
8677 var lines =<< trim END
8678 vim9script
8679
8680 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008681 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008682 def TimerCb(timerID: number)
8683 this.timerTick = 6
8684 enddef
8685 endclass
8686
8687 var a = A.new()
8688 timer_start(0, a.TimerCb)
8689 var maxWait = 5
8690 while maxWait > 0 && a.timerTick == -1
8691 :sleep 10m
8692 maxWait -= 1
8693 endwhile
8694 assert_equal(6, a.timerTick)
8695 END
8696 v9.CheckSourceSuccess(lines)
8697
8698 # Use the timer callback from a def function
8699 lines =<< trim END
8700 vim9script
8701
8702 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008703 var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008704 def TimerCb(timerID: number)
8705 this.timerTick = 6
8706 enddef
8707 endclass
8708
8709 def Foo()
8710 var a = A.new()
8711 timer_start(0, a.TimerCb)
8712 var maxWait = 5
8713 while maxWait > 0 && a.timerTick == -1
8714 :sleep 10m
8715 maxWait -= 1
8716 endwhile
8717 assert_equal(6, a.timerTick)
8718 enddef
8719 Foo()
8720 END
8721 v9.CheckSourceSuccess(lines)
8722enddef
8723
8724" Test for using a class method as a timer callback function
8725def Test_classmethod_timer_callback()
8726 # Use the timer callback from script level
8727 var lines =<< trim END
8728 vim9script
8729
8730 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008731 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008732 static def TimerCb(timerID: number)
8733 timerTick = 6
8734 enddef
8735 endclass
8736
8737 timer_start(0, A.TimerCb)
8738 var maxWait = 5
8739 while maxWait > 0 && A.timerTick == -1
8740 :sleep 10m
8741 maxWait -= 1
8742 endwhile
8743 assert_equal(6, A.timerTick)
8744 END
8745 v9.CheckSourceSuccess(lines)
8746
8747 # Use the timer callback from a def function
8748 lines =<< trim END
8749 vim9script
8750
8751 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008752 static var timerTick: number = -1
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008753 static def TimerCb(timerID: number)
8754 timerTick = 6
8755 enddef
8756 endclass
8757
8758 def Foo()
8759 timer_start(0, A.TimerCb)
8760 var maxWait = 5
8761 while maxWait > 0 && A.timerTick == -1
8762 :sleep 10m
8763 maxWait -= 1
8764 endwhile
8765 assert_equal(6, A.timerTick)
8766 enddef
8767 Foo()
8768 END
8769 v9.CheckSourceSuccess(lines)
8770enddef
8771
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008772" Test for using a class variable as the first and/or second operand of a binary
8773" operator.
8774def Test_class_variable_as_operands()
8775 var lines =<< trim END
8776 vim9script
8777 class Tests
Doug Kearns74da0ee2023-12-14 20:26:26 +01008778 static var truthy: bool = true
8779 public static var TruthyFn: func
8780 static var list: list<any> = []
8781 static var four: number = 4
8782 static var str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008783
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008784 static def Str(): string
8785 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008786 enddef
8787
8788 static def Four(): number
8789 return four
8790 enddef
8791
8792 static def List(): list<any>
8793 return list
8794 enddef
8795
8796 static def Truthy(): bool
8797 return truthy
8798 enddef
8799
8800 def TestOps()
8801 assert_true(Tests.truthy == truthy)
8802 assert_true(truthy == Tests.truthy)
8803 assert_true(Tests.list isnot [])
8804 assert_true([] isnot Tests.list)
8805 assert_equal(2, Tests.four >> 1)
8806 assert_equal(16, 1 << Tests.four)
8807 assert_equal(8, Tests.four + four)
8808 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008809 assert_equal('hellohello', Tests.str .. str)
8810 assert_equal('hellohello', str .. Tests.str)
8811
8812 # Using class variable for list indexing
8813 var l = range(10)
8814 assert_equal(4, l[Tests.four])
8815 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8816
8817 # Using class variable for Dict key
8818 var d = {hello: 'abc'}
8819 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008820 enddef
8821 endclass
8822
8823 def TestOps2()
8824 assert_true(Tests.truthy == Tests.Truthy())
8825 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008826 assert_true(Tests.truthy == Tests.TruthyFn())
8827 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008828 assert_true(Tests.list is Tests.List())
8829 assert_true(Tests.List() is Tests.list)
8830 assert_equal(2, Tests.four >> 1)
8831 assert_equal(16, 1 << Tests.four)
8832 assert_equal(8, Tests.four + Tests.Four())
8833 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008834 assert_equal('hellohello', Tests.str .. Tests.Str())
8835 assert_equal('hellohello', Tests.Str() .. Tests.str)
8836
8837 # Using class variable for list indexing
8838 var l = range(10)
8839 assert_equal(4, l[Tests.four])
8840 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8841
8842 # Using class variable for Dict key
8843 var d = {hello: 'abc'}
8844 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008845 enddef
8846
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008847 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008848 var t = Tests.new()
8849 t.TestOps()
8850 TestOps2()
8851
8852 assert_true(Tests.truthy == Tests.Truthy())
8853 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008854 assert_true(Tests.truthy == Tests.TruthyFn())
8855 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008856 assert_true(Tests.list is Tests.List())
8857 assert_true(Tests.List() is Tests.list)
8858 assert_equal(2, Tests.four >> 1)
8859 assert_equal(16, 1 << Tests.four)
8860 assert_equal(8, Tests.four + Tests.Four())
8861 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008862 assert_equal('hellohello', Tests.str .. Tests.Str())
8863 assert_equal('hellohello', Tests.Str() .. Tests.str)
8864
8865 # Using class variable for list indexing
8866 var l = range(10)
8867 assert_equal(4, l[Tests.four])
8868 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8869
8870 # Using class variable for Dict key
8871 var d = {hello: 'abc'}
8872 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008873 END
8874 v9.CheckSourceSuccess(lines)
8875enddef
8876
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008877" Test for checking the type of the key used to access an object dict member.
8878def Test_dict_member_key_type_check()
8879 var lines =<< trim END
8880 vim9script
8881
8882 abstract class State
Doug Kearns74da0ee2023-12-14 20:26:26 +01008883 var numbers: dict<string> = {0: 'nil', 1: 'unity'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008884 endclass
8885
8886 class Test extends State
8887 def ObjMethodTests()
8888 var cursor: number = 0
8889 var z: number = 0
8890 [this.numbers[cursor]] = ['zero.1']
8891 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8892 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8893 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8894 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8895 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8896 [this.numbers[cursor], z] = ['zero.4', 1]
8897 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8898 [z, this.numbers[cursor]] = [1, 'zero.5']
8899 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8900 enddef
8901
8902 static def ClassMethodTests(that: State)
8903 var cursor: number = 0
8904 var z: number = 0
8905 [that.numbers[cursor]] = ['zero.1']
8906 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8907 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8908 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8909 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8910 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8911 [that.numbers[cursor], z] = ['zero.4', 1]
8912 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8913 [z, that.numbers[cursor]] = [1, 'zero.5']
8914 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8915 enddef
8916
8917 def new()
8918 enddef
8919
8920 def newMethodTests()
8921 var cursor: number = 0
8922 var z: number
8923 [this.numbers[cursor]] = ['zero.1']
8924 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8925 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8926 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8927 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8928 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8929 [this.numbers[cursor], z] = ['zero.4', 1]
8930 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8931 [z, this.numbers[cursor]] = [1, 'zero.5']
8932 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8933 enddef
8934 endclass
8935
8936 def DefFuncTests(that: Test)
8937 var cursor: number = 0
8938 var z: number
8939 [that.numbers[cursor]] = ['zero.1']
8940 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8941 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8942 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8943 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8944 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8945 [that.numbers[cursor], z] = ['zero.4', 1]
8946 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8947 [z, that.numbers[cursor]] = [1, 'zero.5']
8948 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8949 enddef
8950
8951 Test.newMethodTests()
8952 Test.new().ObjMethodTests()
8953 Test.ClassMethodTests(Test.new())
8954 DefFuncTests(Test.new())
8955
8956 const test: Test = Test.new()
8957 var cursor: number = 0
8958 [test.numbers[cursor], cursor] = ['zero', 1]
8959 [cursor, test.numbers[cursor]] = [1, 'one']
8960 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8961 END
8962 v9.CheckSourceSuccess(lines)
8963
8964 lines =<< trim END
8965 vim9script
8966
8967 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008968 var numbers: dict<string> = {a: '1', b: '2'}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008969
8970 def new()
8971 enddef
8972
8973 def Foo()
8974 var z: number
8975 [this.numbers.a, z] = [{}, 10]
8976 enddef
8977 endclass
8978
8979 var a = A.new()
8980 a.Foo()
8981 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008982 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008983
8984 lines =<< trim END
8985 vim9script
8986
8987 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01008988 var numbers: dict<number> = {a: 1, b: 2}
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008989
8990 def new()
8991 enddef
8992
8993 def Foo()
8994 var x: string = 'a'
8995 var y: number
8996 [this.numbers[x], y] = [{}, 10]
8997 enddef
8998 endclass
8999
9000 var a = A.new()
9001 a.Foo()
9002 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01009003 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02009004enddef
9005
mityua5550692023-11-25 15:41:20 +01009006def Test_compile_many_def_functions_in_funcref_instr()
9007 # This used to crash Vim. This is reproducible only when run on new instance
9008 # of Vim.
9009 var lines =<< trim END
9010 vim9script
9011
9012 class A
9013 def new()
9014 this.TakeFunc(this.F00)
9015 enddef
9016
9017 def TakeFunc(F: func)
9018 enddef
9019
9020 def F00()
9021 this.F01()
9022 this.F02()
9023 this.F03()
9024 this.F04()
9025 this.F05()
9026 this.F06()
9027 this.F07()
9028 this.F08()
9029 this.F09()
9030 this.F10()
9031 this.F11()
9032 this.F12()
9033 this.F13()
9034 this.F14()
9035 this.F15()
9036 this.F16()
9037 this.F17()
9038 this.F18()
9039 this.F19()
9040 this.F20()
9041 this.F21()
9042 this.F22()
9043 this.F23()
9044 this.F24()
9045 this.F25()
9046 this.F26()
9047 this.F27()
9048 this.F28()
9049 this.F29()
9050 this.F30()
9051 this.F31()
9052 this.F32()
9053 this.F33()
9054 this.F34()
9055 this.F35()
9056 this.F36()
9057 this.F37()
9058 this.F38()
9059 this.F39()
9060 this.F40()
9061 this.F41()
9062 this.F42()
9063 this.F43()
9064 this.F44()
9065 this.F45()
9066 this.F46()
9067 this.F47()
9068 enddef
9069
9070 def F01()
9071 enddef
9072 def F02()
9073 enddef
9074 def F03()
9075 enddef
9076 def F04()
9077 enddef
9078 def F05()
9079 enddef
9080 def F06()
9081 enddef
9082 def F07()
9083 enddef
9084 def F08()
9085 enddef
9086 def F09()
9087 enddef
9088 def F10()
9089 enddef
9090 def F11()
9091 enddef
9092 def F12()
9093 enddef
9094 def F13()
9095 enddef
9096 def F14()
9097 enddef
9098 def F15()
9099 enddef
9100 def F16()
9101 enddef
9102 def F17()
9103 enddef
9104 def F18()
9105 enddef
9106 def F19()
9107 enddef
9108 def F20()
9109 enddef
9110 def F21()
9111 enddef
9112 def F22()
9113 enddef
9114 def F23()
9115 enddef
9116 def F24()
9117 enddef
9118 def F25()
9119 enddef
9120 def F26()
9121 enddef
9122 def F27()
9123 enddef
9124 def F28()
9125 enddef
9126 def F29()
9127 enddef
9128 def F30()
9129 enddef
9130 def F31()
9131 enddef
9132 def F32()
9133 enddef
9134 def F33()
9135 enddef
9136 def F34()
9137 enddef
9138 def F35()
9139 enddef
9140 def F36()
9141 enddef
9142 def F37()
9143 enddef
9144 def F38()
9145 enddef
9146 def F39()
9147 enddef
9148 def F40()
9149 enddef
9150 def F41()
9151 enddef
9152 def F42()
9153 enddef
9154 def F43()
9155 enddef
9156 def F44()
9157 enddef
9158 def F45()
9159 enddef
9160 def F46()
9161 enddef
9162 def F47()
9163 enddef
9164 endclass
9165
9166 A.new()
9167 END
9168 writefile(lines, 'Xscript', 'D')
9169 g:RunVim([], [], '-u NONE -S Xscript -c qa')
9170 assert_equal(0, v:shell_error)
9171enddef
9172
Yegappan Lakshmanane5437c52023-12-16 14:11:19 +01009173" Test for 'final' class and object variables
9174def Test_final_class_object_variable()
9175 # Test for changing a final object variable from an object function
9176 var lines =<< trim END
9177 vim9script
9178 class A
9179 final foo: string = "abc"
9180 def Foo()
9181 this.foo = "def"
9182 enddef
9183 endclass
9184 defcompile A.Foo
9185 END
9186 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9187
9188 # Test for changing a final object variable from the 'new' function
9189 lines =<< trim END
9190 vim9script
9191 class A
9192 final s1: string
9193 final s2: string
9194 def new(this.s1)
9195 this.s2 = 'def'
9196 enddef
9197 endclass
9198 var a = A.new('abc')
9199 assert_equal('abc', a.s1)
9200 assert_equal('def', a.s2)
9201 END
9202 v9.CheckSourceSuccess(lines)
9203
9204 # Test for a final class variable
9205 lines =<< trim END
9206 vim9script
9207 class A
9208 static final s1: string = "abc"
9209 endclass
9210 assert_equal('abc', A.s1)
9211 END
9212 v9.CheckSourceSuccess(lines)
9213
9214 # Test for changing a final class variable from a class function
9215 lines =<< trim END
9216 vim9script
9217 class A
9218 static final s1: string = "abc"
9219 static def Foo()
9220 s1 = "def"
9221 enddef
9222 endclass
9223 A.Foo()
9224 END
9225 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9226
9227 # Test for changing a public final class variable at script level
9228 lines =<< trim END
9229 vim9script
9230 class A
9231 public static final s1: string = "abc"
9232 endclass
9233 assert_equal('abc', A.s1)
9234 A.s1 = 'def'
9235 END
9236 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9237
9238 # Test for changing a public final class variable from a class function
9239 lines =<< trim END
9240 vim9script
9241 class A
9242 public static final s1: string = "abc"
9243 static def Foo()
9244 s1 = "def"
9245 enddef
9246 endclass
9247 A.Foo()
9248 END
9249 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9250
9251 # Test for changing a public final class variable from a function
9252 lines =<< trim END
9253 vim9script
9254 class A
9255 public static final s1: string = "abc"
9256 endclass
9257 def Foo()
9258 A.s1 = 'def'
9259 enddef
9260 defcompile
9261 END
9262 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9263
9264 # Test for using a final variable of composite type
9265 lines =<< trim END
9266 vim9script
9267 class A
9268 public final l: list<number>
9269 def new()
9270 this.l = [1, 2]
9271 enddef
9272 def Foo()
9273 this.l[0] = 3
9274 this.l->add(4)
9275 enddef
9276 endclass
9277 var a = A.new()
9278 assert_equal([1, 2], a.l)
9279 a.Foo()
9280 assert_equal([3, 2, 4], a.l)
9281 END
9282 v9.CheckSourceSuccess(lines)
9283
9284 # Test for changing a final variable of composite type from another object
9285 # function
9286 lines =<< trim END
9287 vim9script
9288 class A
9289 public final l: list<number> = [1, 2]
9290 def Foo()
9291 this.l = [3, 4]
9292 enddef
9293 endclass
9294 var a = A.new()
9295 a.Foo()
9296 END
9297 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9298
9299 # Test for modifying a final variable of composite type at script level
9300 lines =<< trim END
9301 vim9script
9302 class A
9303 public final l: list<number> = [1, 2]
9304 endclass
9305 var a = A.new()
9306 a.l[0] = 3
9307 a.l->add(4)
9308 assert_equal([3, 2, 4], a.l)
9309 END
9310 v9.CheckSourceSuccess(lines)
9311
9312 # Test for modifying a final variable of composite type from a function
9313 lines =<< trim END
9314 vim9script
9315 class A
9316 public final l: list<number> = [1, 2]
9317 endclass
9318 def Foo()
9319 var a = A.new()
9320 a.l[0] = 3
9321 a.l->add(4)
9322 assert_equal([3, 2, 4], a.l)
9323 enddef
9324 Foo()
9325 END
9326 v9.CheckSourceSuccess(lines)
9327
9328 # Test for modifying a final variable of composite type from another object
9329 # function
9330 lines =<< trim END
9331 vim9script
9332 class A
9333 public final l: list<number> = [1, 2]
9334 def Foo()
9335 this.l[0] = 3
9336 this.l->add(4)
9337 enddef
9338 endclass
9339 var a = A.new()
9340 a.Foo()
9341 assert_equal([3, 2, 4], a.l)
9342 END
9343 v9.CheckSourceSuccess(lines)
9344
9345 # Test for assigning a new value to a final variable of composite type at
9346 # script level
9347 lines =<< trim END
9348 vim9script
9349 class A
9350 public final l: list<number> = [1, 2]
9351 endclass
9352 var a = A.new()
9353 a.l = [3, 4]
9354 END
9355 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9356
9357 # Test for assigning a new value to a final variable of composite type from
9358 # another object function
9359 lines =<< trim END
9360 vim9script
9361 class A
9362 public final l: list<number> = [1, 2]
9363 def Foo()
9364 this.l = [3, 4]
9365 enddef
9366 endclass
9367 var a = A.new()
9368 a.Foo()
9369 END
9370 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9371
9372 # Test for assigning a new value to a final variable of composite type from
9373 # another function
9374 lines =<< trim END
9375 vim9script
9376 class A
9377 public final l: list<number> = [1, 2]
9378 endclass
9379 def Foo()
9380 var a = A.new()
9381 a.l = [3, 4]
9382 enddef
9383 Foo()
9384 END
9385 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9386
9387 # Error case: Use 'final' with just a variable name
9388 lines =<< trim END
9389 vim9script
9390 class A
9391 final foo
9392 endclass
9393 var a = A.new()
9394 END
9395 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9396
9397 # Error case: Use 'final' followed by 'public'
9398 lines =<< trim END
9399 vim9script
9400 class A
9401 final public foo: number
9402 endclass
9403 var a = A.new()
9404 END
9405 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9406
9407 # Error case: Use 'final' followed by 'static'
9408 lines =<< trim END
9409 vim9script
9410 class A
9411 final static foo: number
9412 endclass
9413 var a = A.new()
9414 END
9415 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9416
9417 # Error case: 'final' cannot be used in an interface
9418 lines =<< trim END
9419 vim9script
9420 interface A
9421 final foo: number = 10
9422 endinterface
9423 END
9424 v9.CheckSourceFailure(lines, 'E1408: Final variable not supported in an interface', 3)
9425
9426 # Error case: 'final' not supported for an object method
9427 lines =<< trim END
9428 vim9script
9429 class A
9430 final def Foo()
9431 enddef
9432 endclass
9433 END
9434 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9435
9436 # Error case: 'final' not supported for a class method
9437 lines =<< trim END
9438 vim9script
9439 class A
9440 static final def Foo()
9441 enddef
9442 endclass
9443 END
9444 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9445enddef
9446
9447" Test for 'const' class and object variables
9448def Test_const_class_object_variable()
9449 # Test for changing a const object variable from an object function
9450 var lines =<< trim END
9451 vim9script
9452 class A
9453 const foo: string = "abc"
9454 def Foo()
9455 this.foo = "def"
9456 enddef
9457 endclass
9458 defcompile A.Foo
9459 END
9460 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "foo" in class "A"', 1)
9461
9462 # Test for changing a const object variable from the 'new' function
9463 lines =<< trim END
9464 vim9script
9465 class A
9466 const s1: string
9467 const s2: string
9468 def new(this.s1)
9469 this.s2 = 'def'
9470 enddef
9471 endclass
9472 var a = A.new('abc')
9473 assert_equal('abc', a.s1)
9474 assert_equal('def', a.s2)
9475 END
9476 v9.CheckSourceSuccess(lines)
9477
9478 # Test for changing a const object variable from an object method called from
9479 # the 'new' function
9480 lines =<< trim END
9481 vim9script
9482 class A
9483 const s1: string = 'abc'
9484 def new()
9485 this.ChangeStr()
9486 enddef
9487 def ChangeStr()
9488 this.s1 = 'def'
9489 enddef
9490 endclass
9491 var a = A.new()
9492 END
9493 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9494
9495 # Test for a const class variable
9496 lines =<< trim END
9497 vim9script
9498 class A
9499 static const s1: string = "abc"
9500 endclass
9501 assert_equal('abc', A.s1)
9502 END
9503 v9.CheckSourceSuccess(lines)
9504
9505 # Test for changing a const class variable from a class function
9506 lines =<< trim END
9507 vim9script
9508 class A
9509 static const s1: string = "abc"
9510 static def Foo()
9511 s1 = "def"
9512 enddef
9513 endclass
9514 A.Foo()
9515 END
9516 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9517
9518 # Test for changing a public const class variable at script level
9519 lines =<< trim END
9520 vim9script
9521 class A
9522 public static const s1: string = "abc"
9523 endclass
9524 assert_equal('abc', A.s1)
9525 A.s1 = 'def'
9526 END
9527 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 6)
9528
9529 # Test for changing a public const class variable from a class function
9530 lines =<< trim END
9531 vim9script
9532 class A
9533 public static const s1: string = "abc"
9534 static def Foo()
9535 s1 = "def"
9536 enddef
9537 endclass
9538 A.Foo()
9539 END
9540 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9541
9542 # Test for changing a public const class variable from a function
9543 lines =<< trim END
9544 vim9script
9545 class A
9546 public static const s1: string = "abc"
9547 endclass
9548 def Foo()
9549 A.s1 = 'def'
9550 enddef
9551 defcompile
9552 END
9553 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "s1" in class "A"', 1)
9554
9555 # Test for changing a const List item from an object function
9556 lines =<< trim END
9557 vim9script
9558 class A
9559 public const l: list<number>
9560 def new()
9561 this.l = [1, 2]
9562 enddef
9563 def Foo()
9564 this.l[0] = 3
9565 enddef
9566 endclass
9567 var a = A.new()
9568 assert_equal([1, 2], a.l)
9569 a.Foo()
9570 END
9571 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9572
9573 # Test for adding a value to a const List from an object function
9574 lines =<< trim END
9575 vim9script
9576 class A
9577 public const l: list<number>
9578 def new()
9579 this.l = [1, 2]
9580 enddef
9581 def Foo()
9582 this.l->add(3)
9583 enddef
9584 endclass
9585 var a = A.new()
9586 a.Foo()
9587 END
9588 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9589
9590 # Test for reassigning a const List from an object function
9591 lines =<< trim END
9592 vim9script
9593 class A
9594 public const l: list<number> = [1, 2]
9595 def Foo()
9596 this.l = [3, 4]
9597 enddef
9598 endclass
9599 var a = A.new()
9600 a.Foo()
9601 END
9602 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9603
9604 # Test for changing a const List item at script level
9605 lines =<< trim END
9606 vim9script
9607 class A
9608 public const l: list<number> = [1, 2]
9609 endclass
9610 var a = A.new()
9611 a.l[0] = 3
9612 END
9613 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9614
9615 # Test for adding a value to a const List item at script level
9616 lines =<< trim END
9617 vim9script
9618 class A
9619 public const l: list<number> = [1, 2]
9620 endclass
9621 var a = A.new()
9622 a.l->add(4)
9623 END
9624 v9.CheckSourceFailure(lines, 'E741: Value is locked:', 6)
9625
9626 # Test for changing a const List item from a function
9627 lines =<< trim END
9628 vim9script
9629 class A
9630 public const l: list<number> = [1, 2]
9631 endclass
9632 def Foo()
9633 var a = A.new()
9634 a.l[0] = 3
9635 enddef
9636 Foo()
9637 END
9638 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 2)
9639
9640 # Test for adding a value to a const List item from a function
9641 lines =<< trim END
9642 vim9script
9643 class A
9644 public const l: list<number> = [1, 2]
9645 endclass
9646 def Foo()
9647 var a = A.new()
9648 a.l->add(4)
9649 enddef
9650 Foo()
9651 END
9652 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 2)
9653
9654 # Test for changing a const List item from an object method
9655 lines =<< trim END
9656 vim9script
9657 class A
9658 public const l: list<number> = [1, 2]
9659 def Foo()
9660 this.l[0] = 3
9661 enddef
9662 endclass
9663 var a = A.new()
9664 a.Foo()
9665 END
9666 v9.CheckSourceFailure(lines, 'E1119: Cannot change locked list item', 1)
9667
9668 # Test for adding a value to a const List item from an object method
9669 lines =<< trim END
9670 vim9script
9671 class A
9672 public const l: list<number> = [1, 2]
9673 def Foo()
9674 this.l->add(4)
9675 enddef
9676 endclass
9677 var a = A.new()
9678 a.Foo()
9679 END
9680 v9.CheckSourceFailure(lines, 'E741: Value is locked: add() argument', 1)
9681
9682 # Test for reassigning a const List object variable at script level
9683 lines =<< trim END
9684 vim9script
9685 class A
9686 public const l: list<number> = [1, 2]
9687 endclass
9688 var a = A.new()
9689 a.l = [3, 4]
9690 END
9691 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 6)
9692
9693 # Test for reassigning a const List object variable from an object method
9694 lines =<< trim END
9695 vim9script
9696 class A
9697 public const l: list<number> = [1, 2]
9698 def Foo()
9699 this.l = [3, 4]
9700 enddef
9701 endclass
9702 var a = A.new()
9703 a.Foo()
9704 END
9705 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 1)
9706
9707 # Test for reassigning a const List object variable from another function
9708 lines =<< trim END
9709 vim9script
9710 class A
9711 public const l: list<number> = [1, 2]
9712 endclass
9713 def Foo()
9714 var a = A.new()
9715 a.l = [3, 4]
9716 enddef
9717 Foo()
9718 END
9719 v9.CheckSourceFailure(lines, 'E1409: Cannot change read-only variable "l" in class "A"', 2)
9720
9721 # Error case: Use 'const' with just a variable name
9722 lines =<< trim END
9723 vim9script
9724 class A
9725 const foo
9726 endclass
9727 var a = A.new()
9728 END
9729 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9730
9731 # Error case: Use 'const' followed by 'public'
9732 lines =<< trim END
9733 vim9script
9734 class A
9735 const public foo: number
9736 endclass
9737 var a = A.new()
9738 END
9739 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9740
9741 # Error case: Use 'const' followed by 'static'
9742 lines =<< trim END
9743 vim9script
9744 class A
9745 const static foo: number
9746 endclass
9747 var a = A.new()
9748 END
9749 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9750
9751 # Error case: 'const' cannot be used in an interface
9752 lines =<< trim END
9753 vim9script
9754 interface A
9755 const foo: number = 10
9756 endinterface
9757 END
9758 v9.CheckSourceFailure(lines, 'E1410: Const variable not supported in an interface', 3)
9759
9760 # Error case: 'const' not supported for an object method
9761 lines =<< trim END
9762 vim9script
9763 class A
9764 const def Foo()
9765 enddef
9766 endclass
9767 END
9768 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9769
9770 # Error case: 'const' not supported for a class method
9771 lines =<< trim END
9772 vim9script
9773 class A
9774 static const def Foo()
9775 enddef
9776 endclass
9777 END
9778 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
9779enddef
9780
Yegappan Lakshmanan4f32c832024-01-12 17:36:40 +01009781" Test for compiling class/object methods using :defcompile
9782def Test_defcompile_class()
9783 # defcompile all the classes in the current script
9784 var lines =<< trim END
9785 vim9script
9786 class A
9787 def Foo()
9788 var i = 10
9789 enddef
9790 endclass
9791 class B
9792 def Bar()
9793 var i = 20
9794 xxx
9795 enddef
9796 endclass
9797 defcompile
9798 END
9799 v9.CheckSourceFailure(lines, 'E476: Invalid command: xxx', 2)
9800
9801 # defcompile a specific class
9802 lines =<< trim END
9803 vim9script
9804 class A
9805 def Foo()
9806 xxx
9807 enddef
9808 endclass
9809 class B
9810 def Bar()
9811 yyy
9812 enddef
9813 endclass
9814 defcompile B
9815 END
9816 v9.CheckSourceFailure(lines, 'E476: Invalid command: yyy', 1)
9817
9818 # defcompile a non-class
9819 lines =<< trim END
9820 vim9script
9821 class A
9822 def Foo()
9823 enddef
9824 endclass
9825 var X: list<number> = []
9826 defcompile X
9827 END
9828 v9.CheckSourceFailure(lines, 'E1061: Cannot find function X', 7)
9829
9830 # defcompile a class twice
9831 lines =<< trim END
9832 vim9script
9833 class A
9834 def new()
9835 enddef
9836 endclass
9837 defcompile A
9838 defcompile A
9839 assert_equal('Function A.new does not need compiling', v:statusmsg)
9840 END
9841 v9.CheckSourceSuccess(lines)
9842
9843 # defcompile should not compile an imported class
9844 lines =<< trim END
9845 vim9script
9846 export class A
9847 def Foo()
9848 xxx
9849 enddef
9850 endclass
9851 END
9852 writefile(lines, 'Xdefcompileimport.vim', 'D')
9853 lines =<< trim END
9854 vim9script
9855
9856 import './Xdefcompileimport.vim'
9857 class B
9858 endclass
9859 defcompile
9860 END
9861 v9.CheckScriptSuccess(lines)
9862enddef
9863
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01009864" Test for cases common to all the object builtin methods
9865def Test_object_builtin_method()
9866 var lines =<< trim END
9867 vim9script
9868 class A
9869 def abc()
9870 enddef
9871 endclass
9872 END
9873 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: abc()', 3)
9874
9875 for funcname in ["len", "string", "empty"]
9876 lines =<< trim eval END
9877 vim9script
9878 class A
9879 static def {funcname}(): number
9880 enddef
9881 endclass
9882 END
9883 v9.CheckSourceFailure(lines, 'E1413: Builtin class method not supported', 3)
9884 endfor
9885enddef
9886
9887" Test for using the empty() builtin method with an object
9888" This is a legacy function to use the test_garbagecollect_now() function.
9889func Test_object_empty()
9890 let lines =<< trim END
9891 vim9script
9892 class A
9893 def empty(): bool
9894 return true
9895 enddef
9896 endclass
9897
9898 def Foo()
9899 var afoo = A.new()
9900 assert_equal(true, empty(afoo))
9901 assert_equal(true, afoo->empty())
9902 enddef
9903
9904 var a = A.new()
9905 assert_equal(1, empty(a))
9906 assert_equal(1, a->empty())
9907 test_garbagecollect_now()
9908 assert_equal(1, empty(a))
9909 Foo()
9910 test_garbagecollect_now()
9911 Foo()
9912 END
9913 call v9.CheckSourceSuccess(lines)
9914
9915 " empty() should return 1 without a builtin method
9916 let lines =<< trim END
9917 vim9script
9918 class A
9919 endclass
9920
9921 def Foo()
9922 var afoo = A.new()
9923 assert_equal(1, empty(afoo))
9924 enddef
9925
9926 var a = A.new()
9927 assert_equal(1, empty(a))
9928 Foo()
9929 END
9930 call v9.CheckSourceSuccess(lines)
9931
9932 " Unsupported signature for the empty() method
9933 let lines =<< trim END
9934 vim9script
9935 class A
9936 def empty()
9937 enddef
9938 endclass
9939 END
9940 call v9.CheckSourceFailure(lines, 'E1383: Method "empty": type mismatch, expected func(): bool but got func()', 4)
9941
9942 " Error when calling the empty() method
9943 let lines =<< trim END
9944 vim9script
9945 class A
9946 def empty(): bool
9947 throw "Failed to check emptiness"
9948 enddef
9949 endclass
9950
9951 def Foo()
9952 var afoo = A.new()
9953 var i = empty(afoo)
9954 enddef
9955
9956 var a = A.new()
9957 assert_fails('empty(a)', 'Failed to check emptiness')
9958 assert_fails('Foo()', 'Failed to check emptiness')
9959 END
9960 call v9.CheckSourceSuccess(lines)
9961
9962 " call empty() using an object from a script
9963 let lines =<< trim END
9964 vim9script
9965 class A
9966 def empty(): bool
9967 return true
9968 enddef
9969 endclass
9970 var afoo = A.new()
9971 assert_equal(true, afoo.empty())
9972 END
9973 call v9.CheckSourceSuccess(lines)
9974
9975 " call empty() using an object from a method
9976 let lines =<< trim END
9977 vim9script
9978 class A
9979 def empty(): bool
9980 return true
9981 enddef
9982 endclass
9983 def Foo()
9984 var afoo = A.new()
9985 assert_equal(true, afoo.empty())
9986 enddef
9987 Foo()
9988 END
9989 call v9.CheckSourceSuccess(lines)
9990
9991 " call empty() using "this" from an object method
9992 let lines =<< trim END
9993 vim9script
9994 class A
9995 def empty(): bool
9996 return true
9997 enddef
9998 def Foo(): bool
9999 return this.empty()
10000 enddef
10001 endclass
10002 def Bar()
10003 var abar = A.new()
10004 assert_equal(true, abar.Foo())
10005 enddef
10006 Bar()
10007 END
10008 call v9.CheckSourceSuccess(lines)
10009
10010 " Call empty() from a derived object
10011 let lines =<< trim END
10012 vim9script
10013 class A
10014 def empty(): bool
10015 return false
10016 enddef
10017 endclass
10018 class B extends A
10019 def empty(): bool
10020 return true
10021 enddef
10022 endclass
10023 def Foo(afoo: A)
10024 assert_equal(true, empty(afoo))
10025 var bfoo = B.new()
10026 assert_equal(true, empty(bfoo))
10027 enddef
10028 var b = B.new()
10029 assert_equal(1, empty(b))
10030 Foo(b)
10031 END
10032 call v9.CheckSourceSuccess(lines)
10033
10034 " Invoking empty method using an interface
10035 let lines =<< trim END
10036 vim9script
10037 interface A
10038 def empty(): bool
10039 endinterface
10040 class B implements A
10041 def empty(): bool
10042 return false
10043 enddef
10044 endclass
10045 def Foo(a: A)
10046 assert_equal(false, empty(a))
10047 enddef
10048 var b = B.new()
10049 Foo(b)
10050 END
10051 call v9.CheckSourceSuccess(lines)
10052endfunc
10053
10054" Test for using the len() builtin method with an object
10055" This is a legacy function to use the test_garbagecollect_now() function.
10056func Test_object_length()
10057 let lines =<< trim END
10058 vim9script
10059 class A
10060 var mylen: number = 0
10061 def new(n: number)
10062 this.mylen = n
10063 enddef
10064 def len(): number
10065 return this.mylen
10066 enddef
10067 endclass
10068
10069 def Foo()
10070 var afoo = A.new(12)
10071 assert_equal(12, len(afoo))
10072 assert_equal(12, afoo->len())
10073 enddef
10074
10075 var a = A.new(22)
10076 assert_equal(22, len(a))
10077 assert_equal(22, a->len())
10078 test_garbagecollect_now()
10079 assert_equal(22, len(a))
10080 Foo()
10081 test_garbagecollect_now()
10082 Foo()
10083 END
10084 call v9.CheckSourceSuccess(lines)
10085
10086 " len() should return 0 without a builtin method
10087 let lines =<< trim END
10088 vim9script
10089 class A
10090 endclass
10091
10092 def Foo()
10093 var afoo = A.new()
10094 assert_equal(0, len(afoo))
10095 enddef
10096
10097 var a = A.new()
10098 assert_equal(0, len(a))
10099 Foo()
10100 END
10101 call v9.CheckSourceSuccess(lines)
10102
10103 " Unsupported signature for the len() method
10104 let lines =<< trim END
10105 vim9script
10106 class A
10107 def len()
10108 enddef
10109 endclass
10110 END
10111 call v9.CheckSourceFailure(lines, 'E1383: Method "len": type mismatch, expected func(): number but got func()', 4)
10112
10113 " Error when calling the len() method
10114 let lines =<< trim END
10115 vim9script
10116 class A
10117 def len(): number
10118 throw "Failed to compute length"
10119 enddef
10120 endclass
10121
10122 def Foo()
10123 var afoo = A.new()
10124 var i = len(afoo)
10125 enddef
10126
10127 var a = A.new()
10128 assert_fails('len(a)', 'Failed to compute length')
10129 assert_fails('Foo()', 'Failed to compute length')
10130 END
10131 call v9.CheckSourceSuccess(lines)
10132
10133 " call len() using an object from a script
10134 let lines =<< trim END
10135 vim9script
10136 class A
10137 def len(): number
10138 return 5
10139 enddef
10140 endclass
10141 var afoo = A.new()
10142 assert_equal(5, afoo.len())
10143 END
10144 call v9.CheckSourceSuccess(lines)
10145
10146 " call len() using an object from a method
10147 let lines =<< trim END
10148 vim9script
10149 class A
10150 def len(): number
10151 return 5
10152 enddef
10153 endclass
10154 def Foo()
10155 var afoo = A.new()
10156 assert_equal(5, afoo.len())
10157 enddef
10158 Foo()
10159 END
10160 call v9.CheckSourceSuccess(lines)
10161
10162 " call len() using "this" from an object method
10163 let lines =<< trim END
10164 vim9script
10165 class A
10166 def len(): number
10167 return 8
10168 enddef
10169 def Foo(): number
10170 return this.len()
10171 enddef
10172 endclass
10173 def Bar()
10174 var abar = A.new()
10175 assert_equal(8, abar.Foo())
10176 enddef
10177 Bar()
10178 END
10179 call v9.CheckSourceSuccess(lines)
10180
10181 " Call len() from a derived object
10182 let lines =<< trim END
10183 vim9script
10184 class A
10185 def len(): number
10186 return 10
10187 enddef
10188 endclass
10189 class B extends A
10190 def len(): number
10191 return 20
10192 enddef
10193 endclass
10194 def Foo(afoo: A)
10195 assert_equal(20, len(afoo))
10196 var bfoo = B.new()
10197 assert_equal(20, len(bfoo))
10198 enddef
10199 var b = B.new()
10200 assert_equal(20, len(b))
10201 Foo(b)
10202 END
10203 call v9.CheckSourceSuccess(lines)
10204
10205 " Invoking len method using an interface
10206 let lines =<< trim END
10207 vim9script
10208 interface A
10209 def len(): number
10210 endinterface
10211 class B implements A
10212 def len(): number
10213 return 123
10214 enddef
10215 endclass
10216 def Foo(a: A)
10217 assert_equal(123, len(a))
10218 enddef
10219 var b = B.new()
10220 Foo(b)
10221 END
10222 call v9.CheckSourceSuccess(lines)
10223endfunc
10224
10225" Test for using the string() builtin method with an object
10226" This is a legacy function to use the test_garbagecollect_now() function.
10227func Test_object_string()
10228 let lines =<< trim END
10229 vim9script
10230 class A
10231 var name: string
10232 def string(): string
10233 return this.name
10234 enddef
10235 endclass
10236
10237 def Foo()
10238 var afoo = A.new("foo-A")
10239 assert_equal('foo-A', string(afoo))
10240 assert_equal('foo-A', afoo->string())
10241 enddef
10242
10243 var a = A.new("script-A")
10244 assert_equal('script-A', string(a))
10245 assert_equal('script-A', a->string())
10246 assert_equal(['script-A'], execute('echo a')->split("\n"))
10247 test_garbagecollect_now()
10248 assert_equal('script-A', string(a))
10249 Foo()
10250 test_garbagecollect_now()
10251 Foo()
10252 END
10253 call v9.CheckSourceSuccess(lines)
10254
10255 " string() should return "object of A {}" without a builtin method
10256 let lines =<< trim END
10257 vim9script
10258 class A
10259 endclass
10260
10261 def Foo()
10262 var afoo = A.new()
10263 assert_equal('object of A {}', string(afoo))
10264 enddef
10265
10266 var a = A.new()
10267 assert_equal('object of A {}', string(a))
10268 Foo()
10269 END
10270 call v9.CheckSourceSuccess(lines)
10271
10272 " Unsupported signature for the string() method
10273 let lines =<< trim END
10274 vim9script
10275 class A
10276 def string()
10277 enddef
10278 endclass
10279 END
10280 call v9.CheckSourceFailure(lines, 'E1383: Method "string": type mismatch, expected func(): string but got func()', 4)
10281
10282 " Error when calling the string() method
10283 let lines =<< trim END
10284 vim9script
10285 class A
10286 def string(): string
10287 throw "Failed to get text"
10288 enddef
10289 endclass
10290
10291 def Foo()
10292 var afoo = A.new()
10293 var i = string(afoo)
10294 enddef
10295
10296 var a = A.new()
10297 assert_fails('string(a)', 'Failed to get text')
10298 assert_fails('Foo()', 'Failed to get text')
10299 END
10300 call v9.CheckSourceSuccess(lines)
10301
10302 " call string() using an object from a script
10303 let lines =<< trim END
10304 vim9script
10305 class A
10306 def string(): string
10307 return 'A'
10308 enddef
10309 endclass
10310 var afoo = A.new()
10311 assert_equal('A', afoo.string())
10312 END
10313 call v9.CheckSourceSuccess(lines)
10314
10315 " call string() using an object from a method
10316 let lines =<< trim END
10317 vim9script
10318 class A
10319 def string(): string
10320 return 'A'
10321 enddef
10322 endclass
10323 def Foo()
10324 var afoo = A.new()
10325 assert_equal('A', afoo.string())
10326 enddef
10327 Foo()
10328 END
10329 call v9.CheckSourceSuccess(lines)
10330
10331 " call string() using "this" from an object method
10332 let lines =<< trim END
10333 vim9script
10334 class A
10335 def string(): string
10336 return 'A'
10337 enddef
10338 def Foo(): string
10339 return this.string()
10340 enddef
10341 endclass
10342 def Bar()
10343 var abar = A.new()
10344 assert_equal('A', abar.string())
10345 enddef
10346 Bar()
10347 END
10348 call v9.CheckSourceSuccess(lines)
10349
10350 " Call string() from a derived object
10351 let lines =<< trim END
10352 vim9script
10353 class A
10354 def string(): string
10355 return 'A'
10356 enddef
10357 endclass
10358 class B extends A
10359 def string(): string
10360 return 'B'
10361 enddef
10362 endclass
10363 def Foo(afoo: A)
10364 assert_equal('B', string(afoo))
10365 var bfoo = B.new()
10366 assert_equal('B', string(bfoo))
10367 enddef
10368 var b = B.new()
10369 assert_equal('B', string(b))
10370 Foo(b)
10371 END
10372 call v9.CheckSourceSuccess(lines)
10373
10374 " Invoking string method using an interface
10375 let lines =<< trim END
10376 vim9script
10377 interface A
10378 def string(): string
10379 endinterface
10380 class B implements A
10381 def string(): string
10382 return 'B'
10383 enddef
10384 endclass
10385 def Foo(a: A)
10386 assert_equal('B', string(a))
10387 enddef
10388 var b = B.new()
10389 Foo(b)
10390 END
10391 call v9.CheckSourceSuccess(lines)
10392endfunc
10393
Yegappan Lakshmanan35b867b2024-03-09 15:44:19 +010010394" Test for using a class in the class definition
10395def Test_Ref_Class_Within_Same_Class()
10396 var lines =<< trim END
10397 vim9script
10398 class A
10399 var n: number = 0
10400 def Equals(other: A): bool
10401 return this.n == other.n
10402 enddef
10403 endclass
10404
10405 var a1 = A.new(10)
10406 var a2 = A.new(10)
10407 var a3 = A.new(20)
10408 assert_equal(true, a1.Equals(a2))
10409 assert_equal(false, a2.Equals(a3))
10410 END
10411 v9.CheckScriptSuccess(lines)
10412
10413 lines =<< trim END
10414 vim9script
10415
10416 class Foo
10417 var num: number
10418 def Clone(): Foo
10419 return Foo.new(this.num)
10420 enddef
10421 endclass
10422
10423 var f1 = Foo.new(1)
10424
10425 def F()
10426 var f2: Foo = f1.Clone()
10427 assert_equal(false, f2 is f1)
10428 assert_equal(true, f2.num == f1.num)
10429 enddef
10430 F()
10431
10432 var f3: Foo = f1.Clone()
10433 assert_equal(false, f3 is f1)
10434 assert_equal(true, f3.num == f1.num)
10435 END
10436 v9.CheckScriptSuccess(lines)
10437
10438 # Test for trying to use a class to extend when defining the same class
10439 lines =<< trim END
10440 vim9script
10441 class A extends A
10442 endclass
10443 END
10444 v9.CheckScriptFailure(lines, 'E1354: Cannot extend A', 3)
10445
10446 # Test for trying to use a class to implement when defining the same class
10447 lines =<< trim END
10448 vim9script
10449 class A implements A
10450 endclass
10451 END
10452 v9.CheckScriptFailure(lines, 'E1347: Not a valid interface: A', 3)
10453enddef
10454
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010455" Test for using a compound operator from a lambda function in an object method
10456def Test_compound_op_in_objmethod_lambda()
10457 # Test using the "+=" operator
10458 var lines =<< trim END
10459 vim9script
10460 class A
10461 var n: number = 10
10462 def Foo()
10463 var Fn = () => {
10464 this.n += 1
10465 }
10466 Fn()
10467 enddef
10468 endclass
10469
10470 var a = A.new()
10471 a.Foo()
10472 assert_equal(11, a.n)
10473 END
10474 v9.CheckScriptSuccess(lines)
10475
10476 # Test using the "..=" operator
10477 lines =<< trim END
10478 vim9script
10479 class A
10480 var s: string = "a"
10481 def Foo()
10482 var Fn = () => {
10483 this.s ..= "a"
10484 }
10485 Fn()
10486 enddef
10487 endclass
10488
10489 var a = A.new()
10490 a.Foo()
10491 a.Foo()
10492 assert_equal("aaa", a.s)
10493 END
10494 v9.CheckScriptSuccess(lines)
10495enddef
10496
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010497" Test for using test_refcount() with a class and an object
10498def Test_class_object_refcount()
10499 var lines =<< trim END
10500 vim9script
10501 class A
10502 endclass
10503 var a: A = A.new()
10504 assert_equal(2, test_refcount(A))
10505 assert_equal(1, test_refcount(a))
10506 var b = a
10507 assert_equal(2, test_refcount(A))
10508 assert_equal(2, test_refcount(a))
10509 assert_equal(2, test_refcount(b))
10510 END
10511 v9.CheckScriptSuccess(lines)
10512enddef
10513
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +010010514" call a lambda function in one object from another object
10515def Test_lambda_invocation_across_classes()
10516 var lines =<< trim END
10517 vim9script
10518 class A
10519 var s: string = "foo"
10520 def GetFn(): func
10521 var Fn = (): string => {
10522 return this.s
10523 }
10524 return Fn
10525 enddef
10526 endclass
10527
10528 class B
10529 var s: string = "bar"
10530 def GetFn(): func
10531 var a = A.new()
10532 return a.GetFn()
10533 enddef
10534 endclass
10535
10536 var b = B.new()
10537 var Fn = b.GetFn()
10538 assert_equal("foo", Fn())
10539 END
10540 v9.CheckScriptSuccess(lines)
10541enddef
10542
Yegappan Lakshmanan3164cf82024-03-28 10:36:42 +010010543" Test for using a class member which is an object of the current class
10544def Test_current_class_object_class_member()
10545 var lines =<< trim END
10546 vim9script
10547 class A
10548 public static var obj1: A = A.new(10)
10549 var n: number
10550 endclass
10551 defcompile
10552 assert_equal(10, A.obj1.n)
10553 END
10554 v9.CheckScriptSuccess(lines)
10555enddef
10556
Yegappan Lakshmanan2ed5a112024-04-01 14:50:41 +020010557" Test for updating a base class variable from a base class method without the
10558" class name. This used to crash Vim (Github issue #14352).
10559def Test_use_base_class_variable_from_base_class_method()
10560 var lines =<< trim END
10561 vim9script
10562
10563 class DictKeyClass
10564 static var _obj_id_count = 1
10565 def _GenerateKey()
10566 _obj_id_count += 1
10567 enddef
10568 static def GetIdCount(): number
10569 return _obj_id_count
10570 enddef
10571 endclass
10572
10573 class C extends DictKeyClass
10574 def F()
10575 this._GenerateKey()
10576 enddef
10577 endclass
10578
10579 C.new().F()
10580 assert_equal(2, DictKeyClass.GetIdCount())
10581 END
10582 v9.CheckScriptSuccess(lines)
10583enddef
10584
Yegappan Lakshmanan3e336502024-04-04 19:35:59 +020010585" Test for accessing protected funcref object and class variables
10586def Test_protected_funcref()
10587 # protected funcref object variable
10588 var lines =<< trim END
10589 vim9script
10590 class Test1
10591 const _Id: func(any): any = (v) => v
10592 endclass
10593 var n = Test1.new()._Id(1)
10594 END
10595 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test1"', 5)
10596
10597 # protected funcref class variable
10598 lines =<< trim END
10599 vim9script
10600 class Test2
10601 static const _Id: func(any): any = (v) => v
10602 endclass
10603 var n = Test2._Id(2)
10604 END
10605 v9.CheckScriptFailure(lines, 'E1333: Cannot access protected variable "_Id" in class "Test2"', 5)
10606enddef
10607
Yegappan Lakshmanan3fa8f772024-04-04 21:42:07 +020010608" Test for using lambda block in classes
10609def Test_lambda_block_in_class()
10610 # This used to crash Vim
10611 var lines =<< trim END
10612 vim9script
10613 class IdClass1
10614 const Id: func(number): number = (num: number): number => {
10615 # Return a ID
10616 return num * 10
10617 }
10618 endclass
10619 var id = IdClass1.new()
10620 assert_equal(20, id.Id(2))
10621 END
10622 v9.CheckScriptSuccess(lines)
10623
10624 # This used to crash Vim
10625 lines =<< trim END
10626 vim9script
10627 class IdClass2
10628 static const Id: func(number): number = (num: number): number => {
10629 # Return a ID
10630 return num * 2
10631 }
10632 endclass
10633 assert_equal(16, IdClass2.Id(8))
10634 END
10635 v9.CheckScriptSuccess(lines)
10636enddef
10637
Yegappan Lakshmanan1af0fbf2024-04-09 21:39:27 +020010638" Test for defcompiling an abstract method
10639def Test_abstract_method_defcompile()
10640 # Compile an abstract class with abstract object methods
10641 var lines =<< trim END
10642 vim9script
10643 abstract class A
10644 abstract def Foo(): string
10645 abstract def Bar(): list<string>
10646 endclass
10647 defcompile
10648 END
10649 v9.CheckScriptSuccess(lines)
10650
10651 # Compile a concrete object method in an abstract class
10652 lines =<< trim END
10653 vim9script
10654 abstract class A
10655 abstract def Foo(): string
10656 abstract def Bar(): list<string>
10657 def Baz(): string
10658 pass
10659 enddef
10660 endclass
10661 defcompile
10662 END
10663 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10664
10665 # Compile a concrete class method in an abstract class
10666 lines =<< trim END
10667 vim9script
10668 abstract class A
10669 abstract def Foo(): string
10670 abstract def Bar(): list<string>
10671 static def Baz(): string
10672 pass
10673 enddef
10674 endclass
10675 defcompile
10676 END
10677 v9.CheckScriptFailure(lines, 'E476: Invalid command: pass', 1)
10678enddef
10679
Yegappan Lakshmananc51578f2024-04-13 17:58:09 +020010680" Test for defining a class in a function
10681def Test_class_definition_in_a_function()
10682 var lines =<< trim END
10683 vim9script
10684 def Foo()
10685 class A
10686 endclass
10687 enddef
10688 defcompile
10689 END
10690 v9.CheckScriptFailure(lines, 'E1429: Class can only be used in a script', 1)
10691enddef
10692
Bram Moolenaar00b28d62022-12-08 15:32:33 +000010693" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker