blob: b3d9841247992423dedfb9ee145361158db9d90b [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 Lakshmanan00cd1822023-09-18 19:56:49 +020070 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000071 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020072 vim9script
73 class Something
74 this
75 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020077 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020079 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000080 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020081 vim9script
82 class Something
83 this.
84 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000085 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020086 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000087
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020088 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000089 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020090 vim9script
91 class Something
92 this .count
93 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000094 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020095 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000096
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020099 vim9script
100 class Something
101 this. count
102 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200104 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200108 vim9script
109 class Something
110 this.count: number
111 that.count
112 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000113 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200114 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000115
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200116 # Member variable without a type or initialization
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200118 vim9script
119 class Something
120 this.count
121 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000122 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200123 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200125 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000126 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200127 vim9script
128 class Something
129 def new()
130 this.state = 0
131 enddef
132 endclass
133 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000134 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200135 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000136
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200137 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200139 vim9script
140 class Something
141 this.count : number
142 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200144 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000145
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200146 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000147 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200148 vim9script
149 class Something
150 this.count:number
151 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200153 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000154
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200155 # Test for unsupported comment specifier
156 lines =<< trim END
157 vim9script
158 class Something
159 # comment
160 #{
161 endclass
162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200164
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200165 # Test for using class as a bool
166 lines =<< trim END
167 vim9script
168 class A
169 endclass
170 if A
171 endif
172 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200173 v9.CheckSourceFailure(lines, 'E1319: Using a Class as a Number', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200174
175 # Test for using object as a bool
176 lines =<< trim END
177 vim9script
178 class A
179 endclass
180 var a = A.new()
181 if a
182 endif
183 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200184 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200185
186 # Test for using class as a float
187 lines =<< trim END
188 vim9script
189 class A
190 endclass
191 sort([1.1, A], 'f')
192 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200193 v9.CheckSourceFailure(lines, 'E1321: Using a Class as a Float', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200194
195 # Test for using object as a float
196 lines =<< trim END
197 vim9script
198 class A
199 endclass
200 var a = A.new()
201 sort([1.1, a], 'f')
202 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200203 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200204
205 # Test for using class as a string
206 lines =<< trim END
207 vim9script
208 class A
209 endclass
210 :exe 'call ' .. A
211 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200212 v9.CheckSourceFailure(lines, 'E1323: Using a Class as a String', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200213
214 # Test for using object as a string
215 lines =<< trim END
216 vim9script
217 class A
218 endclass
219 var a = A.new()
220 :exe 'call ' .. a
221 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200222 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200223
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200224 # Test creating a class with member variables and methods, calling a object
225 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200227 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200229 class TextPosition
230 this.lnum: number
231 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000232
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200233 # make a nicely formatted string
234 def ToString(): string
235 return $'({this.lnum}, {this.col})'
236 enddef
237 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000238
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200239 # use the automatically generated new() method
240 var pos = TextPosition.new(2, 12)
241 assert_equal(2, pos.lnum)
242 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000243
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200244 # call an object method
245 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000246
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200247 assert_equal(v:t_class, type(TextPosition))
248 assert_equal(v:t_object, type(pos))
249 assert_equal('class<TextPosition>', typename(TextPosition))
250 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200253
254 # When referencing object methods, space cannot be used after a "."
255 lines =<< trim END
256 vim9script
257 class A
258 def Foo(): number
259 return 10
260 enddef
261 endclass
262 var a = A.new()
263 var v = a. Foo()
264 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200265 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200266
267 # Using an object without specifying a method or a member variable
268 lines =<< trim END
269 vim9script
270 class A
271 def Foo(): number
272 return 10
273 enddef
274 endclass
275 var a = A.new()
276 var v = a.
277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200278 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279
280 # Error when parsing the arguments of an object method.
281 lines =<< trim END
282 vim9script
283 class A
284 def Foo()
285 enddef
286 endclass
287 var a = A.new()
288 var v = a.Foo(,)
289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200290 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200291
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200292 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200293 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200294 vim9script
295 class A
296 this.y = {
297 X: 1
298 }
299 endclass
300 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200301 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200302 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000303enddef
304
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200305" Tests for object/class methods in a class
306def Test_class_def_method()
307 # Using the "public" keyword when defining an object method
308 var lines =<< trim END
309 vim9script
310 class A
311 public def Foo()
312 enddef
313 endclass
314 END
315 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
316
317 # Using the "public" keyword when defining a class method
318 lines =<< trim END
319 vim9script
320 class A
321 public static def Foo()
322 enddef
323 endclass
324 END
325 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
326
327 # Using the "public" keyword when defining an object private method
328 lines =<< trim END
329 vim9script
330 class A
331 public def _Foo()
332 enddef
333 endclass
334 END
335 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
336
337 # Using the "public" keyword when defining a class private method
338 lines =<< trim END
339 vim9script
340 class A
341 public static def _Foo()
342 enddef
343 endclass
344 END
345 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
346
347 # Using a "def" keyword without an object method name
348 lines =<< trim END
349 vim9script
350 class A
351 def
352 enddef
353 endclass
354 END
355 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
356
357 # Using a "def" keyword without a class method name
358 lines =<< trim END
359 vim9script
360 class A
361 static def
362 enddef
363 endclass
364 END
365 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
366enddef
367
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000368def Test_class_defined_twice()
369 # class defined twice should fail
370 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200371 vim9script
372 class There
373 endclass
374 class There
375 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200377 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000378
379 # one class, reload same script twice is OK
380 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200381 vim9script
382 class There
383 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000384 END
385 writefile(lines, 'XclassTwice.vim', 'D')
386 source XclassTwice.vim
387 source XclassTwice.vim
388enddef
389
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000390def Test_returning_null_object()
391 # this was causing an internal error
392 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200393 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200395 class BufferList
396 def Current(): any
397 return null_object
398 enddef
399 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000400
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 var buffers = BufferList.new()
402 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000403 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200404 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000405enddef
406
Bram Moolenaard13dd302023-03-11 20:56:35 +0000407def Test_using_null_class()
408 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200409 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000410 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200411 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000412enddef
413
Bram Moolenaar657aea72023-01-27 13:16:19 +0000414def Test_class_interface_wrong_end()
415 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200416 vim9script
417 abstract class SomeName
418 this.member = 'text'
419 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000420 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200421 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000422
423 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200424 vim9script
425 export interface AnotherName
426 this.member: string
427 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200429 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000430enddef
431
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000432def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200433 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000434 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200435 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200437 class State
438 this.value = 'xyz'
439 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200441 var state: State
442 var db = {'xyz': 789}
443 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000444 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200445 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000446
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200447 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200449 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200451 class Class
452 this.id: string
453 def Method1()
454 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000455 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200456 endclass
457
458 var obj: Class
459 def Func()
460 obj.Method1()
461 enddef
462 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200464 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000465
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200466 # Pass an uninitialized object variable to a "new" function and try to call an
467 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000468 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200469 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000470
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200471 class Background
472 this.background = 'dark'
473 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000474
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200475 class Colorscheme
476 this._bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000477
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200478 def GetBackground(): string
479 return this._bg.background
480 enddef
481 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 var bg: Background # UNINITIALIZED
484 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200486 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000487
488 # TODO: this should not give an error but be handled at runtime
489 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200490 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000491
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200492 class Class
493 this.id: string
494 def Method1()
495 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000496 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200497 endclass
498
499 var obj = null_object
500 def Func()
501 obj.Method1()
502 enddef
503 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200505 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000506enddef
507
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200508" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200509def Test_null_object_assign_compare()
510 var lines =<< trim END
511 vim9script
512
513 var nullo = null_object
514 def F(): any
515 return nullo
516 enddef
517 assert_equal('object<Unknown>', typename(F()))
518
519 var o0 = F()
520 assert_true(o0 == null_object)
521 assert_true(o0 == null)
522
523 var o1: any = nullo
524 assert_true(o1 == null_object)
525 assert_true(o1 == null)
526
527 def G()
528 var x = null_object
529 enddef
530
531 class C
532 endclass
533 var o2: C
534 assert_true(o2 == null_object)
535 assert_true(o2 == null)
536
537 o2 = null_object
538 assert_true(o2 == null)
539
540 o2 = C.new()
541 assert_true(o2 != null)
542
543 o2 = null_object
544 assert_true(o2 == null)
545 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200546 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200547enddef
548
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200549" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000550def Test_class_member_initializer()
551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200554 class TextPosition
555 this.lnum: number = 1
556 this.col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000557
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200558 # constructor with only the line number
559 def new(lnum: number)
560 this.lnum = lnum
561 enddef
562 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000563
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200564 var pos = TextPosition.new(3)
565 assert_equal(3, pos.lnum)
566 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200568 var instr = execute('disassemble TextPosition.new')
569 assert_match('new\_s*' ..
570 '0 NEW TextPosition size \d\+\_s*' ..
571 '\d PUSHNR 1\_s*' ..
572 '\d STORE_THIS 0\_s*' ..
573 '\d PUSHNR 1\_s*' ..
574 '\d STORE_THIS 1\_s*' ..
575 'this.lnum = lnum\_s*' ..
576 '\d LOAD arg\[-1]\_s*' ..
577 '\d PUSHNR 0\_s*' ..
578 '\d LOAD $0\_s*' ..
579 '\d\+ STOREINDEX object\_s*' ..
580 '\d\+ RETURN object.*',
581 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000582 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200583 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000584enddef
585
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000586def Test_member_any_used_as_object()
587 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200588 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000589
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200590 class Inner
591 this.value: number = 0
592 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000593
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200594 class Outer
595 this.inner: any
596 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200598 def F(outer: Outer)
599 outer.inner.value = 1
600 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000601
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200602 var inner_obj = Inner.new(0)
603 var outer_obj = Outer.new(inner_obj)
604 F(outer_obj)
605 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000606 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200607 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000608
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200609 # Try modifying a private variable using an "any" object
610 lines =<< trim END
611 vim9script
612
613 class Inner
614 this._value: string = ''
615 endclass
616
617 class Outer
618 this.inner: any
619 endclass
620
621 def F(outer: Outer)
622 outer.inner._value = 'b'
623 enddef
624
625 var inner_obj = Inner.new('a')
626 var outer_obj = Outer.new(inner_obj)
627 F(outer_obj)
628 END
Ernie Rael64885642023-10-04 20:16:22 +0200629 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200630
631 # Try modifying a non-existing variable using an "any" object
632 lines =<< trim END
633 vim9script
634
635 class Inner
636 this.value: string = ''
637 endclass
638
639 class Outer
640 this.inner: any
641 endclass
642
643 def F(outer: Outer)
644 outer.inner.someval = 'b'
645 enddef
646
647 var inner_obj = Inner.new('a')
648 var outer_obj = Outer.new(inner_obj)
649 F(outer_obj)
650 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200651 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000652enddef
653
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200654" Nested assignment to a object variable which is of another class type
655def Test_assignment_nested_type()
656 var lines =<< trim END
657 vim9script
658
659 class Inner
660 public this.value: number = 0
661 endclass
662
663 class Outer
664 this.inner: Inner
665 endclass
666
667 def F(outer: Outer)
668 outer.inner.value = 1
669 enddef
670
671 def Test_assign_to_nested_typed_member()
672 var inner = Inner.new(0)
673 var outer = Outer.new(inner)
674 F(outer)
675 assert_equal(1, inner.value)
676 enddef
677
678 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200679
680 var script_inner = Inner.new(0)
681 var script_outer = Outer.new(script_inner)
682 script_outer.inner.value = 1
683 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200684 END
685 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200686
687 # Assignment where target item is read only in :def
688 lines =<< trim END
689 vim9script
690
691 class Inner
692 this.value: number = 0
693 endclass
694
695 class Outer
696 this.inner: Inner
697 endclass
698
699 def F(outer: Outer)
700 outer.inner.value = 1
701 enddef
702
703 def Test_assign_to_nested_typed_member()
704 var inner = Inner.new(0)
705 var outer = Outer.new(inner)
706 F(outer)
707 assert_equal(1, inner.value)
708 enddef
709
710 Test_assign_to_nested_typed_member()
711 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200713
714 # Assignment where target item is read only script level
715 lines =<< trim END
716 vim9script
717
718 class Inner
719 this.value: number = 0
720 endclass
721
722 class Outer
723 this.inner: Inner
724 endclass
725
726 def F(outer: Outer)
727 outer.inner.value = 1
728 enddef
729
730 var script_inner = Inner.new(0)
731 var script_outer = Outer.new(script_inner)
732 script_outer.inner.value = 1
733 assert_equal(1, script_inner.value)
734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200735 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200736enddef
737
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000738def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200739 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000740 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200741 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000742
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200743 class Foo
744 public this.x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 def Add(n: number)
747 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100748 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200749 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200751 var f = Foo.new(3)
752 f.Add(17)
753 assert_equal(20, f.x)
754
755 def AddToFoo(obj: Foo)
756 obj.x += 3
757 enddef
758
759 AddToFoo(f)
760 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000761 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200762 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000763enddef
764
Bram Moolenaarf4508042023-01-15 16:54:57 +0000765def Test_list_of_objects()
766 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200767 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200769 class Foo
770 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000771 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200772 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000773
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200774 def ProcessList(fooList: list<Foo>)
775 for foo in fooList
776 foo.Add()
777 endfor
778 enddef
779
780 var l: list<Foo> = [Foo.new()]
781 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000782 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200783 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000784enddef
785
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000786def Test_expr_after_using_object()
787 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Something
791 this.label: string = ''
792 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def Foo(): Something
795 var v = Something.new()
796 echo 'in Foo(): ' .. typename(v)
797 return v
798 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000799
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000801 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200802 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000803enddef
804
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000805def Test_class_default_new()
806 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200807 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000808
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200809 class TextPosition
810 this.lnum: number = 1
811 this.col: number = 1
812 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000813
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200814 var pos = TextPosition.new()
815 assert_equal(1, pos.lnum)
816 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200818 pos = TextPosition.new(v:none, v:none)
819 assert_equal(1, pos.lnum)
820 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000821
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200822 pos = TextPosition.new(3, 22)
823 assert_equal(3, pos.lnum)
824 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200826 pos = TextPosition.new(v:none, 33)
827 assert_equal(1, pos.lnum)
828 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000829 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200830 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000831
832 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200833 vim9script
834 class Person
835 this.name: string
836 this.age: number = 42
837 this.education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 def new(this.name, this.age = v:none, this.education = v:none)
840 enddef
841 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000842
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200843 var piet = Person.new("Piet")
844 assert_equal("Piet", piet.name)
845 assert_equal(42, piet.age)
846 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000847
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200848 var chris = Person.new("Chris", 4, "none")
849 assert_equal("Chris", chris.name)
850 assert_equal(4, chris.age)
851 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000852 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200853 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000854
855 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200856 vim9script
857 class Person
858 this.name: string
859 this.age: number = 42
860 this.education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def new(this.name, this.age = v:none, this.education = v:none)
863 enddef
864 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200866 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200868 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200869
870 # Using a specific value to initialize an instance variable in the new()
871 # method.
872 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200873 vim9script
874 class A
875 this.val: string
876 def new(this.val = 'a')
877 enddef
878 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200879 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000881enddef
882
h-east2261c892023-08-16 21:49:54 +0900883def Test_class_new_with_object_member()
884 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200885 vim9script
h-east2261c892023-08-16 21:49:54 +0900886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200887 class C
888 this.str: string
889 this.num: number
890 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900891 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200892 def newVals(this.str, this.num)
893 enddef
894 endclass
h-east2261c892023-08-16 21:49:54 +0900895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200896 def Check()
897 try
898 var c = C.new('cats', 2)
899 assert_equal('cats', c.str)
900 assert_equal(2, c.num)
901
902 c = C.newVals('dogs', 4)
903 assert_equal('dogs', c.str)
904 assert_equal(4, c.num)
905 catch
906 assert_report($'Unexpected exception was caught: {v:exception}')
907 endtry
908 enddef
909
910 Check()
h-east2261c892023-08-16 21:49:54 +0900911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200912 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900913
914 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +0200915 vim9script
916
917 class C
918 this.str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200919 this.num: number
920 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +0200921 enddef
922 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200923
924 def Check()
925 try
926 var c = C.new(1, 2)
927 catch
928 assert_report($'Unexpected exception was caught: {v:exception}')
929 endtry
930 enddef
931
932 Check()
h-eastdb385522023-09-28 22:18:19 +0200933 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +0200935
936 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
h-eastb895b0f2023-09-24 15:46:31 +0200938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class C
940 this.str: string
941 this.num: number
942 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +0200943 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 endclass
h-eastb895b0f2023-09-24 15:46:31 +0200945
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 def Check()
947 try
948 var c = C.newVals('dogs', 'apes')
949 catch
950 assert_report($'Unexpected exception was caught: {v:exception}')
951 endtry
952 enddef
953
954 Check()
955 END
956 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
957
958 lines =<< trim END
959 vim9script
960
961 class C
962 this.str: string
963 def new(str: any)
964 enddef
965 endclass
966
967 def Check()
968 try
969 var c = C.new(1)
970 catch
971 assert_report($'Unexpected exception was caught: {v:exception}')
972 endtry
973 enddef
974
975 Check()
h-eastb895b0f2023-09-24 15:46:31 +0200976 END
977 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +0200978
979 # Try using "this." argument in a class method
980 lines =<< trim END
981 vim9script
982 class A
983 this.val = 10
984 static def Foo(this.val: number)
985 enddef
986 endclass
987 END
988 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
989
990 # Try using "this." argument in an object method
991 lines =<< trim END
992 vim9script
993 class A
994 this.val = 10
995 def Foo(this.val: number)
996 enddef
997 endclass
998 END
999 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001000enddef
1001
Bram Moolenaar74e12742022-12-13 21:14:28 +00001002def Test_class_object_member_inits()
1003 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001004 vim9script
1005 class TextPosition
1006 this.lnum: number
1007 this.col = 1
1008 this.addcol: number = 2
1009 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001010
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011 var pos = TextPosition.new()
1012 assert_equal(0, pos.lnum)
1013 assert_equal(1, pos.col)
1014 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001015 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001016 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001017
1018 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001019 vim9script
1020 class TextPosition
1021 this.lnum
1022 this.col = 1
1023 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001024 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001025 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001026
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001027 # If the type is not specified for a member, then it should be set during
1028 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001029 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001030 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001031
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001032 var init_count = 0
1033 def Init(): string
1034 init_count += 1
1035 return 'foo'
1036 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001037
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001038 class A
1039 this.str1 = Init()
1040 this.str2: string = Init()
1041 this.col = 1
1042 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 assert_equal(init_count, 0)
1045 var a = A.new()
1046 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001047 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001049
1050 # Test for initializing an object member with an unknown variable/type
1051 lines =<< trim END
1052 vim9script
1053 class A
1054 this.value = init_val
1055 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001056 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001059
1060 # Test for initializing an object member with an special type
1061 lines =<< trim END
1062 vim9script
1063 class A
1064 this.value: void
1065 endclass
1066 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001067 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001068enddef
1069
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001070" Test for instance variable access
1071def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001072 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 vim9script
1074 class Triple
1075 this._one = 1
1076 this.two = 2
1077 public this.three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001078
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001079 def GetOne(): number
1080 return this._one
1081 enddef
1082 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001084 var trip = Triple.new()
1085 assert_equal(1, trip.GetOne())
1086 assert_equal(2, trip.two)
1087 assert_equal(3, trip.three)
Ernie Rael64885642023-10-04 20:16:22 +02001088 assert_fails('echo trip._one', 'E1333: Cannot access private variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001089
Ernie Rael64885642023-10-04 20:16:22 +02001090 assert_fails('trip._one = 11', 'E1333: Cannot access private variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001091 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1092 trip.three = 33
1093 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001094
Ernie Raeld4802ec2023-10-20 11:59:00 +02001095 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001096 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001097 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001098
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001099 # Test for a public member variable name beginning with an underscore
1100 lines =<< trim END
1101 vim9script
1102 class A
1103 public this._val = 10
1104 endclass
1105 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001106 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001107
Bram Moolenaar590162c2022-12-24 21:24:06 +00001108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001109 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001111 class MyCar
1112 this.make: string
1113 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001114
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001115 def new(make_arg: string)
1116 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001117 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001118
1119 def GetMake(): string
1120 return $"make = {this.make}"
1121 enddef
1122 def GetAge(): number
1123 return this.age
1124 enddef
1125 endclass
1126
1127 var c = MyCar.new("abc")
1128 assert_equal('make = abc', c.GetMake())
1129
1130 c = MyCar.new("def")
1131 assert_equal('make = def', c.GetMake())
1132
1133 var c2 = MyCar.new("123")
1134 assert_equal('make = 123', c2.GetMake())
1135
1136 def CheckCar()
1137 assert_equal("make = def", c.GetMake())
1138 assert_equal(5, c.GetAge())
1139 enddef
1140 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001141 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001142 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001143
1144 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001145 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001146
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001147 class MyCar
1148 this.make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001150 def new(make_arg: string)
1151 this.make = make_arg
1152 enddef
1153 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001155 var c = MyCar.new("abc")
1156 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001157 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001158 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001159
1160 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001161 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001162
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001163 class Foo
1164 this.x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001165
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001166 def Add(n: number): any
1167 this.x->add(n)
1168 return this
1169 enddef
1170 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001171
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001172 echo Foo.new().Add(1).Add(2).x
1173 echo Foo.new().Add(1).Add(2)
1174 .x
1175 echo Foo.new().Add(1)
1176 .Add(2).x
1177 echo Foo.new()
1178 .Add(1).Add(2).x
1179 echo Foo.new()
1180 .Add(1)
1181 .Add(2)
1182 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001183 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001184 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001185
1186 # Test for "public" cannot be abbreviated
1187 lines =<< trim END
1188 vim9script
1189 class Something
1190 pub this.val = 1
1191 endclass
1192 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001193 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001194
1195 # Test for "public" keyword must be followed by "this" or "static".
1196 lines =<< trim END
1197 vim9script
1198 class Something
1199 public val = 1
1200 endclass
1201 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001202 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001203
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001204 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001205 lines =<< trim END
1206 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001207 class A
1208 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001209 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001210 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001212 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001213
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001215 lines =<< trim END
1216 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001217 class A
1218 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001219 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001220 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001222 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001223
1224 # Modify a instance variable using the class name in a def function
1225 lines =<< trim END
1226 vim9script
1227 class A
1228 public this.val = 1
1229 endclass
1230 def T()
1231 A.val = 1
1232 enddef
1233 T()
1234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001236
1237 # Read a instance variable using the class name in a def function
1238 lines =<< trim END
1239 vim9script
1240 class A
1241 public this.val = 1
1242 endclass
1243 def T()
1244 var i = A.val
1245 enddef
1246 T()
1247 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001248 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001249
1250 # Access from child class extending a class:
1251 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001252 vim9script
1253 class A
1254 this.ro_obj_var = 10
1255 public this.rw_obj_var = 20
1256 this._priv_obj_var = 30
1257 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001258
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001259 class B extends A
1260 def Foo()
1261 var x: number
1262 x = this.ro_obj_var
1263 this.ro_obj_var = 0
1264 x = this.rw_obj_var
1265 this.rw_obj_var = 0
1266 x = this._priv_obj_var
1267 this._priv_obj_var = 0
1268 enddef
1269 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001271 var b = B.new()
1272 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001273 END
1274 v9.CheckSourceSuccess(lines)
1275enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001276
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001277" Test for class variable access
1278def Test_class_variable_access()
1279 # Test for "static" cannot be abbreviated
1280 var lines =<< trim END
1281 vim9script
1282 class Something
1283 stat this.val = 1
1284 endclass
1285 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001287
1288 # Test for "static" cannot be followed by "this".
1289 lines =<< trim END
1290 vim9script
1291 class Something
1292 static this.val = 1
1293 endclass
1294 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001295 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296
1297 # Test for "static" cannot be followed by "public".
1298 lines =<< trim END
1299 vim9script
1300 class Something
1301 static public val = 1
1302 endclass
1303 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001304 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001305
1306 # A readonly class variable cannot be modified from a child class
1307 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001308 vim9script
1309 class A
1310 static ro_class_var = 40
1311 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001312
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001313 class B extends A
1314 def Foo()
1315 A.ro_class_var = 50
1316 enddef
1317 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001318
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001319 var b = B.new()
1320 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001321 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001322 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001323
1324 # A private class variable cannot be accessed from a child class
1325 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001326 vim9script
1327 class A
1328 static _priv_class_var = 60
1329 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001330
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001331 class B extends A
1332 def Foo()
1333 var i = A._priv_class_var
1334 enddef
1335 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001336
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001337 var b = B.new()
1338 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001339 END
Ernie Rael64885642023-10-04 20:16:22 +02001340 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001341
1342 # A private class variable cannot be modified from a child class
1343 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001344 vim9script
1345 class A
1346 static _priv_class_var = 60
1347 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001348
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001349 class B extends A
1350 def Foo()
1351 A._priv_class_var = 0
1352 enddef
1353 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001354
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001355 var b = B.new()
1356 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001357 END
Ernie Rael64885642023-10-04 20:16:22 +02001358 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001359
1360 # Access from child class extending a class and from script context
1361 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001362 vim9script
1363 class A
1364 static ro_class_var = 10
1365 public static rw_class_var = 20
1366 static _priv_class_var = 30
1367 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001369 class B extends A
1370 def Foo()
1371 var x: number
1372 x = A.ro_class_var
1373 assert_equal(10, x)
1374 x = A.rw_class_var
1375 assert_equal(25, x)
1376 A.rw_class_var = 20
1377 assert_equal(20, A.rw_class_var)
1378 enddef
1379 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001380
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001381 assert_equal(10, A.ro_class_var)
1382 assert_equal(20, A.rw_class_var)
1383 A.rw_class_var = 25
1384 assert_equal(25, A.rw_class_var)
1385 var b = B.new()
1386 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001387 END
1388 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001389enddef
1390
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001391def Test_class_object_compare()
1392 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001393 vim9script
1394 class Item
1395 this.nr = 0
1396 this.name = 'xx'
1397 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001398 END
1399
1400 # used at the script level and in a compiled function
1401 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001402 var i1 = Item.new()
1403 assert_equal(i1, i1)
1404 assert_true(i1 is i1)
1405 var i2 = Item.new()
1406 assert_equal(i1, i2)
1407 assert_false(i1 is i2)
1408 var i3 = Item.new(0, 'xx')
1409 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001410
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001411 var io1 = Item.new(1, 'xx')
1412 assert_notequal(i1, io1)
1413 var io2 = Item.new(0, 'yy')
1414 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001415 END
1416
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001417 v9.CheckSourceSuccess(class_lines + test_lines)
1418 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001419 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001420
1421 for op in ['>', '>=', '<', '<=', '=~', '!~']
1422 var op_lines = [
1423 'var i1 = Item.new()',
1424 'var i2 = Item.new()',
1425 'echo i1 ' .. op .. ' i2',
1426 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001427 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001428 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001429 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001430 endfor
1431enddef
1432
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001433def Test_object_type()
1434 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001437 class One
1438 this.one = 1
1439 endclass
1440 class Two
1441 this.two = 2
1442 endclass
1443 class TwoMore extends Two
1444 this.more = 9
1445 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001446
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001447 var o: One = One.new()
1448 var t: Two = Two.new()
1449 var m: TwoMore = TwoMore.new()
1450 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001451
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001452 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001453 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001454 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001455
1456 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001457 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001458
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 class One
1460 this.one = 1
1461 endclass
1462 class Two
1463 this.two = 2
1464 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001466 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001467 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001468 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001469
1470 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001471 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001472
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001473 interface One
1474 def GetMember(): number
1475 endinterface
1476 class Two implements One
1477 this.one = 1
1478 def GetMember(): number
1479 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001480 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001481 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001483 var o: One = Two.new(5)
1484 assert_equal(5, o.GetMember())
1485 END
1486 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001487
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001488 lines =<< trim END
1489 vim9script
1490
1491 class Num
1492 this.n: number = 0
1493 endclass
1494
1495 def Ref(name: string): func(Num): Num
1496 return (arg: Num): Num => {
1497 return eval(name)(arg)
1498 }
1499 enddef
1500
1501 const Fn = Ref('Double')
1502 var Double = (m: Num): Num => Num.new(m.n * 2)
1503
1504 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001505 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001506 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001507enddef
1508
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001509def Test_class_member()
1510 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001511 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001512 vim9script
1513 class TextPos
1514 this.lnum = 1
1515 this.col = 1
1516 static counter = 0
1517 static _secret = 7
1518 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001519
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 static def AddToCounter(nr: number)
1521 counter += nr
1522 enddef
1523 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001525 assert_equal(0, TextPos.counter)
1526 TextPos.AddToCounter(3)
1527 assert_equal(3, TextPos.counter)
1528 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001529
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 def GetCounter(): number
1531 return TextPos.counter
1532 enddef
1533 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1536 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1537 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001538
Ernie Rael64885642023-10-04 20:16:22 +02001539 assert_fails('echo TextPos._secret', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
1540 assert_fails('TextPos._secret = 8', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 assert_equal(42, TextPos.anybody)
1543 TextPos.anybody = 12
1544 assert_equal(12, TextPos.anybody)
1545 TextPos.anybody += 5
1546 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001547 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001548 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001549
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001550 # example in the help
1551 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001552 vim9script
1553 class OtherThing
1554 this.size: number
1555 static totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001556
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001557 def new(this.size)
1558 totalSize += this.size
1559 enddef
1560 endclass
1561 assert_equal(0, OtherThing.totalSize)
1562 var to3 = OtherThing.new(3)
1563 assert_equal(3, OtherThing.totalSize)
1564 var to7 = OtherThing.new(7)
1565 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001566 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001567 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001568
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001569 # using static class member twice
1570 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001572
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001573 class HTML
1574 static author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001575
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 static def MacroSubstitute(s: string): string
1577 return substitute(s, '{{author}}', author, 'gi')
1578 enddef
1579 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001580
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001581 assert_equal('some text', HTML.MacroSubstitute('some text'))
1582 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001583 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001584 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001585
Bram Moolenaar62a69232023-01-24 15:07:04 +00001586 # access private member in lambda
1587 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001589
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001590 class Foo
1591 this._x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 def Add(n: number): number
1594 const F = (): number => this._x + n
1595 return F()
1596 enddef
1597 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001599 var foo = Foo.new()
1600 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001601 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001602 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001603
h-east2bd6a092023-05-19 19:01:17 +01001604 # access private member in lambda body
1605 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001607
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 class Foo
1609 this._x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001610
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001611 def Add(n: number): number
1612 var Lam = () => {
1613 this._x = this._x + n
1614 }
1615 Lam()
1616 return this._x
1617 enddef
1618 endclass
h-east2bd6a092023-05-19 19:01:17 +01001619
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 var foo = Foo.new()
1621 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001622 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001623 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001624
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001625 # check shadowing
1626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001627 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001629 class Some
1630 static count = 0
1631 def Method(count: number)
1632 echo count
1633 enddef
1634 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001636 var s = Some.new()
1637 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001638 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001640
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001641 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001642 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001643 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001644
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001645 class Some
1646 static count = 0
1647 def Method(arg: number)
1648 var count = 3
1649 echo arg count
1650 enddef
1651 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var s = Some.new()
1654 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001655 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001656 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001657
1658 # Test for using an invalid type for a member variable
1659 lines =<< trim END
1660 vim9script
1661 class A
1662 this.val: xxx
1663 endclass
1664 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001665 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001666
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001667 # Test for setting a member on a null object
1668 lines =<< trim END
1669 vim9script
1670 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001671 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001672 endclass
1673
1674 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001675 var obj: A
1676 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001677 enddef
1678 F()
1679 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001680 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001681
1682 # Test for accessing a member on a null object
1683 lines =<< trim END
1684 vim9script
1685 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001687 endclass
1688
1689 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001690 var obj: A
1691 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001692 enddef
1693 F()
1694 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001695 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001696
1697 # Test for setting a member on a null object, at script level
1698 lines =<< trim END
1699 vim9script
1700 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001701 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001702 endclass
1703
1704 var obj: A
1705 obj.val = ""
1706 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001707 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001708
1709 # Test for accessing a member on a null object, at script level
1710 lines =<< trim END
1711 vim9script
1712 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001713 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001714 endclass
1715
1716 var obj: A
1717 echo obj.val
1718 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001719 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001720
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001721 # Test for no space before or after the '=' when initializing a member
1722 # variable
1723 lines =<< trim END
1724 vim9script
1725 class A
1726 this.val: number= 10
1727 endclass
1728 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001729 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001730 lines =<< trim END
1731 vim9script
1732 class A
1733 this.val: number =10
1734 endclass
1735 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001736 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001737
1738 # Access a non-existing member
1739 lines =<< trim END
1740 vim9script
1741 class A
1742 endclass
1743 var a = A.new()
1744 var v = a.bar
1745 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001746 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001747enddef
1748
Ernie Raele6c9aa52023-10-06 19:55:52 +02001749" These messages should show the defining class of the variable (base class),
1750" not the class that did the reference (super class)
1751def Test_defining_class_message()
1752 var lines =<< trim END
1753 vim9script
1754
1755 class Base
1756 this._v1: list<list<number>>
1757 endclass
1758
1759 class Child extends Base
1760 endclass
1761
1762 var o = Child.new()
1763 var x = o._v1
1764 END
1765 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 11)
1766 lines =<< trim END
1767 vim9script
1768
1769 class Base
1770 this._v1: list<list<number>>
1771 endclass
1772
1773 class Child extends Base
1774 endclass
1775
1776 def F()
1777 var o = Child.new()
1778 var x = o._v1
1779 enddef
1780 F()
1781 END
1782 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 2)
1783 lines =<< trim END
1784 vim9script
1785
1786 class Base
1787 this.v1: list<list<number>>
1788 endclass
1789
1790 class Child extends Base
1791 endclass
1792
1793 var o = Child.new()
1794 o.v1 = []
1795 END
1796 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1797 lines =<< trim END
1798 vim9script
1799
1800 class Base
1801 this.v1: list<list<number>>
1802 endclass
1803
1804 class Child extends Base
1805 endclass
1806
1807 def F()
1808 var o = Child.new()
1809 o.v1 = []
1810 enddef
1811 F()
1812 END
1813
1814 # Attempt to read a private variable that is in the middle
1815 # of the class hierarchy.
1816 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1817 lines =<< trim END
1818 vim9script
1819
1820 class Base0
1821 endclass
1822
1823 class Base extends Base0
1824 this._v1: list<list<number>>
1825 endclass
1826
1827 class Child extends Base
1828 endclass
1829
1830 def F()
1831 var o = Child.new()
1832 var x = o._v1
1833 enddef
1834 F()
1835 END
1836 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 2)
1837
1838 # Attempt to read a private variable that is at the start
1839 # of the class hierarchy.
1840 lines =<< trim END
1841 vim9script
1842
1843 class Base0
1844 endclass
1845
1846 class Base extends Base0
1847 endclass
1848
1849 class Child extends Base
1850 this._v1: list<list<number>>
1851 endclass
1852
1853 def F()
1854 var o = Child.new()
1855 var x = o._v1
1856 enddef
1857 F()
1858 END
1859 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Child"', 2)
1860enddef
1861
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001862func Test_class_garbagecollect()
1863 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001864 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001866 class Point
1867 this.p = [2, 3]
1868 static pl = ['a', 'b']
1869 static pd = {a: 'a', b: 'b'}
1870 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001871
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001872 echo Point.pl Point.pd
1873 call test_garbagecollect_now()
1874 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001875 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001876 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001877
1878 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001879 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001880
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001881 interface View
1882 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001883
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001884 class Widget
1885 this.view: View
1886 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001888 class MyView implements View
1889 this.widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001890
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001891 def new()
1892 # this will result in a circular reference to this object
1893 this.widget = Widget.new(this)
1894 enddef
1895 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001896
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001897 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001898
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001899 # overwrite "view", will be garbage-collected next
1900 view = MyView.new()
1901 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001902 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001903 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001904endfunc
1905
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001906" Test interface garbage collection
1907func Test_interface_garbagecollect()
1908 let lines =<< trim END
1909 vim9script
1910
1911 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001912 this.ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001913
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001914 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001915 endinterface
1916
1917 class A implements I
1918 static ro_class_var: number = 10
1919 public static rw_class_var: number = 20
1920 static _priv_class_var: number = 30
1921 this.ro_obj_var: number = 40
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001922 this._priv_obj_var: number = 60
1923
1924 static def _ClassBar(): number
1925 return _priv_class_var
1926 enddef
1927
1928 static def ClassFoo(): number
1929 return ro_class_var + rw_class_var + A._ClassBar()
1930 enddef
1931
1932 def _ObjBar(): number
1933 return this._priv_obj_var
1934 enddef
1935
1936 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001937 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001938 enddef
1939 endclass
1940
1941 assert_equal(60, A.ClassFoo())
1942 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001943 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001944 test_garbagecollect_now()
1945 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001946 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001947 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001948 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001949endfunc
1950
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001951def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001952 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001953 vim9script
1954 class Value
1955 this.value = 0
1956 static objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001957
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001958 def new(v: number)
1959 this.value = v
1960 ++objects
1961 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001962
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001963 static def GetCount(): number
1964 return objects
1965 enddef
1966 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001967
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001968 assert_equal(0, Value.GetCount())
1969 var v1 = Value.new(2)
1970 assert_equal(1, Value.GetCount())
1971 var v2 = Value.new(7)
1972 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001973 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001974 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001975
1976 # Test for cleaning up after a class definition failure when using class
1977 # functions.
1978 lines =<< trim END
1979 vim9script
1980 class A
1981 static def Foo()
1982 enddef
1983 aaa
1984 endclass
1985 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001986 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001987
1988 # Test for calling a class method from another class method without the class
1989 # name prefix.
1990 lines =<< trim END
1991 vim9script
1992 class A
1993 static myList: list<number> = [1]
1994 static def Foo(n: number)
1995 myList->add(n)
1996 enddef
1997 static def Bar()
1998 Foo(2)
1999 enddef
2000 def Baz()
2001 Foo(3)
2002 enddef
2003 endclass
2004 A.Bar()
2005 var a = A.new()
2006 a.Baz()
2007 assert_equal([1, 2, 3], A.myList)
2008 END
2009 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002010enddef
2011
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002012def Test_class_defcompile()
2013 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002014 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002015
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 class C
2017 def Fo(i: number): string
2018 return i
2019 enddef
2020 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002022 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002023 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002024 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002025
2026 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002027 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002028
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002029 class C
2030 static def Fc(): number
2031 return 'x'
2032 enddef
2033 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002034
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002035 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002036 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002038
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002040 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002041
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002042 class C
2043 static def new()
2044 enddef
2045 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002046
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002047 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002048 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002049 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002050
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002051 # Trying to compile a function using a non-existing class variable
2052 lines =<< trim END
2053 vim9script
2054 defcompile x.Foo()
2055 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002056 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002057
2058 # Trying to compile a function using a variable which is not a class
2059 lines =<< trim END
2060 vim9script
2061 var x: number
2062 defcompile x.Foo()
2063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002064 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002065
2066 # Trying to compile a function without specifying the name
2067 lines =<< trim END
2068 vim9script
2069 class A
2070 endclass
2071 defcompile A.
2072 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002074
2075 # Trying to compile a non-existing class object member function
2076 lines =<< trim END
2077 vim9script
2078 class A
2079 endclass
2080 var a = A.new()
2081 defcompile a.Foo()
2082 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002083 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002084enddef
2085
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002086def Test_class_object_to_string()
2087 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002088 vim9script
2089 class TextPosition
2090 this.lnum = 1
2091 this.col = 22
2092 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002093
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002094 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002095
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002096 var pos = TextPosition.new()
2097 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002098 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002099 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002100enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002101
Bram Moolenaar554d0312023-01-05 19:59:18 +00002102def Test_interface_basics()
2103 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002104 vim9script
2105 interface Something
2106 this.ro_var: list<number>
2107 def GetCount(): number
2108 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002109 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002110 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002111
2112 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002113 interface SomethingWrong
2114 static count = 7
2115 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002117 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002118
2119 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002120 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002121
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002122 interface Some
2123 this.value: number
2124 def Method(value: number)
2125 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002126 END
h-east61378a12023-04-18 19:07:29 +01002127 # The argument name and the object member name are the same, but this is not a
2128 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002129 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002130
2131 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002132 vim9script
2133 interface somethingWrong
2134 static count = 7
2135 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002136 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002137 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002138
2139 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002140 vim9script
2141 interface SomethingWrong
2142 this.value: string
2143 this.count = 7
2144 def GetCount(): number
2145 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002146 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002147 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002148
2149 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 vim9script
2151 interface SomethingWrong
2152 this.value: string
2153 this.count: number
2154 def GetCount(): number
2155 return 5
2156 enddef
2157 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002158 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002159 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002160
2161 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002162 vim9script
2163 export interface EnterExit
2164 def Enter(): void
2165 def Exit(): void
2166 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002167 END
2168 writefile(lines, 'XdefIntf.vim', 'D')
2169
2170 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 vim9script
2172 import './XdefIntf.vim' as defIntf
2173 export def With(ee: defIntf.EnterExit, F: func)
2174 ee.Enter()
2175 try
2176 F()
2177 finally
2178 ee.Exit()
2179 endtry
2180 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002181 END
2182 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002183
2184 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002185 vim9script
2186 export abstract class EnterExit
2187 def Enter(): void
2188 enddef
2189 def Exit(): void
2190 enddef
2191 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002192 END
2193 writefile(imported, 'XdefIntf2.vim', 'D')
2194
2195 lines[1] = " import './XdefIntf2.vim' as defIntf"
2196 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002197enddef
2198
Bram Moolenaar94674f22023-01-06 18:42:20 +00002199def Test_class_implements_interface()
2200 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 interface Some
2204 this.count: number
2205 def Method(nr: number)
2206 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002207
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002208 class SomeImpl implements Some
2209 this.count: number
2210 def Method(nr: number)
2211 echo nr
2212 enddef
2213 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002215 interface Another
2216 this.member: string
2217 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002218
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 class AnotherImpl implements Some, Another
2220 this.member = 'abc'
2221 this.count = 20
2222 def Method(nr: number)
2223 echo nr
2224 enddef
2225 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002226 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002227 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002228
2229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002230 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002231
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002232 interface Some
2233 this.count: number
2234 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002235
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002236 class SomeImpl implements Some implements Some
2237 this.count: number
2238 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002239 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002240 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002241
2242 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002244
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002245 interface Some
2246 this.count: number
2247 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002249 class SomeImpl implements Some, Some
2250 this.count: number
2251 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002253 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002254
2255 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002256 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002257
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002258 interface Some
2259 this.counter: number
2260 def Method(nr: number)
2261 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002262
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002263 class SomeImpl implements Some
2264 this.count: number
2265 def Method(nr: number)
2266 echo nr
2267 enddef
2268 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002269 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002270 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002271
2272 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002273 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002274
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002275 interface Some
2276 this.count: number
2277 def Methods(nr: number)
2278 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002279
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002280 class SomeImpl implements Some
2281 this.count: number
2282 def Method(nr: number)
2283 echo nr
2284 enddef
2285 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002286 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002287 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002288
2289 # Check different order of members in class and interface works.
2290 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002291 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002292
2293 interface Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002294 this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002295 this.errpos: number
2296 endinterface
2297
2298 # order of members is opposite of interface
2299 class Failure implements Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002300 public this.lnum: number = 5
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002301 this.errpos: number = 42
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002302 this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002303 endclass
2304
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002305 def Test()
2306 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002307
2308 assert_equal('label', result.label)
2309 assert_equal(42, result.errpos)
2310 enddef
2311
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002312 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002313 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002314 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002315
2316 # Interface name after "extends" doesn't end in a space or NUL character
2317 lines =<< trim END
2318 vim9script
2319 interface A
2320 endinterface
2321 class B extends A"
2322 endclass
2323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002324 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002325
2326 # Trailing characters after a class name
2327 lines =<< trim END
2328 vim9script
2329 class A bbb
2330 endclass
2331 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002333
2334 # using "implements" with a non-existing class
2335 lines =<< trim END
2336 vim9script
2337 class A implements B
2338 endclass
2339 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002341
2342 # using "implements" with a regular class
2343 lines =<< trim END
2344 vim9script
2345 class A
2346 endclass
2347 class B implements A
2348 endclass
2349 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002351
2352 # using "implements" with a variable
2353 lines =<< trim END
2354 vim9script
2355 var T: number = 10
2356 class A implements T
2357 endclass
2358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002359 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002360
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002361 # implements should be followed by a white space
2362 lines =<< trim END
2363 vim9script
2364 interface A
2365 endinterface
2366 class B implements A;
2367 endclass
2368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002370
LemonBoyc5d27442023-08-19 13:02:35 +02002371 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002373
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002374 interface One
2375 def IsEven(nr: number): bool
2376 endinterface
2377 class Two implements One
2378 def IsEven(nr: number): string
2379 enddef
2380 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002381 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002383
2384 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002385 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002386
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 interface One
2388 def IsEven(nr: number): bool
2389 endinterface
2390 class Two implements One
2391 def IsEven(nr: bool): bool
2392 enddef
2393 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002395 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002396
2397 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002399
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002400 interface One
2401 def IsEven(nr: number): bool
2402 endinterface
2403 class Two implements One
2404 def IsEven(nr: number, ...extra: list<number>): bool
2405 enddef
2406 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002407 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002408 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 +02002409
2410 # access superclass interface members from subclass, mix variable order
2411 lines =<< trim END
2412 vim9script
2413
2414 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 this.mvar1: number
2416 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002417 endinterface
2418
2419 # NOTE: the order is swapped
2420 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002421 this.mvar2: number
2422 this.mvar1: number
2423 public static svar2: number
2424 public static svar1: number
2425 def new()
2426 svar1 = 11
2427 svar2 = 12
2428 this.mvar1 = 111
2429 this.mvar2 = 112
2430 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002431 endclass
2432
2433 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002434 def new()
2435 this.mvar1 = 121
2436 this.mvar2 = 122
2437 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002438 endclass
2439
2440 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002441 def new()
2442 this.mvar1 = 131
2443 this.mvar2 = 132
2444 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002445 endclass
2446
Ernie Raelcf138d42023-09-06 20:45:03 +02002447 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002448 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002449 enddef
2450
2451 var oa = A.new()
2452 var ob = B.new()
2453 var oc = C.new()
2454
Ernie Raelcf138d42023-09-06 20:45:03 +02002455 assert_equal([111, 112], F2(oa))
2456 assert_equal([121, 122], F2(ob))
2457 assert_equal([131, 132], F2(oc))
2458 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002459 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002460
2461 # Access superclass interface members from subclass, mix variable order.
2462 # Two interfaces, one on A, one on B; each has both kinds of variables
2463 lines =<< trim END
2464 vim9script
2465
2466 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 this.mvar1: number
2468 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002469 endinterface
2470
2471 interface I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002472 this.mvar3: number
2473 this.mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002474 endinterface
2475
2476 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002477 public static svar1: number
2478 public static svar2: number
2479 this.mvar1: number
2480 this.mvar2: number
2481 def new()
2482 svar1 = 11
2483 svar2 = 12
2484 this.mvar1 = 111
2485 this.mvar2 = 112
2486 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002487 endclass
2488
2489 class B extends A implements I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002490 static svar3: number
2491 static svar4: number
2492 this.mvar3: number
2493 this.mvar4: number
2494 def new()
2495 svar3 = 23
2496 svar4 = 24
2497 this.mvar1 = 121
2498 this.mvar2 = 122
2499 this.mvar3 = 123
2500 this.mvar4 = 124
2501 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002502 endclass
2503
2504 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002505 public static svar5: number
2506 def new()
2507 svar5 = 1001
2508 this.mvar1 = 131
2509 this.mvar2 = 132
2510 this.mvar3 = 133
2511 this.mvar4 = 134
2512 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002513 endclass
2514
Ernie Raelcf138d42023-09-06 20:45:03 +02002515 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002516 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002517 enddef
2518
Ernie Raelcf138d42023-09-06 20:45:03 +02002519 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002521 enddef
2522
Ernie Raelcf138d42023-09-06 20:45:03 +02002523 var oa = A.new()
2524 var ob = B.new()
2525 var oc = C.new()
2526
Ernie Raelcf138d42023-09-06 20:45:03 +02002527 assert_equal([[111, 112]], [F2(oa)])
2528 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2529 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002530 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002531 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002532
2533 # Using two interface names without a space after the ","
2534 lines =<< trim END
2535 vim9script
2536 interface A
2537 endinterface
2538 interface B
2539 endinterface
2540 class C implements A,B
2541 endclass
2542 END
2543 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2544
2545 # No interface name after a comma
2546 lines =<< trim END
2547 vim9script
2548 interface A
2549 endinterface
2550 class B implements A,
2551 endclass
2552 END
2553 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2554
2555 # No interface name after implements
2556 lines =<< trim END
2557 vim9script
2558 class A implements
2559 endclass
2560 END
2561 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002562enddef
2563
Bram Moolenaard0200c82023-01-28 15:19:40 +00002564def Test_call_interface_method()
2565 var lines =<< trim END
2566 vim9script
2567 interface Base
2568 def Enter(): void
2569 endinterface
2570
2571 class Child implements Base
2572 def Enter(): void
2573 g:result ..= 'child'
2574 enddef
2575 endclass
2576
2577 def F(obj: Base)
2578 obj.Enter()
2579 enddef
2580
2581 g:result = ''
2582 F(Child.new())
2583 assert_equal('child', g:result)
2584 unlet g:result
2585 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002586 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002587
2588 lines =<< trim END
2589 vim9script
2590 class Base
2591 def Enter(): void
2592 g:result ..= 'base'
2593 enddef
2594 endclass
2595
2596 class Child extends Base
2597 def Enter(): void
2598 g:result ..= 'child'
2599 enddef
2600 endclass
2601
2602 def F(obj: Base)
2603 obj.Enter()
2604 enddef
2605
2606 g:result = ''
2607 F(Child.new())
2608 assert_equal('child', g:result)
2609 unlet g:result
2610 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002611 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002612
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002613 # method of interface returns a value
2614 lines =<< trim END
2615 vim9script
2616 interface Base
2617 def Enter(): string
2618 endinterface
2619
2620 class Child implements Base
2621 def Enter(): string
2622 g:result ..= 'child'
2623 return "/resource"
2624 enddef
2625 endclass
2626
2627 def F(obj: Base)
2628 var r = obj.Enter()
2629 g:result ..= r
2630 enddef
2631
2632 g:result = ''
2633 F(Child.new())
2634 assert_equal('child/resource', g:result)
2635 unlet g:result
2636 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002637 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002638
2639 lines =<< trim END
2640 vim9script
2641 class Base
2642 def Enter(): string
2643 return null_string
2644 enddef
2645 endclass
2646
2647 class Child extends Base
2648 def Enter(): string
2649 g:result ..= 'child'
2650 return "/resource"
2651 enddef
2652 endclass
2653
2654 def F(obj: Base)
2655 var r = obj.Enter()
2656 g:result ..= r
2657 enddef
2658
2659 g:result = ''
2660 F(Child.new())
2661 assert_equal('child/resource', g:result)
2662 unlet g:result
2663 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002664 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002665
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002666 # No class that implements the interface.
2667 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002668 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002670 interface IWithEE
2671 def Enter(): any
2672 def Exit(): void
2673 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002674
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002675 def With1(ee: IWithEE, F: func)
2676 var r = ee.Enter()
2677 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002679 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002680 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002681 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002682enddef
2683
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002684def Test_class_used_as_type()
2685 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002686 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002687
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002688 class Point
2689 this.x = 0
2690 this.y = 0
2691 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002692
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002693 var p: Point
2694 p = Point.new(2, 33)
2695 assert_equal(2, p.x)
2696 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002697 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002698 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002699
2700 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002701 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002702
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002703 interface HasX
2704 this.x: number
2705 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002706
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002707 class Point implements HasX
2708 this.x = 0
2709 this.y = 0
2710 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002712 var p: Point
2713 p = Point.new(2, 33)
2714 var hx = p
2715 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002716 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002717 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002718
2719 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002720 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002722 class Point
2723 this.x = 0
2724 this.y = 0
2725 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002726
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002727 var p: Point
2728 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002729 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002730 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002731enddef
2732
Bram Moolenaar83677162023-01-08 19:54:10 +00002733def Test_class_extends()
2734 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002735 vim9script
2736 class Base
2737 this.one = 1
2738 def GetOne(): number
2739 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002740 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002741 endclass
2742 class Child extends Base
2743 this.two = 2
2744 def GetTotal(): number
2745 return this.one + this.two
2746 enddef
2747 endclass
2748 var o = Child.new()
2749 assert_equal(1, o.one)
2750 assert_equal(2, o.two)
2751 assert_equal(1, o.GetOne())
2752 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002753 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002754 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002755
2756 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002757 vim9script
2758 class Base
2759 this.one = 1
2760 endclass
2761 class Child extends Base
2762 this.two = 2
2763 endclass
2764 var o = Child.new(3, 44)
2765 assert_equal(3, o.one)
2766 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002767 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002768 v9.CheckSourceSuccess(lines)
2769
2770 lines =<< trim END
2771 vim9script
2772 class Base
2773 this.one = 1
2774 endclass
2775 class Child extends Base extends Base
2776 this.two = 2
2777 endclass
2778 END
2779 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2780
2781 lines =<< trim END
2782 vim9script
2783 class Child extends BaseClass
2784 this.two = 2
2785 endclass
2786 END
2787 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2788
2789 lines =<< trim END
2790 vim9script
2791 var SomeVar = 99
2792 class Child extends SomeVar
2793 this.two = 2
2794 endclass
2795 END
2796 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2797
2798 lines =<< trim END
2799 vim9script
2800 class Base
2801 this.name: string
2802 def ToString(): string
2803 return this.name
2804 enddef
2805 endclass
2806
2807 class Child extends Base
2808 this.age: number
2809 def ToString(): string
2810 return super.ToString() .. ': ' .. this.age
2811 enddef
2812 endclass
2813
2814 var o = Child.new('John', 42)
2815 assert_equal('John: 42', o.ToString())
2816 END
2817 v9.CheckSourceSuccess(lines)
2818
2819 lines =<< trim END
2820 vim9script
2821 class Child
2822 this.age: number
2823 def ToString(): number
2824 return this.age
2825 enddef
2826 def ToString(): string
2827 return this.age
2828 enddef
2829 endclass
2830 END
2831 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2832
2833 lines =<< trim END
2834 vim9script
2835 class Child
2836 this.age: number
2837 def ToString(): string
2838 return super .ToString() .. ': ' .. this.age
2839 enddef
2840 endclass
2841 var o = Child.new(42)
2842 echo o.ToString()
2843 END
2844 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2845
2846 lines =<< trim END
2847 vim9script
2848 class Base
2849 this.name: string
2850 def ToString(): string
2851 return this.name
2852 enddef
2853 endclass
2854
2855 var age = 42
2856 def ToString(): string
2857 return super.ToString() .. ': ' .. age
2858 enddef
2859 echo ToString()
2860 END
2861 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2862
2863 lines =<< trim END
2864 vim9script
2865 class Child
2866 this.age: number
2867 def ToString(): string
2868 return super.ToString() .. ': ' .. this.age
2869 enddef
2870 endclass
2871 var o = Child.new(42)
2872 echo o.ToString()
2873 END
2874 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2875
2876 lines =<< trim END
2877 vim9script
2878 class Base
2879 this.name: string
2880 static def ToString(): string
2881 return 'Base class'
2882 enddef
2883 endclass
2884
2885 class Child extends Base
2886 this.age: number
2887 def ToString(): string
2888 return Base.ToString() .. ': ' .. this.age
2889 enddef
2890 endclass
2891
2892 var o = Child.new('John', 42)
2893 assert_equal('Base class: 42', o.ToString())
2894 END
2895 v9.CheckSourceSuccess(lines)
2896
2897 lines =<< trim END
2898 vim9script
2899 class Base
2900 this.value = 1
2901 def new(init: number)
2902 this.value = number + 1
2903 enddef
2904 endclass
2905 class Child extends Base
2906 def new()
2907 this.new(3)
2908 enddef
2909 endclass
2910 var c = Child.new()
2911 END
2912 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002913
2914 # base class with more than one object member
2915 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002916 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002917
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002918 class Result
2919 this.success: bool
2920 this.value: any = null
2921 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002922
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002923 class Success extends Result
2924 def new(this.value = v:none)
2925 this.success = true
2926 enddef
2927 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002928
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 var v = Success.new('asdf')
2930 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002931 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002932 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002933
2934 # class name after "extends" doesn't end in a space or NUL character
2935 lines =<< trim END
2936 vim9script
2937 class A
2938 endclass
2939 class B extends A"
2940 endclass
2941 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002942 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00002943enddef
2944
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002945def Test_using_base_class()
2946 var lines =<< trim END
2947 vim9script
2948
2949 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 def Enter(): any
2951 return null
2952 enddef
2953 def Exit(resource: any): void
2954 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002955 endclass
2956
2957 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 def Enter(): any
2959 return 42
2960 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002962 def Exit(resource: number): void
2963 g:result ..= '/exit'
2964 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002965 endclass
2966
2967 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 var r = ee.Enter()
2969 try
2970 g:result ..= r
2971 finally
2972 g:result ..= '/finally'
2973 ee.Exit(r)
2974 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002975 enddef
2976
2977 g:result = ''
2978 With(ChildEE.new())
2979 assert_equal('42/finally/exit', g:result)
2980 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002981 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002982 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002983
2984 # Using super, Child invokes Base method which has optional arg. #12471
2985 lines =<< trim END
2986 vim9script
2987
2988 class Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 this.success: bool = false
2990 def Method(arg = 0)
2991 this.success = true
2992 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002993 endclass
2994
2995 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002996 def new()
2997 super.Method()
2998 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002999 endclass
3000
3001 var obj = Child.new()
3002 assert_equal(true, obj.success)
3003 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003004 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003005enddef
3006
Bram Moolenaara86655a2023-01-12 17:06:27 +00003007def Test_class_import()
3008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003009 vim9script
3010 export class Animal
3011 this.kind: string
3012 this.name: string
3013 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003014 END
3015 writefile(lines, 'Xanimal.vim', 'D')
3016
3017 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003018 vim9script
3019 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 var a: animal.Animal
3022 a = animal.Animal.new('fish', 'Eric')
3023 assert_equal('fish', a.kind)
3024 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003026 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3027 assert_equal('cat', b.kind)
3028 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003029 END
3030 v9.CheckScriptSuccess(lines)
3031enddef
3032
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003033def Test_abstract_class()
3034 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003035 vim9script
3036 abstract class Base
3037 this.name: string
3038 endclass
3039 class Person extends Base
3040 this.age: number
3041 endclass
3042 var p: Base = Person.new('Peter', 42)
3043 assert_equal('Peter', p.name)
3044 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003045 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003046 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003047
3048 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 vim9script
3050 abstract class Base
3051 this.name: string
3052 endclass
3053 class Person extends Base
3054 this.age: number
3055 endclass
3056 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003057 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003058 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003059
3060 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003061 abstract class Base
3062 this.name: string
3063 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003065 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003066
3067 # Abstract class cannot have a "new" function
3068 lines =<< trim END
3069 vim9script
3070 abstract class Base
3071 def new()
3072 enddef
3073 endclass
3074 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003075 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003076enddef
3077
Bram Moolenaar486fc252023-01-18 14:51:07 +00003078def Test_closure_in_class()
3079 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003080 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003081
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003082 class Foo
3083 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 def new()
3086 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3087 enddef
3088 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003089
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003090 Foo.new()
3091 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003092 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003093 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003094enddef
3095
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003096def Test_call_constructor_from_legacy()
3097 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003098 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003099
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003100 var newCalled = 'false'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003101
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003102 class A
3103 def new()
3104 newCalled = 'true'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003105 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003106 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003107
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003108 export def F(options = {}): any
3109 return A
3110 enddef
3111
3112 g:p = F()
3113 legacy call p.new()
3114 assert_equal('true', newCalled)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003115 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003116 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003117enddef
3118
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003119def Test_defer_with_object()
3120 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003121 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003122
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003123 class CWithEE
3124 def Enter()
3125 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003126 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003127 def Exit()
3128 g:result ..= "exited"
3129 enddef
3130 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003131
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003132 def With(ee: CWithEE, F: func)
3133 ee.Enter()
3134 defer ee.Exit()
3135 F()
3136 enddef
3137
3138 g:result = ''
3139 var obj = CWithEE.new()
3140 obj->With(() => {
3141 g:result ..= "called/"
3142 })
3143 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003144 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003145 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003146 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003147
3148 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003149 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003150
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003151 class BaseWithEE
3152 def Enter()
3153 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003154 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003155 def Exit()
3156 g:result ..= "exited-base"
3157 enddef
3158 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003159
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003160 class CWithEE extends BaseWithEE
3161 def Enter()
3162 g:result ..= "entered-child/"
3163 enddef
3164 def Exit()
3165 g:result ..= "exited-child"
3166 enddef
3167 endclass
3168
3169 def With(ee: BaseWithEE, F: func)
3170 ee.Enter()
3171 defer ee.Exit()
3172 F()
3173 enddef
3174
3175 g:result = ''
3176 var obj = CWithEE.new()
3177 obj->With(() => {
3178 g:result ..= "called/"
3179 })
3180 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003181 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003182 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003183 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003184enddef
3185
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003186" The following test used to crash Vim (Github issue #12676)
3187def Test_extends_method_crashes_vim()
3188 var lines =<< trim END
3189 vim9script
3190
3191 class Observer
3192 endclass
3193
3194 class Property
3195 this.value: any
3196
3197 def Set(v: any)
3198 if v != this.value
3199 this.value = v
3200 endif
3201 enddef
3202
3203 def Register(observer: Observer)
3204 enddef
3205 endclass
3206
3207 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003208 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003209 endclass
3210
3211 def Observe(obj: Property, who: Observer)
3212 obj.Register(who)
3213 enddef
3214
3215 var p = Bool.new(false)
3216 var myObserver = Observer.new()
3217
3218 Observe(p, myObserver)
3219
3220 p.Set(true)
3221 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003222 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003223enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003224
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003225" Test for calling a method in a class that is extended
3226def Test_call_method_in_extended_class()
3227 var lines =<< trim END
3228 vim9script
3229
3230 var prop_init_called = false
3231 var prop_register_called = false
3232
3233 class Property
3234 def Init()
3235 prop_init_called = true
3236 enddef
3237
3238 def Register()
3239 prop_register_called = true
3240 enddef
3241 endclass
3242
3243 class Bool extends Property
3244 endclass
3245
3246 def Observe(obj: Property)
3247 obj.Register()
3248 enddef
3249
3250 var p = Property.new()
3251 Observe(p)
3252
3253 p.Init()
3254 assert_true(prop_init_called)
3255 assert_true(prop_register_called)
3256 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003257 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003258enddef
3259
LemonBoyafe04662023-08-23 21:08:11 +02003260def Test_instanceof()
3261 var lines =<< trim END
3262 vim9script
3263
3264 class Base1
3265 endclass
3266
3267 class Base2 extends Base1
3268 endclass
3269
3270 interface Intf1
3271 endinterface
3272
3273 class Mix1 implements Intf1
3274 endclass
3275
3276 class Base3 extends Mix1
3277 endclass
3278
3279 var b1 = Base1.new()
3280 var b2 = Base2.new()
3281 var b3 = Base3.new()
3282
3283 assert_true(instanceof(b1, Base1))
3284 assert_true(instanceof(b2, Base1))
3285 assert_false(instanceof(b1, Base2))
3286 assert_true(instanceof(b3, Mix1))
3287 assert_false(instanceof(b3, []))
3288 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003289
3290 def Foo()
3291 var a1 = Base1.new()
3292 var a2 = Base2.new()
3293 var a3 = Base3.new()
3294
3295 assert_true(instanceof(a1, Base1))
3296 assert_true(instanceof(a2, Base1))
3297 assert_false(instanceof(a1, Base2))
3298 assert_true(instanceof(a3, Mix1))
3299 assert_false(instanceof(a3, []))
3300 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3301 enddef
3302 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003303
3304 var o_null: Base1
3305 assert_false(instanceof(o_null, Base1))
3306
LemonBoyafe04662023-08-23 21:08:11 +02003307 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003308 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003309enddef
3310
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003311" Test for calling a method in the parent class that is extended partially.
3312" This used to fail with the 'E118: Too many arguments for function: Text' error
3313" message (Github issue #12524).
3314def Test_call_method_in_parent_class()
3315 var lines =<< trim END
3316 vim9script
3317
3318 class Widget
3319 this._lnum: number = 1
3320
3321 def SetY(lnum: number)
3322 this._lnum = lnum
3323 enddef
3324
3325 def Text(): string
3326 return ''
3327 enddef
3328 endclass
3329
3330 class Foo extends Widget
3331 def Text(): string
3332 return '<Foo>'
3333 enddef
3334 endclass
3335
3336 def Stack(w1: Widget, w2: Widget): list<Widget>
3337 w1.SetY(1)
3338 w2.SetY(2)
3339 return [w1, w2]
3340 enddef
3341
3342 var foo1 = Foo.new()
3343 var foo2 = Foo.new()
3344 var l = Stack(foo1, foo2)
3345 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003346 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003347enddef
3348
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003349" Test for calling methods from three levels of classes
3350def Test_multi_level_method_call()
3351 var lines =<< trim END
3352 vim9script
3353
3354 var A_func1: number = 0
3355 var A_func2: number = 0
3356 var A_func3: number = 0
3357 var B_func2: number = 0
3358 var B_func3: number = 0
3359 var C_func3: number = 0
3360
3361 class A
3362 def Func1()
3363 A_func1 += 1
3364 enddef
3365
3366 def Func2()
3367 A_func2 += 1
3368 enddef
3369
3370 def Func3()
3371 A_func3 += 1
3372 enddef
3373 endclass
3374
3375 class B extends A
3376 def Func2()
3377 B_func2 += 1
3378 enddef
3379
3380 def Func3()
3381 B_func3 += 1
3382 enddef
3383 endclass
3384
3385 class C extends B
3386 def Func3()
3387 C_func3 += 1
3388 enddef
3389 endclass
3390
3391 def A_CallFuncs(a: A)
3392 a.Func1()
3393 a.Func2()
3394 a.Func3()
3395 enddef
3396
3397 def B_CallFuncs(b: B)
3398 b.Func1()
3399 b.Func2()
3400 b.Func3()
3401 enddef
3402
3403 def C_CallFuncs(c: C)
3404 c.Func1()
3405 c.Func2()
3406 c.Func3()
3407 enddef
3408
3409 var cobj = C.new()
3410 A_CallFuncs(cobj)
3411 B_CallFuncs(cobj)
3412 C_CallFuncs(cobj)
3413 assert_equal(3, A_func1)
3414 assert_equal(0, A_func2)
3415 assert_equal(0, A_func3)
3416 assert_equal(3, B_func2)
3417 assert_equal(0, B_func3)
3418 assert_equal(3, C_func3)
3419 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003420 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003421enddef
3422
3423" Test for using members from three levels of classes
3424def Test_multi_level_member_access()
3425 var lines =<< trim END
3426 vim9script
3427
3428 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003429 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003430 endclass
3431
3432 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003433 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003434 endclass
3435
3436 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003437 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003438 endclass
3439
3440 def A_members(a: A)
3441 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003442 enddef
3443
3444 def B_members(b: B)
3445 b.val1 += 1
3446 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003447 enddef
3448
3449 def C_members(c: C)
3450 c.val1 += 1
3451 c.val2 += 1
3452 c.val3 += 1
3453 enddef
3454
3455 var cobj = C.new()
3456 A_members(cobj)
3457 B_members(cobj)
3458 C_members(cobj)
3459 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003460 assert_equal(2, cobj.val2)
3461 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003462 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003463 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003464enddef
3465
LemonBoy0ffc17a2023-08-20 18:09:11 +02003466" Test expansion of <stack> with class methods.
3467def Test_stack_expansion_with_methods()
3468 var lines =<< trim END
3469 vim9script
3470
3471 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003472 def M1()
3473 F0()
3474 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003475 endclass
3476
3477 def F0()
3478 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3479 enddef
3480
3481 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003482 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003483 enddef
3484
3485 F()
3486 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003487 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003488enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003489
3490" Test the return type of the new() constructor
3491def Test_new_return_type()
3492 # new() uses the default return type and there is no return statement
3493 var lines =<< trim END
3494 vim9script
3495
3496 class C
3497 this._bufnr: number
3498
3499 def new(this._bufnr)
3500 if !bufexists(this._bufnr)
3501 this._bufnr = -1
3502 endif
3503 enddef
3504 endclass
3505
3506 var c = C.new(12345)
3507 assert_equal('object<C>', typename(c))
3508
3509 var v1: C
3510 v1 = C.new(12345)
3511 assert_equal('object<C>', typename(v1))
3512
3513 def F()
3514 var v2: C
3515 v2 = C.new(12345)
3516 assert_equal('object<C>', typename(v2))
3517 enddef
3518 F()
3519 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003520 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003521
3522 # new() uses the default return type and an empty 'return' statement
3523 lines =<< trim END
3524 vim9script
3525
3526 class C
3527 this._bufnr: number
3528
3529 def new(this._bufnr)
3530 if !bufexists(this._bufnr)
3531 this._bufnr = -1
3532 return
3533 endif
3534 enddef
3535 endclass
3536
3537 var c = C.new(12345)
3538 assert_equal('object<C>', typename(c))
3539
3540 var v1: C
3541 v1 = C.new(12345)
3542 assert_equal('object<C>', typename(v1))
3543
3544 def F()
3545 var v2: C
3546 v2 = C.new(12345)
3547 assert_equal('object<C>', typename(v2))
3548 enddef
3549 F()
3550 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003551 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003552
3553 # new() uses "any" return type and returns "this"
3554 lines =<< trim END
3555 vim9script
3556
3557 class C
3558 this._bufnr: number
3559
3560 def new(this._bufnr): any
3561 if !bufexists(this._bufnr)
3562 this._bufnr = -1
3563 return this
3564 endif
3565 enddef
3566 endclass
3567 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003568 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003569
3570 # new() uses 'Dict' return type and returns a Dict
3571 lines =<< trim END
3572 vim9script
3573
3574 class C
3575 this._state: dict<any>
3576
3577 def new(): dict<any>
3578 this._state = {}
3579 return this._state
3580 enddef
3581 endclass
3582
3583 var c = C.new()
3584 assert_equal('object<C>', typename(c))
3585 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003586 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003587enddef
3588
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003589" Test for checking a member initialization type at run time.
3590def Test_runtime_type_check_for_member_init()
3591 var lines =<< trim END
3592 vim9script
3593
3594 var retnum: bool = false
3595
3596 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003597 retnum = !retnum
3598 if retnum
3599 return 1
3600 else
3601 return "hello"
3602 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003603 enddef
3604
3605 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003606 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003607 endclass
3608
3609 var c1 = C.new()
3610 var c2 = C.new()
3611 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003612 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003613enddef
3614
3615" Test for locking a variable referring to an object and reassigning to another
3616" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003617def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003618 var lines =<< trim END
3619 vim9script
3620
3621 class C
3622 this.val: number
3623 def new(this.val)
3624 enddef
3625 endclass
3626
3627 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3628 lockvar 2 some_dict
3629
3630 var current: C
3631 current = some_dict['c']
3632 assert_equal(3, current.val)
3633 current = some_dict['b']
3634 assert_equal(2, current.val)
3635
3636 def F()
3637 current = some_dict['c']
3638 enddef
3639
3640 def G()
3641 current = some_dict['b']
3642 enddef
3643
3644 F()
3645 assert_equal(3, current.val)
3646 G()
3647 assert_equal(2, current.val)
3648 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003649 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003650enddef
3651
Ernie Raelee865f32023-09-29 19:53:55 +02003652" Test trying to lock an object variable from various places
3653def Test_lockvar_object_variable()
3654 # An object variable lockvar has several cases:
3655 # object method, scriptlevel, scriplevel from :def, :def arg
3656 # method arg, static method arg.
3657 # Also different depths
3658
Ernie Raelee865f32023-09-29 19:53:55 +02003659 #
3660 # lockvar of read-only object variable
3661 #
3662
3663 # read-only lockvar from object method
3664 var lines =<< trim END
3665 vim9script
3666
3667 class C
3668 this.val1: number
3669 def Lock()
3670 lockvar this.val1
3671 enddef
3672 endclass
3673 var o = C.new(3)
3674 o.Lock()
3675 END
Ernie Rael64885642023-10-04 20:16:22 +02003676 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003677
3678 # read-only lockvar from scriptlevel
3679 lines =<< trim END
3680 vim9script
3681
3682 class C
3683 this.val2: number
3684 endclass
3685 var o = C.new(3)
3686 lockvar o.val2
3687 END
3688 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3689
3690 # read-only lockvar of scriptlevel variable from def
3691 lines =<< trim END
3692 vim9script
3693
3694 class C
3695 this.val3: number
3696 endclass
3697 var o = C.new(3)
3698 def Lock()
3699 lockvar o.val3
3700 enddef
3701 Lock()
3702 END
3703 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3704
3705 # read-only lockvar of def argument variable
3706 lines =<< trim END
3707 vim9script
3708
3709 class C
3710 this.val4: number
3711 endclass
3712 def Lock(o: C)
3713 lockvar o.val4
3714 enddef
3715 Lock(C.new(3))
3716 END
3717 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3718
3719 # TODO: the following tests use type "any" for argument. Need a run time
3720 # check for access. Probably OK as is for now.
3721
3722 # read-only lockvar from object method arg
3723 lines =<< trim END
3724 vim9script
3725
3726 class C
3727 this.val5: number
3728 def Lock(o_any: any)
3729 lockvar o_any.val5
3730 enddef
3731 endclass
3732 var o = C.new(3)
3733 o.Lock(C.new(5))
3734 END
Ernie Rael64885642023-10-04 20:16:22 +02003735 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003736
3737 # read-only lockvar from class method arg
3738 lines =<< trim END
3739 vim9script
3740
3741 class C
3742 this.val6: number
3743 static def Lock(o_any: any)
3744 lockvar o_any.val6
3745 enddef
3746 endclass
3747 var o = C.new(3)
3748 C.Lock(o)
3749 END
Ernie Rael64885642023-10-04 20:16:22 +02003750 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003751
3752 #
3753 # lockvar of public object variable
3754 #
3755
3756 # lockvar from object method
3757 lines =<< trim END
3758 vim9script
3759
3760 class C
3761 public this.val1: number
3762 def Lock()
3763 lockvar this.val1
3764 enddef
3765 endclass
3766 var o = C.new(3)
3767 o.Lock()
3768 END
3769 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3770
3771 # lockvar from scriptlevel
3772 lines =<< trim END
3773 vim9script
3774
3775 class C
3776 public this.val2: number
3777 endclass
3778 var o = C.new(3)
3779 lockvar o.val2
3780 END
3781 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3782
3783 # lockvar of scriptlevel variable from def
3784 lines =<< trim END
3785 vim9script
3786
3787 class C
3788 public this.val3: number
3789 endclass
3790 var o = C.new(3)
3791 def Lock()
3792 lockvar o.val3
3793 enddef
3794 Lock()
3795 END
3796 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3797
3798 # lockvar of def argument variable
3799 lines =<< trim END
3800 vim9script
3801
3802 class C
3803 public this.val4: number
3804 endclass
3805 def Lock(o: C)
3806 lockvar o.val4
3807 enddef
3808 Lock(C.new(3))
3809 END
3810 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3811
3812 # lockvar from object method arg
3813 lines =<< trim END
3814 vim9script
3815
3816 class C
3817 public this.val5: number
3818 def Lock(o_any: any)
3819 lockvar o_any.val5
3820 enddef
3821 endclass
3822 var o = C.new(3)
3823 o.Lock(C.new(5))
3824 END
3825 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3826
3827 # lockvar from class method arg
3828 lines =<< trim END
3829 vim9script
3830
3831 class C
3832 public this.val6: number
3833 static def Lock(o_any: any)
3834 lockvar o_any.val6
3835 enddef
3836 endclass
3837 var o = C.new(3)
3838 C.Lock(o)
3839 END
3840 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3841enddef
3842
3843" Test trying to lock a class variable from various places
3844def Test_lockvar_class_variable()
3845
3846 # lockvar bare static from object method
3847 var lines =<< trim END
3848 vim9script
3849
3850 class C
3851 public static sval1: number
3852 def Lock()
3853 lockvar sval1
3854 enddef
3855 endclass
3856 var o = C.new()
3857 o.Lock()
3858 END
3859 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3860
3861 # lockvar C.static from object method
3862 lines =<< trim END
3863 vim9script
3864
3865 class C
3866 public static sval2: number
3867 def Lock()
3868 lockvar C.sval2
3869 enddef
3870 endclass
3871 var o = C.new()
3872 o.Lock()
3873 END
3874 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3875
3876 # lockvar bare static from class method
3877 lines =<< trim END
3878 vim9script
3879
3880 class C
3881 public static sval3: number
3882 static def Lock()
3883 lockvar sval3
3884 enddef
3885 endclass
3886 C.Lock()
3887 END
3888 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
3889
3890 # lockvar C.static from class method
3891 lines =<< trim END
3892 vim9script
3893
3894 class C
3895 public static sval4: number
3896 static def Lock()
3897 lockvar C.sval4
3898 enddef
3899 endclass
3900 C.Lock()
3901 END
3902 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
3903
3904 # lockvar C.static from script level
3905 lines =<< trim END
3906 vim9script
3907
3908 class C
3909 public static sval5: number
3910 endclass
3911 lockvar C.sval5
3912 END
3913 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
3914
3915 # lockvar o.static from script level
3916 lines =<< trim END
3917 vim9script
3918
3919 class C
3920 public static sval6: number
3921 endclass
3922 var o = C.new()
3923 lockvar o.sval6
3924 END
3925 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
3926enddef
3927
3928" Test locking an argument to :def
3929def Test_lockvar_argument()
3930 # Lockvar a function arg
3931 var lines =<< trim END
3932 vim9script
3933
3934 def Lock(val: any)
3935 lockvar val
3936 enddef
3937
3938 var d = {a: 1, b: 2}
3939 Lock(d)
3940
3941 d->extend({c: 3})
3942 END
3943 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
3944
3945 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
3946 # class member in "C". This tests lval_root_is_arg.
3947 lines =<< trim END
3948 vim9script
3949
3950 class C
3951 public static sval: list<number>
3952 endclass
3953
3954 def Lock2(sval: any)
3955 lockvar sval
3956 enddef
3957
3958 var o = C.new()
3959 Lock2(o)
3960 END
3961 v9.CheckSourceSuccess(lines)
3962
3963 # Lock a class.
3964 lines =<< trim END
3965 vim9script
3966
3967 class C
3968 public static sval: list<number>
3969 endclass
3970
3971 def Lock2(sval: any)
3972 lockvar sval
3973 enddef
3974
3975 Lock2(C)
3976 END
3977 v9.CheckSourceSuccess(lines)
3978
3979 # Lock an object.
3980 lines =<< trim END
3981 vim9script
3982
3983 class C
3984 public static sval: list<number>
3985 endclass
3986
3987 def Lock2(sval: any)
3988 lockvar sval
3989 enddef
3990
3991 Lock2(C.new())
3992 END
3993 v9.CheckSourceSuccess(lines)
3994
3995 # In this case (unlike previous) "lockvar sval" is a class member.
3996 lines =<< trim END
3997 vim9script
3998
3999 class C
4000 public static sval: list<number>
4001 def Lock2()
4002 lockvar sval
4003 enddef
4004 endclass
4005
4006
4007 var o = C.new()
4008 o.Lock2()
4009 END
4010 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4011enddef
4012
4013" Test that this can be locked without error
4014def Test_lockvar_this()
4015 # lockvar this
4016 var lines =<< trim END
4017 vim9script
4018 class C
4019 def TLock()
4020 lockvar this
4021 enddef
4022 endclass
4023 var o = C.new()
4024 o.TLock()
4025 END
4026 v9.CheckSourceSuccess(lines)
4027
4028 # lockvar four (four letter word, but not this)
4029 lines =<< trim END
4030 vim9script
4031 class C
4032 def TLock4()
4033 var four: number
4034 lockvar four
4035 enddef
4036 endclass
4037 var o = C.new()
4038 o.TLock4()
4039 END
4040 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4041
4042 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4043 lines =<< trim END
4044 vim9script
4045 class C
4046 def TLock5()
4047 var this5: number
4048 lockvar this5
4049 enddef
4050 endclass
4051 var o = C.new()
4052 o.TLock5()
4053 END
4054 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4055enddef
4056
4057" Test some general lockvar cases
4058def Test_lockvar_general()
4059 # lockvar an object and a class. It does nothing
4060 var lines =<< trim END
4061 vim9script
4062 class C
4063 endclass
4064 var o = C.new()
4065 lockvar o
4066 lockvar C
4067 END
4068 v9.CheckSourceSuccess(lines)
4069
4070 # Lock a list element that's nested in an object variable from a :def
4071 lines =<< trim END
4072 vim9script
4073
4074 class C
4075 public this.val: list<list<number>> = [ [1], [2], [3] ]
4076 endclass
4077 def Lock2(obj: any)
4078 lockvar obj.val[1]
4079 enddef
4080
4081 var o = C.new()
4082 Lock2(o)
4083 o.val[0] = [9]
4084 assert_equal([ [9], [2], [3] ], o.val)
4085 try
4086 o.val[1] = [999]
4087 call assert_false(true, 'assign should have failed')
4088 catch
4089 assert_exception('E741:')
4090 endtry
4091 o.val[2] = [8]
4092 assert_equal([ [9], [2], [8] ], o.val)
4093 END
4094 v9.CheckSourceSuccess(lines)
4095
4096 # Lock a list element that's nested in an object variable from scriptlevel
4097 lines =<< trim END
4098 vim9script
4099
4100 class C
4101 public this.val: list<list<number>> = [ [1], [2], [3] ]
4102 endclass
4103
4104 var o = C.new()
4105 lockvar o.val[1]
4106 o.val[0] = [9]
4107 assert_equal([ [9], [2], [3] ], o.val)
4108 try
4109 o.val[1] = [999]
4110 call assert_false(true, 'assign should have failed')
4111 catch
4112 assert_exception('E741:')
4113 endtry
4114 o.val[2] = [8]
4115 assert_equal([ [9], [2], [8] ], o.val)
4116 END
4117 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004118
4119 # lock a script level variable from an object method
4120 lines =<< trim END
4121 vim9script
4122
4123 class C
4124 def Lock()
4125 lockvar l
4126 enddef
4127 endclass
4128
4129 var l = [1]
4130 C.new().Lock()
4131 l[0] = 11
4132 END
4133 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4134
4135 # lock a list element referenced by a private object variable
4136 # in an object fetched via a script level list
4137 lines =<< trim END
4138 vim9script
4139
4140 class C
4141 this._v1: list<list<number>>
4142 def Lock()
4143 lockvar lc[0]._v1[1]
4144 enddef
4145 endclass
4146
4147 var l = [[1], [2], [3]]
4148 var o = C.new(l)
4149 var lc: list<C> = [ o ]
4150
4151 o.Lock()
4152 l[0] = [22]
4153 l[1] = [33]
4154 END
4155 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4156
4157 # similar to the previous test, except the locking code is executing
4158 # in a class that does not own the private variable.
4159 # Note that the locking code is in a class has a private variable of
4160 # the same name.
4161 lines =<< trim END
4162 vim9script
4163
4164 class C2
4165 this._v1: list<list<number>>
4166 def Lock(obj: any)
4167 lockvar lc[0]._v1[1]
4168 enddef
4169 endclass
4170
4171 class C
4172 this._v1: list<list<number>>
4173 endclass
4174
4175 var l = [[1], [2], [3]]
4176 var o = C.new(l)
4177 var lc: list<C> = [ o ]
4178
4179 var o2 = C2.new()
4180 o2.Lock(o)
4181 END
4182 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004183enddef
4184
Ernie Rael9771b2a2023-10-07 22:05:40 +02004185" Test builtin islocked()
4186def Test_lockvar_islocked()
4187 # Can't lock class/object variable
4188 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004189 # Lock item of variable's value (a list item)
4190 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004191 var lines =<< trim END
4192 vim9script
4193
4194 class C
4195 this.o0: list<list<number>> = [ [0], [1], [2]]
4196 this.o1: list<list<number>> = [[10], [11], [12]]
4197 static c0: list<list<number>> = [[20], [21], [22]]
4198 static c1: list<list<number>> = [[30], [31], [32]]
4199 endclass
4200
4201 def LockIt(arg: any)
4202 lockvar arg
4203 enddef
4204
4205 def UnlockIt(arg: any)
4206 unlockvar arg
4207 enddef
4208
4209 var obj = C.new()
4210 #lockvar obj.o1 # can't lock something you can't write to
4211
4212 try
4213 lockvar obj.o1 # can't lock something you can't write to
4214 call assert_false(1, '"lockvar obj.o1" should have failed')
4215 catch
4216 call assert_exception('E1335:')
4217 endtry
4218
4219 LockIt(obj.o1) # but can lock it's value
4220 assert_equal(1, islocked("obj.o1"))
4221 assert_equal(1, islocked("obj.o1[0]"))
4222 assert_equal(1, islocked("obj.o1[1]"))
4223 UnlockIt(obj.o1)
4224 assert_equal(0, islocked("obj.o1"))
4225 assert_equal(0, islocked("obj.o1[0]"))
4226
4227 lockvar obj.o1[0]
4228 assert_equal(0, islocked("obj.o1"))
4229 assert_equal(1, islocked("obj.o1[0]"))
4230 assert_equal(0, islocked("obj.o1[1]"))
4231 unlockvar obj.o1[0]
4232 assert_equal(0, islocked("obj.o1"))
4233 assert_equal(0, islocked("obj.o1[0]"))
4234
4235 # Same thing, but with a static
4236
4237 try
4238 lockvar C.c1 # can't lock something you can't write to
4239 call assert_false(1, '"lockvar C.c1" should have failed')
4240 catch
4241 call assert_exception('E1335:')
4242 endtry
4243
4244 LockIt(C.c1) # but can lock it's value
4245 assert_equal(1, islocked("C.c1"))
4246 assert_equal(1, islocked("C.c1[0]"))
4247 assert_equal(1, islocked("C.c1[1]"))
4248 UnlockIt(C.c1)
4249 assert_equal(0, islocked("C.c1"))
4250 assert_equal(0, islocked("C.c1[0]"))
4251
4252 lockvar C.c1[0]
4253 assert_equal(0, islocked("C.c1"))
4254 assert_equal(1, islocked("C.c1[0]"))
4255 assert_equal(0, islocked("C.c1[1]"))
4256 unlockvar C.c1[0]
4257 assert_equal(0, islocked("C.c1"))
4258 assert_equal(0, islocked("C.c1[0]"))
4259 END
4260 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004261
4262 # Do islocked() from an object method
4263 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004264 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004265 vim9script
4266
4267 var l0o0 = [ [0], [1], [2]]
4268 var l0o1 = [ [10], [11], [12]]
4269 var l0c0 = [[120], [121], [122]]
4270 var l0c1 = [[130], [131], [132]]
4271
4272 class C0
4273 this.o0: list<list<number>> = l0o0
4274 this.o1: list<list<number>> = l0o1
4275 static c0: list<list<number>> = l0c0
4276 static c1: list<list<number>> = l0c1
4277 def Islocked(arg: string): number
4278 return islocked(arg)
4279 enddef
4280 static def SIslocked(arg: string): number
4281 return islocked(arg)
4282 enddef
4283 endclass
4284
4285 var l2o0 = [[20000], [20001], [20002]]
4286 var l2o1 = [[20010], [20011], [20012]]
4287 var l2c0 = [[20120], [20121], [20122]]
4288 var l2c1 = [[20130], [20131], [20132]]
4289
4290 class C2
4291 this.o0: list<list<number>> = l2o0
4292 this.o1: list<list<number>> = l2o1
4293 static c0: list<list<number>> = l2c0
4294 static c1: list<list<number>> = l2c1
4295 def Islocked(arg: string): number
4296 return islocked(arg)
4297 enddef
4298 static def SIslocked(arg: string): number
4299 return islocked(arg)
4300 enddef
4301 endclass
4302
4303 var obj0 = C0.new()
4304 var obj2 = C2.new()
4305
4306 var l = [ obj0, null_object, obj2 ]
4307
4308 # lock list, object func access through script var expr
4309 assert_equal(0, obj0.Islocked("l[0].o0"))
4310 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4311 lockvar l0o0
4312 assert_equal(1, obj0.Islocked("l[0].o0"))
4313 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4314
4315 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4316
4317 # lock list element, object func access through script var expr
4318 lockvar l0o1[1]
4319 assert_equal(0, obj0.Islocked("this.o1[0]"))
4320 assert_equal(1, obj0.Islocked("this.o1[1]"))
4321
4322 assert_equal(0, obj0.Islocked("this.o1"))
4323 lockvar l0o1
4324 assert_equal(1, obj0.Islocked("this.o1"))
4325 unlockvar l0o1
4326
4327 lockvar l0c1[1]
4328
4329 # static by class name member expr from same class
4330 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4331 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4332 # static by bare name member expr from same class
4333 assert_equal(0, obj0.Islocked("c1[0]"))
4334 assert_equal(1, obj0.Islocked("c1[1]"))
4335
4336 # static by class name member expr from other class
4337 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4338 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4339 # static by bare name member expr from other class
4340 assert_equal(0, obj2.Islocked("c1[0]"))
4341 assert_equal(0, obj2.Islocked("c1[1]"))
4342
4343
4344 # static by bare name in same class
4345 assert_equal(0, obj0.Islocked("c0"))
4346 lockvar l0c0
4347 assert_equal(1, obj0.Islocked("c0"))
4348
4349 #
4350 # similar stuff, but use static method
4351 #
4352
4353 unlockvar l0o0
4354
4355 # lock list, object func access through script var expr
4356 assert_equal(0, C0.SIslocked("l[0].o0"))
4357 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4358 lockvar l0o0
4359 assert_equal(1, C0.SIslocked("l[0].o0"))
4360 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4361
4362 unlockvar l0o1
4363
4364 # can't access "this" from class method
4365 try
4366 C0.SIslocked("this.o1[0]")
4367 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4368 catch
4369 call assert_exception('E121: Undefined variable: this')
4370 endtry
4371
4372 lockvar l0c1[1]
4373
4374 # static by class name member expr from same class
4375 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4376 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4377 # static by bare name member expr from same class
4378 assert_equal(0, C0.SIslocked("c1[0]"))
4379 assert_equal(1, C0.SIslocked("c1[1]"))
4380
4381 # static by class name member expr from other class
4382 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4383 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4384 # static by bare name member expr from other class
4385 assert_equal(0, C2.SIslocked("c1[0]"))
4386 assert_equal(0, C2.SIslocked("c1[1]"))
4387
4388
4389 # static by bare name in same class
4390 unlockvar l0c0
4391 assert_equal(0, C0.SIslocked("c0"))
4392 lockvar l0c0
4393 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004394 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004395 v9.CheckSourceSuccess(lines)
4396
4397 # Check islocked class/object from various places.
4398 lines =<< trim END
4399 vim9script
4400
4401 class C
4402 def Islocked(arg: string): number
4403 return islocked(arg)
4404 enddef
4405 static def SIslocked(arg: string): number
4406 return islocked(arg)
4407 enddef
4408 endclass
4409 var obj = C.new()
4410
4411 # object method
4412 assert_equal(0, obj.Islocked("this"))
4413 assert_equal(0, obj.Islocked("C"))
4414
4415 # class method
4416 ### assert_equal(0, C.SIslocked("this"))
4417 assert_equal(0, C.SIslocked("C"))
4418
4419 #script level
4420 var v: number
4421 v = islocked("C")
4422 assert_equal(0, v)
4423 v = islocked("obj")
4424 assert_equal(0, v)
4425 END
4426 v9.CheckSourceSuccess(lines)
4427enddef
4428
4429def Test_lockvar_islocked_notfound()
4430 # Try non-existent things
4431 var lines =<< trim END
4432 vim9script
4433
4434 class C
4435 def Islocked(arg: string): number
4436 return islocked(arg)
4437 enddef
4438 static def SIslocked(arg: string): number
4439 return islocked(arg)
4440 enddef
4441 endclass
4442 var obj = C.new()
4443 assert_equal(-1, obj.Islocked("anywhere"))
4444 assert_equal(-1, C.SIslocked("notanywhere"))
4445 END
4446 v9.CheckSourceSuccess(lines)
4447
4448 # Something not found of the form "name1.name2" is an error
4449 lines =<< trim END
4450 vim9script
4451
4452 islocked("one.two")
4453 END
4454 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4455
4456 lines =<< trim END
4457 vim9script
4458
4459 class C
4460 this.val = { key: "value" }
4461 def Islocked(arg: string): number
4462 return islocked(arg)
4463 enddef
4464 endclass
4465 var obj = C.new()
4466 obj.Islocked("this.val.not_there"))
4467 END
4468 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4469
4470 lines =<< trim END
4471 vim9script
4472
4473 class C
4474 def Islocked(arg: string): number
4475 return islocked(arg)
4476 enddef
4477 endclass
4478 var obj = C.new()
4479 obj.Islocked("this.notobjmember")
4480 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004481 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004482
4483 # access a script variable through methods
4484 lines =<< trim END
4485 vim9script
4486
4487 var l = [1]
4488 class C
4489 def Islocked(arg: string): number
4490 return islocked(arg)
4491 enddef
4492 static def SIslocked(arg: string): number
4493 return islocked(arg)
4494 enddef
4495 endclass
4496 var obj = C.new()
4497 assert_equal(0, obj.Islocked("l"))
4498 assert_equal(0, C.SIslocked("l"))
4499 lockvar l
4500 assert_equal(1, obj.Islocked("l"))
4501 assert_equal(1, C.SIslocked("l"))
4502 END
4503 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004504enddef
4505
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004506" Test for a private object method
4507def Test_private_object_method()
4508 # Try calling a private method using an object (at the script level)
4509 var lines =<< trim END
4510 vim9script
4511
4512 class A
4513 def _Foo(): number
4514 return 1234
4515 enddef
4516 endclass
4517 var a = A.new()
4518 a._Foo()
4519 END
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02004520 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004521
4522 # Try calling a private method using an object (from a def function)
4523 lines =<< trim END
4524 vim9script
4525
4526 class A
4527 def _Foo(): number
4528 return 1234
4529 enddef
4530 endclass
4531 def T()
4532 var a = A.new()
4533 a._Foo()
4534 enddef
4535 T()
4536 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004537 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004538
4539 # Use a private method from another object method (in script context)
4540 lines =<< trim END
4541 vim9script
4542
4543 class A
4544 def _Foo(): number
4545 return 1234
4546 enddef
4547 def Bar(): number
4548 return this._Foo()
4549 enddef
4550 endclass
4551 var a = A.new()
4552 assert_equal(1234, a.Bar())
4553 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004554 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004555
4556 # Use a private method from another object method (def function context)
4557 lines =<< trim END
4558 vim9script
4559
4560 class A
4561 def _Foo(): number
4562 return 1234
4563 enddef
4564 def Bar(): number
4565 return this._Foo()
4566 enddef
4567 endclass
4568 def T()
4569 var a = A.new()
4570 assert_equal(1234, a.Bar())
4571 enddef
4572 T()
4573 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004574 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004575
4576 # Try calling a private method without the "this" prefix
4577 lines =<< trim END
4578 vim9script
4579
4580 class A
4581 def _Foo(): number
4582 return 1234
4583 enddef
4584 def Bar(): number
4585 return _Foo()
4586 enddef
4587 endclass
4588 var a = A.new()
4589 a.Bar()
4590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004591 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004592
4593 # Try calling a private method using the class name
4594 lines =<< trim END
4595 vim9script
4596
4597 class A
4598 def _Foo(): number
4599 return 1234
4600 enddef
4601 endclass
4602 A._Foo()
4603 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004604 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004605
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004606 # Define two private methods with the same name
4607 lines =<< trim END
4608 vim9script
4609
4610 class A
4611 def _Foo()
4612 enddef
4613 def _Foo()
4614 enddef
4615 endclass
4616 var a = A.new()
4617 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004618 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004619
4620 # Define a private method and a object method with the same name
4621 lines =<< trim END
4622 vim9script
4623
4624 class A
4625 def _Foo()
4626 enddef
4627 def Foo()
4628 enddef
4629 endclass
4630 var a = A.new()
4631 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004632 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004633
4634 # Define an object method and a private method with the same name
4635 lines =<< trim END
4636 vim9script
4637
4638 class A
4639 def Foo()
4640 enddef
4641 def _Foo()
4642 enddef
4643 endclass
4644 var a = A.new()
4645 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004646 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004647
4648 # Call a public method and a private method from a private method
4649 lines =<< trim END
4650 vim9script
4651
4652 class A
4653 def Foo(): number
4654 return 100
4655 enddef
4656 def _Bar(): number
4657 return 200
4658 enddef
4659 def _Baz()
4660 assert_equal(100, this.Foo())
4661 assert_equal(200, this._Bar())
4662 enddef
4663 def T()
4664 this._Baz()
4665 enddef
4666 endclass
4667 var a = A.new()
4668 a.T()
4669 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004670 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004671
4672 # Try calling a private method from another class
4673 lines =<< trim END
4674 vim9script
4675
4676 class A
4677 def _Foo(): number
4678 return 100
4679 enddef
4680 endclass
4681 class B
4682 def Foo(): number
4683 var a = A.new()
4684 a._Foo()
4685 enddef
4686 endclass
4687 var b = B.new()
4688 b.Foo()
4689 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004690 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004691
4692 # Call a private object method from a child class object method
4693 lines =<< trim END
4694 vim9script
4695 class A
4696 def _Foo(): number
4697 return 1234
4698 enddef
4699 endclass
4700 class B extends A
4701 def Bar()
4702 enddef
4703 endclass
4704 class C extends B
4705 def Baz(): number
4706 return this._Foo()
4707 enddef
4708 endclass
4709 var c = C.new()
4710 assert_equal(1234, c.Baz())
4711 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004712 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004713
4714 # Call a private object method from a child class object
4715 lines =<< trim END
4716 vim9script
4717 class A
4718 def _Foo(): number
4719 return 1234
4720 enddef
4721 endclass
4722 class B extends A
4723 def Bar()
4724 enddef
4725 endclass
4726 class C extends B
4727 def Baz(): number
4728 enddef
4729 endclass
4730 var c = C.new()
4731 assert_equal(1234, c._Foo())
4732 END
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02004733 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004734
4735 # Using "_" prefix in a method name should fail outside of a class
4736 lines =<< trim END
4737 vim9script
4738 def _Foo(): number
4739 return 1234
4740 enddef
4741 var a = _Foo()
4742 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004743 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004744enddef
4745
4746" Test for an private class method
4747def Test_private_class_method()
4748 # Try calling a class private method (at the script level)
4749 var lines =<< trim END
4750 vim9script
4751
4752 class A
4753 static def _Foo(): number
4754 return 1234
4755 enddef
4756 endclass
4757 A._Foo()
4758 END
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02004759 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004760
4761 # Try calling a class private method (from a def function)
4762 lines =<< trim END
4763 vim9script
4764
4765 class A
4766 static def _Foo(): number
4767 return 1234
4768 enddef
4769 endclass
4770 def T()
4771 A._Foo()
4772 enddef
4773 T()
4774 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004775 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004776
4777 # Try calling a class private method using an object (at the script level)
4778 lines =<< trim END
4779 vim9script
4780
4781 class A
4782 static def _Foo(): number
4783 return 1234
4784 enddef
4785 endclass
4786 var a = A.new()
4787 a._Foo()
4788 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004789 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004790
4791 # Try calling a class private method using an object (from a def function)
4792 lines =<< trim END
4793 vim9script
4794
4795 class A
4796 static def _Foo(): number
4797 return 1234
4798 enddef
4799 endclass
4800 def T()
4801 var a = A.new()
4802 a._Foo()
4803 enddef
4804 T()
4805 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004806 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004807
4808 # Use a class private method from an object method
4809 lines =<< trim END
4810 vim9script
4811
4812 class A
4813 static def _Foo(): number
4814 return 1234
4815 enddef
4816 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004817 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004818 enddef
4819 endclass
4820 var a = A.new()
4821 a.Bar()
4822 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004823 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004824
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004825 # Use a class private method from another class private method without the
4826 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004827 lines =<< trim END
4828 vim9script
4829
4830 class A
4831 static def _Foo1(): number
4832 return 1234
4833 enddef
4834 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004835 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004836 enddef
4837 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004838 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004839 enddef
4840 endclass
4841 var a = A.new()
4842 a.Bar()
4843 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004844 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004845
4846 # Declare a class method and a class private method with the same name
4847 lines =<< trim END
4848 vim9script
4849
4850 class A
4851 static def _Foo()
4852 enddef
4853 static def Foo()
4854 enddef
4855 endclass
4856 var a = A.new()
4857 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004858 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004859
4860 # Try calling a class private method from another class
4861 lines =<< trim END
4862 vim9script
4863
4864 class A
4865 static def _Foo(): number
4866 return 1234
4867 enddef
4868 endclass
4869 class B
4870 def Foo(): number
4871 return A._Foo()
4872 enddef
4873 endclass
4874 var b = B.new()
4875 assert_equal(1234, b.Foo())
4876 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004877 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004878
4879 # Call a private class method from a child class object method
4880 lines =<< trim END
4881 vim9script
4882 class A
4883 static def _Foo(): number
4884 return 1234
4885 enddef
4886 endclass
4887 class B extends A
4888 def Bar()
4889 enddef
4890 endclass
4891 class C extends B
4892 def Baz(): number
4893 return A._Foo()
4894 enddef
4895 endclass
4896 var c = C.new()
4897 assert_equal(1234, c.Baz())
4898 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004899 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004900
4901 # Call a private class method from a child class private class method
4902 lines =<< trim END
4903 vim9script
4904 class A
4905 static def _Foo(): number
4906 return 1234
4907 enddef
4908 endclass
4909 class B extends A
4910 def Bar()
4911 enddef
4912 endclass
4913 class C extends B
4914 static def Baz(): number
4915 return A._Foo()
4916 enddef
4917 endclass
4918 assert_equal(1234, C.Baz())
4919 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004920 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004921
4922 # Call a private class method from a child class object
4923 lines =<< trim END
4924 vim9script
4925 class A
4926 static def _Foo(): number
4927 return 1234
4928 enddef
4929 endclass
4930 class B extends A
4931 def Bar()
4932 enddef
4933 endclass
4934 class C extends B
4935 def Baz(): number
4936 enddef
4937 endclass
4938 var c = C.new()
4939 assert_equal(1234, C._Foo())
4940 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004941 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004942enddef
4943
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004944" Test for using the return value of a class/object method as a function
4945" argument.
4946def Test_objmethod_funcarg()
4947 var lines =<< trim END
4948 vim9script
4949
4950 class C
4951 def Foo(): string
4952 return 'foo'
4953 enddef
4954 endclass
4955
4956 def Bar(a: number, s: string): string
4957 return s
4958 enddef
4959
4960 def Baz(c: C)
4961 assert_equal('foo', Bar(10, c.Foo()))
4962 enddef
4963
4964 var t = C.new()
4965 Baz(t)
4966 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004967 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004968
4969 lines =<< trim END
4970 vim9script
4971
4972 class C
4973 static def Foo(): string
4974 return 'foo'
4975 enddef
4976 endclass
4977
4978 def Bar(a: number, s: string): string
4979 return s
4980 enddef
4981
4982 def Baz()
4983 assert_equal('foo', Bar(10, C.Foo()))
4984 enddef
4985
4986 Baz()
4987 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004988 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004989enddef
4990
Ernie Raelcf138d42023-09-06 20:45:03 +02004991def Test_static_inheritence()
4992 # subclasses get their own static copy
4993 var lines =<< trim END
4994 vim9script
4995
4996 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004997 static _svar: number
4998 this._mvar: number
4999 def new()
5000 _svar = 1
5001 this._mvar = 101
5002 enddef
5003 def AccessObject(): number
5004 return this._mvar
5005 enddef
5006 def AccessStaticThroughObject(): number
5007 return _svar
5008 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005009 endclass
5010
5011 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005012 def new()
5013 this._mvar = 102
5014 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005015 endclass
5016
5017 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005018 def new()
5019 this._mvar = 103
5020 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005022 def AccessPrivateStaticThroughClassName(): number
5023 assert_equal(1, A._svar)
5024 return 444
5025 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005026 endclass
5027
5028 var oa = A.new()
5029 var ob = B.new()
5030 var oc = C.new()
5031 assert_equal(101, oa.AccessObject())
5032 assert_equal(102, ob.AccessObject())
5033 assert_equal(103, oc.AccessObject())
5034
Ernie Rael64885642023-10-04 20:16:22 +02005035 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005036
5037 # verify object properly resolves to correct static
5038 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005039 assert_equal(1, ob.AccessStaticThroughObject())
5040 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005041 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005042 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005043enddef
5044
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005045" Test for declaring duplicate object and class members
5046def Test_dup_member_variable()
5047 # Duplicate member variable
5048 var lines =<< trim END
5049 vim9script
5050 class C
5051 this.val = 10
5052 this.val = 20
5053 endclass
5054 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005055 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005056
5057 # Duplicate private member variable
5058 lines =<< trim END
5059 vim9script
5060 class C
5061 this._val = 10
5062 this._val = 20
5063 endclass
5064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005065 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005066
5067 # Duplicate public member variable
5068 lines =<< trim END
5069 vim9script
5070 class C
5071 public this.val = 10
5072 public this.val = 20
5073 endclass
5074 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005075 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005076
5077 # Duplicate private member variable
5078 lines =<< trim END
5079 vim9script
5080 class C
5081 this.val = 10
5082 this._val = 20
5083 endclass
5084 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005085 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005086
5087 # Duplicate public and private member variable
5088 lines =<< trim END
5089 vim9script
5090 class C
5091 this._val = 20
5092 public this.val = 10
5093 endclass
5094 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005095 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005096
5097 # Duplicate class member variable
5098 lines =<< trim END
5099 vim9script
5100 class C
5101 static s: string = "abc"
5102 static _s: string = "def"
5103 endclass
5104 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005105 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005106
5107 # Duplicate public and private class member variable
5108 lines =<< trim END
5109 vim9script
5110 class C
5111 public static s: string = "abc"
5112 static _s: string = "def"
5113 endclass
5114 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005115 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005116
5117 # Duplicate class and object member variable
5118 lines =<< trim END
5119 vim9script
5120 class C
5121 static val = 10
5122 this.val = 20
5123 def new()
5124 enddef
5125 endclass
5126 var c = C.new()
5127 assert_equal(10, C.val)
5128 assert_equal(20, c.val)
5129 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005130 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005131
5132 # Duplicate object member variable in a derived class
5133 lines =<< trim END
5134 vim9script
5135 class A
5136 this.val = 10
5137 endclass
5138 class B extends A
5139 endclass
5140 class C extends B
5141 this.val = 20
5142 endclass
5143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005144 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005145
5146 # Duplicate object private member variable in a derived class
5147 lines =<< trim END
5148 vim9script
5149 class A
5150 this._val = 10
5151 endclass
5152 class B extends A
5153 endclass
5154 class C extends B
5155 this._val = 20
5156 endclass
5157 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005158 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005159
5160 # Duplicate object private member variable in a derived class
5161 lines =<< trim END
5162 vim9script
5163 class A
5164 this.val = 10
5165 endclass
5166 class B extends A
5167 endclass
5168 class C extends B
5169 this._val = 20
5170 endclass
5171 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005172 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005173
5174 # Duplicate object member variable in a derived class
5175 lines =<< trim END
5176 vim9script
5177 class A
5178 this._val = 10
5179 endclass
5180 class B extends A
5181 endclass
5182 class C extends B
5183 this.val = 20
5184 endclass
5185 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005186 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005187
5188 # Two member variables with a common prefix
5189 lines =<< trim END
5190 vim9script
5191 class A
5192 public static svar2: number
5193 public static svar: number
5194 endclass
5195 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005196 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005197enddef
5198
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005199" Test for accessing a private member outside a class in a def function
5200def Test_private_member_access_outside_class()
5201 # private object member variable
5202 var lines =<< trim END
5203 vim9script
5204 class A
5205 this._val = 10
5206 def GetVal(): number
5207 return this._val
5208 enddef
5209 endclass
5210 def T()
5211 var a = A.new()
5212 a._val = 20
5213 enddef
5214 T()
5215 END
Ernie Rael64885642023-10-04 20:16:22 +02005216 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005217
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005218 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005219 lines =<< trim END
5220 vim9script
5221 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005222 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005223 endclass
5224 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005225 var a = A.new()
5226 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005227 enddef
5228 T()
5229 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005230 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005231
5232 # private static member variable
5233 lines =<< trim END
5234 vim9script
5235 class A
5236 static _val = 10
5237 endclass
5238 def T()
5239 var a = A.new()
5240 var x = a._val
5241 enddef
5242 T()
5243 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005244 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005245
5246 # private static member variable
5247 lines =<< trim END
5248 vim9script
5249 class A
5250 static _val = 10
5251 endclass
5252 def T()
5253 var a = A.new()
5254 a._val = 3
5255 enddef
5256 T()
5257 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005258 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005259
5260 # private static class variable
5261 lines =<< trim END
5262 vim9script
5263 class A
5264 static _val = 10
5265 endclass
5266 def T()
5267 var x = A._val
5268 enddef
5269 T()
5270 END
Ernie Rael64885642023-10-04 20:16:22 +02005271 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005272
5273 # private static class variable
5274 lines =<< trim END
5275 vim9script
5276 class A
5277 static _val = 10
5278 endclass
5279 def T()
5280 A._val = 3
5281 enddef
5282 T()
5283 END
Ernie Rael64885642023-10-04 20:16:22 +02005284 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005285enddef
5286
5287" Test for changing the member access of an interface in a implementation class
5288def Test_change_interface_member_access()
5289 var lines =<< trim END
5290 vim9script
5291 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005292 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005293 endinterface
5294 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005295 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005296 endclass
5297 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005298 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005299
5300 lines =<< trim END
5301 vim9script
5302 interface A
5303 this.val: number
5304 endinterface
5305 class B implements A
5306 public this.val = 10
5307 endclass
5308 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005309 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005310enddef
5311
5312" Test for trying to change a readonly member from a def function
5313def Test_readonly_member_change_in_def_func()
5314 var lines =<< trim END
5315 vim9script
5316 class A
5317 this.val: number
5318 endclass
5319 def T()
5320 var a = A.new()
5321 a.val = 20
5322 enddef
5323 T()
5324 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005325 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005326enddef
5327
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005328" Test for reading and writing a class member from a def function
5329def Test_modify_class_member_from_def_function()
5330 var lines =<< trim END
5331 vim9script
5332 class A
5333 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005334 public static var2: list<number> = [1, 2]
5335 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005336 static _priv_var4: number = 40
5337 endclass
5338 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005339 assert_equal([1, 2], A.var2)
5340 assert_equal({a: 1, b: 2}, A.var3)
5341 A.var2 = [3, 4]
5342 A.var3 = {c: 3, d: 4}
5343 assert_equal([3, 4], A.var2)
5344 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael64885642023-10-04 20:16:22 +02005345 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005346 enddef
5347 T()
5348 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005349 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005350enddef
5351
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005352" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005353def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005354 var lines =<< trim END
5355 vim9script
5356 class A
5357 public static svar1: list<number> = [1]
5358 public static svar2: list<number> = [2]
5359 endclass
5360
5361 A.svar1->add(3)
5362 A.svar2->add(4)
5363 assert_equal([1, 3], A.svar1)
5364 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005365
5366 def Foo()
5367 A.svar1->add(7)
5368 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005369 assert_equal([1, 3, 7], A.svar1)
5370 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005371 enddef
5372 Foo()
5373 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005374 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005375
5376 # Cannot read from a class variable using an object in script context
5377 lines =<< trim END
5378 vim9script
5379 class A
5380 public this.var1: number
5381 public static svar2: list<number> = [1]
5382 endclass
5383
5384 var a = A.new()
5385 echo a.svar2
5386 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005387 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005388
5389 # Cannot write to a class variable using an object in script context
5390 lines =<< trim END
5391 vim9script
5392 class A
5393 public this.var1: number
5394 public static svar2: list<number> = [1]
5395 endclass
5396
5397 var a = A.new()
5398 a.svar2 = [2]
5399 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005400 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005401
5402 # Cannot read from a class variable using an object in def method context
5403 lines =<< trim END
5404 vim9script
5405 class A
5406 public this.var1: number
5407 public static svar2: list<number> = [1]
5408 endclass
5409
5410 def T()
5411 var a = A.new()
5412 echo a.svar2
5413 enddef
5414 T()
5415 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005416 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005417
5418 # Cannot write to a class variable using an object in def method context
5419 lines =<< trim END
5420 vim9script
5421 class A
5422 public this.var1: number
5423 public static svar2: list<number> = [1]
5424 endclass
5425
5426 def T()
5427 var a = A.new()
5428 a.svar2 = [2]
5429 enddef
5430 T()
5431 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005432 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005433enddef
5434
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005435" Test for using a interface method using a child object
5436def Test_interface_method_from_child()
5437 var lines =<< trim END
5438 vim9script
5439
5440 interface A
5441 def Foo(): string
5442 endinterface
5443
5444 class B implements A
5445 def Foo(): string
5446 return 'foo'
5447 enddef
5448 endclass
5449
5450 class C extends B
5451 def Bar(): string
5452 return 'bar'
5453 enddef
5454 endclass
5455
5456 def T1(a: A)
5457 assert_equal('foo', a.Foo())
5458 enddef
5459
5460 def T2(b: B)
5461 assert_equal('foo', b.Foo())
5462 enddef
5463
5464 var c = C.new()
5465 T1(c)
5466 T2(c)
5467 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005468 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005469enddef
5470
5471" Test for using an interface method using a child object when it is overridden
5472" by the child class.
5473" FIXME: This test fails.
5474" def Test_interface_overridden_method_from_child()
5475" var lines =<< trim END
5476" vim9script
5477"
5478" interface A
5479" def Foo(): string
5480" endinterface
5481"
5482" class B implements A
5483" def Foo(): string
5484" return 'b-foo'
5485" enddef
5486" endclass
5487"
5488" class C extends B
5489" def Bar(): string
5490" return 'bar'
5491" enddef
5492" def Foo(): string
5493" return 'c-foo'
5494" enddef
5495" endclass
5496"
5497" def T1(a: A)
5498" assert_equal('c-foo', a.Foo())
5499" enddef
5500"
5501" def T2(b: B)
5502" assert_equal('c-foo', b.Foo())
5503" enddef
5504"
5505" var c = C.new()
5506" T1(c)
5507" T2(c)
5508" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005509" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005510" enddef
5511
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005512" Test for abstract methods
5513def Test_abstract_method()
5514 # Use two abstract methods
5515 var lines =<< trim END
5516 vim9script
5517 abstract class A
5518 def M1(): number
5519 return 10
5520 enddef
5521 abstract def M2(): number
5522 abstract def M3(): number
5523 endclass
5524 class B extends A
5525 def M2(): number
5526 return 20
5527 enddef
5528 def M3(): number
5529 return 30
5530 enddef
5531 endclass
5532 var b = B.new()
5533 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5534 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005535 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005536
5537 # Don't define an abstract method
5538 lines =<< trim END
5539 vim9script
5540 abstract class A
5541 abstract def Foo()
5542 endclass
5543 class B extends A
5544 endclass
5545 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005546 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005547
5548 # Use abstract method in a concrete class
5549 lines =<< trim END
5550 vim9script
5551 class A
5552 abstract def Foo()
5553 endclass
5554 class B extends A
5555 endclass
5556 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005557 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005558
5559 # Use abstract method in an interface
5560 lines =<< trim END
5561 vim9script
5562 interface A
5563 abstract def Foo()
5564 endinterface
5565 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005566 def Foo()
5567 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005568 endclass
5569 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005570 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005571
5572 # Abbreviate the "abstract" keyword
5573 lines =<< trim END
5574 vim9script
5575 class A
5576 abs def Foo()
5577 endclass
5578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005579 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005580
5581 # Use "abstract" with a member variable
5582 lines =<< trim END
5583 vim9script
5584 abstract class A
5585 abstract this.val = 10
5586 endclass
5587 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005588 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005589
5590 # Use a static abstract method
5591 lines =<< trim END
5592 vim9script
5593 abstract class A
5594 abstract static def Foo(): number
5595 endclass
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005596 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005597 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005598
5599 # Type mismatch between abstract method and concrete method
5600 lines =<< trim END
5601 vim9script
5602 abstract class A
5603 abstract def Foo(a: string, b: number): list<number>
5604 endclass
5605 class B extends A
5606 def Foo(a: number, b: string): list<string>
5607 return []
5608 enddef
5609 endclass
5610 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005611 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 +02005612
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005613 # Invoke an abstract method from a def function
5614 lines =<< trim END
5615 vim9script
5616 abstract class A
5617 abstract def Foo(): list<number>
5618 endclass
5619 class B extends A
5620 def Foo(): list<number>
5621 return [3, 5]
5622 enddef
5623 endclass
5624 def Bar(c: B)
5625 assert_equal([3, 5], c.Foo())
5626 enddef
5627 var b = B.new()
5628 Bar(b)
5629 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005630 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005631
5632 # Use a static method in an abstract class
5633 lines =<< trim END
5634 vim9script
5635 abstract class A
5636 static def Foo(): string
5637 return 'foo'
5638 enddef
5639 endclass
5640 assert_equal('foo', A.Foo())
5641 END
5642 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005643enddef
5644
5645" Test for calling a class method from a subclass
5646def Test_class_method_call_from_subclass()
5647 # class method call from a subclass
5648 var lines =<< trim END
5649 vim9script
5650
5651 class A
5652 static def Foo()
5653 echo "foo"
5654 enddef
5655 endclass
5656
5657 class B extends A
5658 def Bar()
5659 Foo()
5660 enddef
5661 endclass
5662
5663 var b = B.new()
5664 b.Bar()
5665 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005666 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005667enddef
5668
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005669" Test for calling a class method using an object in a def function context and
5670" script context.
5671def Test_class_method_call_using_object()
5672 # script context
5673 var lines =<< trim END
5674 vim9script
5675 class A
5676 static def Foo(): list<string>
5677 return ['a', 'b']
5678 enddef
5679 def Bar()
5680 assert_equal(['a', 'b'], A.Foo())
5681 assert_equal(['a', 'b'], Foo())
5682 enddef
5683 endclass
5684
5685 def T()
5686 assert_equal(['a', 'b'], A.Foo())
5687 var t_a = A.new()
5688 t_a.Bar()
5689 enddef
5690
5691 assert_equal(['a', 'b'], A.Foo())
5692 var a = A.new()
5693 a.Bar()
5694 T()
5695 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005696 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005697
5698 # script context
5699 lines =<< trim END
5700 vim9script
5701 class A
5702 static def Foo(): string
5703 return 'foo'
5704 enddef
5705 endclass
5706
5707 var a = A.new()
5708 assert_equal('foo', a.Foo())
5709 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005710 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005711
5712 # def function context
5713 lines =<< trim END
5714 vim9script
5715 class A
5716 static def Foo(): string
5717 return 'foo'
5718 enddef
5719 endclass
5720
5721 def T()
5722 var a = A.new()
5723 assert_equal('foo', a.Foo())
5724 enddef
5725 T()
5726 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005727 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005728enddef
5729
5730def Test_class_variable()
5731 var lines =<< trim END
5732 vim9script
5733
5734 class A
5735 public static val: number = 10
5736 static def ClassFunc()
5737 assert_equal(10, val)
5738 enddef
5739 def ObjFunc()
5740 assert_equal(10, val)
5741 enddef
5742 endclass
5743
5744 class B extends A
5745 endclass
5746
5747 assert_equal(10, A.val)
5748 A.ClassFunc()
5749 var a = A.new()
5750 a.ObjFunc()
5751 var b = B.new()
5752 b.ObjFunc()
5753
5754 def T1(a1: A)
5755 a1.ObjFunc()
5756 A.ClassFunc()
5757 enddef
5758 T1(b)
5759
5760 A.val = 20
5761 assert_equal(20, A.val)
5762 END
5763 v9.CheckSourceSuccess(lines)
5764
5765 # Modifying a parent class variable from a child class method
5766 lines =<< trim END
5767 vim9script
5768
5769 class A
5770 static val: number = 10
5771 endclass
5772
5773 class B extends A
5774 static def ClassFunc()
5775 val = 20
5776 enddef
5777 endclass
5778 B.ClassFunc()
5779 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005780 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005781
5782 # Reading a parent class variable from a child class method
5783 lines =<< trim END
5784 vim9script
5785
5786 class A
5787 static val: number = 10
5788 endclass
5789
5790 class B extends A
5791 static def ClassFunc()
5792 var i = val
5793 enddef
5794 endclass
5795 B.ClassFunc()
5796 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005797 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005798
5799 # Modifying a parent class variable from a child object method
5800 lines =<< trim END
5801 vim9script
5802
5803 class A
5804 static val: number = 10
5805 endclass
5806
5807 class B extends A
5808 def ObjFunc()
5809 val = 20
5810 enddef
5811 endclass
5812 var b = B.new()
5813 b.ObjFunc()
5814 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005815 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005816
5817 # Reading a parent class variable from a child object method
5818 lines =<< trim END
5819 vim9script
5820
5821 class A
5822 static val: number = 10
5823 endclass
5824
5825 class B extends A
5826 def ObjFunc()
5827 var i = val
5828 enddef
5829 endclass
5830 var b = B.new()
5831 b.ObjFunc()
5832 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005833 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005834
5835 # Modifying a class variable using an object at script level
5836 lines =<< trim END
5837 vim9script
5838
5839 class A
5840 static val: number = 10
5841 endclass
5842 var a = A.new()
5843 a.val = 20
5844 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005845 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005846
5847 # Reading a class variable using an object at script level
5848 lines =<< trim END
5849 vim9script
5850
5851 class A
5852 static val: number = 10
5853 endclass
5854 var a = A.new()
5855 var i = a.val
5856 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005857 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005858
5859 # Modifying a class variable using an object at function level
5860 lines =<< trim END
5861 vim9script
5862
5863 class A
5864 static val: number = 10
5865 endclass
5866
5867 def T()
5868 var a = A.new()
5869 a.val = 20
5870 enddef
5871 T()
5872 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005873 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005874
5875 # Reading a class variable using an object at function level
5876 lines =<< trim END
5877 vim9script
5878
5879 class A
5880 static val: number = 10
5881 endclass
5882 def T()
5883 var a = A.new()
5884 var i = a.val
5885 enddef
5886 T()
5887 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005888 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005889enddef
5890
5891" Test for using a duplicate class method and class variable in a child class
5892def Test_dup_class_member()
5893 # duplicate class variable, class method and overridden object method
5894 var lines =<< trim END
5895 vim9script
5896 class A
5897 static sval = 100
5898 static def Check()
5899 assert_equal(100, sval)
5900 enddef
5901 def GetVal(): number
5902 return sval
5903 enddef
5904 endclass
5905
5906 class B extends A
5907 static sval = 200
5908 static def Check()
5909 assert_equal(200, sval)
5910 enddef
5911 def GetVal(): number
5912 return sval
5913 enddef
5914 endclass
5915
5916 def T1(aa: A): number
5917 return aa.GetVal()
5918 enddef
5919
5920 def T2(bb: B): number
5921 return bb.GetVal()
5922 enddef
5923
5924 assert_equal(100, A.sval)
5925 assert_equal(200, B.sval)
5926 var a = A.new()
5927 assert_equal(100, a.GetVal())
5928 var b = B.new()
5929 assert_equal(200, b.GetVal())
5930 assert_equal(200, T1(b))
5931 assert_equal(200, T2(b))
5932 END
5933 v9.CheckSourceSuccess(lines)
5934
5935 # duplicate class variable and class method
5936 lines =<< trim END
5937 vim9script
5938 class A
5939 static sval = 100
5940 static def Check()
5941 assert_equal(100, sval)
5942 enddef
5943 def GetVal(): number
5944 return sval
5945 enddef
5946 endclass
5947
5948 class B extends A
5949 static sval = 200
5950 static def Check()
5951 assert_equal(200, sval)
5952 enddef
5953 endclass
5954
5955 def T1(aa: A): number
5956 return aa.GetVal()
5957 enddef
5958
5959 def T2(bb: B): number
5960 return bb.GetVal()
5961 enddef
5962
5963 assert_equal(100, A.sval)
5964 assert_equal(200, B.sval)
5965 var a = A.new()
5966 assert_equal(100, a.GetVal())
5967 var b = B.new()
5968 assert_equal(100, b.GetVal())
5969 assert_equal(100, T1(b))
5970 assert_equal(100, T2(b))
5971 END
5972 v9.CheckSourceSuccess(lines)
5973enddef
5974
5975" Test for calling an instance method using the class
5976def Test_instance_method_call_using_class()
5977 # Invoke an object method using a class in script context
5978 var lines =<< trim END
5979 vim9script
5980 class A
5981 def Foo()
5982 echo "foo"
5983 enddef
5984 endclass
5985 A.Foo()
5986 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005987 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005988
5989 # Invoke an object method using a class in def function context
5990 lines =<< trim END
5991 vim9script
5992 class A
5993 def Foo()
5994 echo "foo"
5995 enddef
5996 endclass
5997 def T()
5998 A.Foo()
5999 enddef
6000 T()
6001 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006002 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006003enddef
6004
6005" Test for duplicate class method and instance method
6006def Test_dup_classmethod_objmethod()
6007 # Duplicate instance method
6008 var lines =<< trim END
6009 vim9script
6010 class A
6011 static def Foo()
6012 enddef
6013 def Foo()
6014 enddef
6015 endclass
6016 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006017 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006018
6019 # Duplicate private instance method
6020 lines =<< trim END
6021 vim9script
6022 class A
6023 static def Foo()
6024 enddef
6025 def _Foo()
6026 enddef
6027 endclass
6028 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006029 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006030
6031 # Duplicate class method
6032 lines =<< trim END
6033 vim9script
6034 class A
6035 def Foo()
6036 enddef
6037 static def Foo()
6038 enddef
6039 endclass
6040 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006041 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006042
6043 # Duplicate private class method
6044 lines =<< trim END
6045 vim9script
6046 class A
6047 def Foo()
6048 enddef
6049 static def _Foo()
6050 enddef
6051 endclass
6052 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006053 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006054
6055 # Duplicate private class and object method
6056 lines =<< trim END
6057 vim9script
6058 class A
6059 def _Foo()
6060 enddef
6061 static def _Foo()
6062 enddef
6063 endclass
6064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006065 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006066enddef
6067
6068" Test for an instance method access level comparison with parent instance
6069" methods.
6070def Test_instance_method_access_level()
6071 # Private method in subclass
6072 var lines =<< trim END
6073 vim9script
6074 class A
6075 def Foo()
6076 enddef
6077 endclass
6078 class B extends A
6079 endclass
6080 class C extends B
6081 def _Foo()
6082 enddef
6083 endclass
6084 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006085 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006086
6087 # Public method in subclass
6088 lines =<< trim END
6089 vim9script
6090 class A
6091 def _Foo()
6092 enddef
6093 endclass
6094 class B extends A
6095 endclass
6096 class C extends B
6097 def Foo()
6098 enddef
6099 endclass
6100 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006101 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006102enddef
6103
6104def Test_extend_empty_class()
6105 var lines =<< trim END
6106 vim9script
6107 class A
6108 endclass
6109 class B extends A
6110 endclass
6111 class C extends B
6112 public static rw_class_var = 1
6113 public this.rw_obj_var = 2
6114 static def ClassMethod(): number
6115 return 3
6116 enddef
6117 def ObjMethod(): number
6118 return 4
6119 enddef
6120 endclass
6121 assert_equal(1, C.rw_class_var)
6122 assert_equal(3, C.ClassMethod())
6123 var c = C.new()
6124 assert_equal(2, c.rw_obj_var)
6125 assert_equal(4, c.ObjMethod())
6126 END
6127 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006128enddef
6129
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006130" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006131" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006132def Test_interface_with_unsupported_members()
6133 var lines =<< trim END
6134 vim9script
6135 interface A
6136 static num: number
6137 endinterface
6138 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006139 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006140
6141 lines =<< trim END
6142 vim9script
6143 interface A
6144 static _num: number
6145 endinterface
6146 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006147 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006148
6149 lines =<< trim END
6150 vim9script
6151 interface A
6152 public static num: number
6153 endinterface
6154 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006155 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006156
6157 lines =<< trim END
6158 vim9script
6159 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006160 public static num: number
6161 endinterface
6162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006163 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006164
6165 lines =<< trim END
6166 vim9script
6167 interface A
6168 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006169 endinterface
6170 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006171 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006172
6173 lines =<< trim END
6174 vim9script
6175 interface A
6176 static def Foo(d: dict<any>): list<string>
6177 endinterface
6178 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006179 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006180
6181 lines =<< trim END
6182 vim9script
6183 interface A
6184 static def _Foo(d: dict<any>): list<string>
6185 endinterface
6186 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006187 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006188
6189 lines =<< trim END
6190 vim9script
6191 interface A
6192 this._Foo: list<string>
6193 endinterface
6194 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006195 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006196
6197 lines =<< trim END
6198 vim9script
6199 interface A
6200 def _Foo(d: dict<any>): list<string>
6201 endinterface
6202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006203 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006204enddef
6205
6206" Test for extending an interface
6207def Test_extend_interface()
6208 var lines =<< trim END
6209 vim9script
6210 interface A
6211 this.var1: list<string>
6212 def Foo()
6213 endinterface
6214 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006215 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006216 def Bar()
6217 endinterface
6218 class C implements A, B
6219 this.var1 = [1, 2]
6220 def Foo()
6221 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006222 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006223 def Bar()
6224 enddef
6225 endclass
6226 END
6227 v9.CheckSourceSuccess(lines)
6228
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006229 # extending empty interface
6230 lines =<< trim END
6231 vim9script
6232 interface A
6233 endinterface
6234 interface B extends A
6235 endinterface
6236 class C implements B
6237 endclass
6238 END
6239 v9.CheckSourceSuccess(lines)
6240
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006241 lines =<< trim END
6242 vim9script
6243 interface A
6244 def Foo()
6245 endinterface
6246 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006247 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006248 endinterface
6249 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006250 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006251 endclass
6252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006253 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006254
6255 lines =<< trim END
6256 vim9script
6257 interface A
6258 def Foo()
6259 endinterface
6260 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006261 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006262 endinterface
6263 class C implements A, B
6264 def Foo()
6265 enddef
6266 endclass
6267 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006268 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006269
6270 # interface cannot extend a class
6271 lines =<< trim END
6272 vim9script
6273 class A
6274 endclass
6275 interface B extends A
6276 endinterface
6277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006278 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006279
6280 # class cannot extend an interface
6281 lines =<< trim END
6282 vim9script
6283 interface A
6284 endinterface
6285 class B extends A
6286 endclass
6287 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006288 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006289
6290 # interface cannot implement another interface
6291 lines =<< trim END
6292 vim9script
6293 interface A
6294 endinterface
6295 interface B implements A
6296 endinterface
6297 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006298 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006299
6300 # interface cannot extend multiple interfaces
6301 lines =<< trim END
6302 vim9script
6303 interface A
6304 endinterface
6305 interface B
6306 endinterface
6307 interface C extends A, B
6308 endinterface
6309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006310 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006311
6312 # Variable type in an extended interface is of different type
6313 lines =<< trim END
6314 vim9script
6315 interface A
6316 this.val1: number
6317 endinterface
6318 interface B extends A
6319 this.val2: string
6320 endinterface
6321 interface C extends B
6322 this.val1: string
6323 this.val2: number
6324 endinterface
6325 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006326 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006327enddef
6328
6329" Test for a child class implementing an interface when some of the methods are
6330" defined in the parent class.
6331def Test_child_class_implements_interface()
6332 var lines =<< trim END
6333 vim9script
6334
6335 interface Intf
6336 def F1(): list<list<number>>
6337 def F2(): list<list<number>>
6338 def F3(): list<list<number>>
6339 this.var1: list<dict<number>>
6340 this.var2: list<dict<number>>
6341 this.var3: list<dict<number>>
6342 endinterface
6343
6344 class A
6345 def A1()
6346 enddef
6347 def F3(): list<list<number>>
6348 return [[3]]
6349 enddef
6350 this.v1: list<list<number>> = [[0]]
6351 this.var3 = [{c: 30}]
6352 endclass
6353
6354 class B extends A
6355 def B1()
6356 enddef
6357 def F2(): list<list<number>>
6358 return [[2]]
6359 enddef
6360 this.v2: list<list<number>> = [[0]]
6361 this.var2 = [{b: 20}]
6362 endclass
6363
6364 class C extends B implements Intf
6365 def C1()
6366 enddef
6367 def F1(): list<list<number>>
6368 return [[1]]
6369 enddef
6370 this.v3: list<list<number>> = [[0]]
6371 this.var1 = [{a: 10}]
6372 endclass
6373
6374 def T(if: Intf)
6375 assert_equal([[1]], if.F1())
6376 assert_equal([[2]], if.F2())
6377 assert_equal([[3]], if.F3())
6378 assert_equal([{a: 10}], if.var1)
6379 assert_equal([{b: 20}], if.var2)
6380 assert_equal([{c: 30}], if.var3)
6381 enddef
6382
6383 var c = C.new()
6384 T(c)
6385 assert_equal([[1]], c.F1())
6386 assert_equal([[2]], c.F2())
6387 assert_equal([[3]], c.F3())
6388 assert_equal([{a: 10}], c.var1)
6389 assert_equal([{b: 20}], c.var2)
6390 assert_equal([{c: 30}], c.var3)
6391 END
6392 v9.CheckSourceSuccess(lines)
6393
6394 # One of the interface methods is not found
6395 lines =<< trim END
6396 vim9script
6397
6398 interface Intf
6399 def F1()
6400 def F2()
6401 def F3()
6402 endinterface
6403
6404 class A
6405 def A1()
6406 enddef
6407 endclass
6408
6409 class B extends A
6410 def B1()
6411 enddef
6412 def F2()
6413 enddef
6414 endclass
6415
6416 class C extends B implements Intf
6417 def C1()
6418 enddef
6419 def F1()
6420 enddef
6421 endclass
6422 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006423 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006424
6425 # One of the interface methods is of different type
6426 lines =<< trim END
6427 vim9script
6428
6429 interface Intf
6430 def F1()
6431 def F2()
6432 def F3()
6433 endinterface
6434
6435 class A
6436 def F3(): number
6437 return 0
6438 enddef
6439 def A1()
6440 enddef
6441 endclass
6442
6443 class B extends A
6444 def B1()
6445 enddef
6446 def F2()
6447 enddef
6448 endclass
6449
6450 class C extends B implements Intf
6451 def C1()
6452 enddef
6453 def F1()
6454 enddef
6455 endclass
6456 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006457 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006458
6459 # One of the interface variables is not present
6460 lines =<< trim END
6461 vim9script
6462
6463 interface Intf
6464 this.var1: list<dict<number>>
6465 this.var2: list<dict<number>>
6466 this.var3: list<dict<number>>
6467 endinterface
6468
6469 class A
6470 this.v1: list<list<number>> = [[0]]
6471 endclass
6472
6473 class B extends A
6474 this.v2: list<list<number>> = [[0]]
6475 this.var2 = [{b: 20}]
6476 endclass
6477
6478 class C extends B implements Intf
6479 this.v3: list<list<number>> = [[0]]
6480 this.var1 = [{a: 10}]
6481 endclass
6482 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006483 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006484
6485 # One of the interface variables is of different type
6486 lines =<< trim END
6487 vim9script
6488
6489 interface Intf
6490 this.var1: list<dict<number>>
6491 this.var2: list<dict<number>>
6492 this.var3: list<dict<number>>
6493 endinterface
6494
6495 class A
6496 this.v1: list<list<number>> = [[0]]
6497 this.var3: list<dict<string>>
6498 endclass
6499
6500 class B extends A
6501 this.v2: list<list<number>> = [[0]]
6502 this.var2 = [{b: 20}]
6503 endclass
6504
6505 class C extends B implements Intf
6506 this.v3: list<list<number>> = [[0]]
6507 this.var1 = [{a: 10}]
6508 endclass
6509 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006510 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 +02006511enddef
6512
6513" Test for extending an interface with duplicate variables and methods
6514def Test_interface_extends_with_dup_members()
6515 var lines =<< trim END
6516 vim9script
6517 interface A
6518 this.n1: number
6519 def Foo1(): number
6520 endinterface
6521 interface B extends A
6522 this.n2: number
6523 this.n1: number
6524 def Foo2(): number
6525 def Foo1(): number
6526 endinterface
6527 class C implements B
6528 this.n1 = 10
6529 this.n2 = 20
6530 def Foo1(): number
6531 return 30
6532 enddef
6533 def Foo2(): number
6534 return 40
6535 enddef
6536 endclass
6537 def T1(a: A)
6538 assert_equal(10, a.n1)
6539 assert_equal(30, a.Foo1())
6540 enddef
6541 def T2(b: B)
6542 assert_equal(10, b.n1)
6543 assert_equal(20, b.n2)
6544 assert_equal(30, b.Foo1())
6545 assert_equal(40, b.Foo2())
6546 enddef
6547 var c = C.new()
6548 T1(c)
6549 T2(c)
6550 END
6551 v9.CheckSourceSuccess(lines)
6552enddef
6553
6554" Test for using "any" type for a variable in a sub-class while it has a
6555" concrete type in the interface
6556def Test_implements_using_var_type_any()
6557 var lines =<< trim END
6558 vim9script
6559 interface A
6560 this.val: list<dict<string>>
6561 endinterface
6562 class B implements A
6563 this.val = [{a: '1'}, {b: '2'}]
6564 endclass
6565 var b = B.new()
6566 assert_equal([{a: '1'}, {b: '2'}], b.val)
6567 END
6568 v9.CheckSourceSuccess(lines)
6569
6570 # initialize instance variable using a different type
6571 lines =<< trim END
6572 vim9script
6573 interface A
6574 this.val: list<dict<string>>
6575 endinterface
6576 class B implements A
6577 this.val = {a: 1, b: 2}
6578 endclass
6579 var b = B.new()
6580 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006581 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006582enddef
6583
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006584" Test for assigning to a member variable in a nested class
6585def Test_nested_object_assignment()
6586 var lines =<< trim END
6587 vim9script
6588
6589 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006590 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006591 endclass
6592
6593 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006594 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006595 endclass
6596
6597 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006598 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006599 endclass
6600
6601 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006602 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006603 endclass
6604
6605 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006606 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006607 enddef
6608
6609 var d = D.new()
6610 T(d)
6611 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006612 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006613enddef
6614
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006615" Test for calling methods using a null object
6616def Test_null_object_method_call()
6617 # Calling a object method using a null object in script context
6618 var lines =<< trim END
6619 vim9script
6620
6621 class C
6622 def Foo()
6623 assert_report('This method should not be executed')
6624 enddef
6625 endclass
6626
6627 var o: C
6628 o.Foo()
6629 END
6630 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6631
6632 # Calling a object method using a null object in def function context
6633 lines =<< trim END
6634 vim9script
6635
6636 class C
6637 def Foo()
6638 assert_report('This method should not be executed')
6639 enddef
6640 endclass
6641
6642 def T()
6643 var o: C
6644 o.Foo()
6645 enddef
6646 T()
6647 END
6648 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6649
6650 # Calling a object method through another class method using a null object in
6651 # script context
6652 lines =<< trim END
6653 vim9script
6654
6655 class C
6656 def Foo()
6657 assert_report('This method should not be executed')
6658 enddef
6659
6660 static def Bar(o_any: any)
6661 var o_typed: C = o_any
6662 o_typed.Foo()
6663 enddef
6664 endclass
6665
6666 var o: C
6667 C.Bar(o)
6668 END
6669 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6670
6671 # Calling a object method through another class method using a null object in
6672 # def function context
6673 lines =<< trim END
6674 vim9script
6675
6676 class C
6677 def Foo()
6678 assert_report('This method should not be executed')
6679 enddef
6680
6681 static def Bar(o_any: any)
6682 var o_typed: C = o_any
6683 o_typed.Foo()
6684 enddef
6685 endclass
6686
6687 def T()
6688 var o: C
6689 C.Bar(o)
6690 enddef
6691 T()
6692 END
6693 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6694enddef
6695
6696" Test for using a dict as an object member
6697def Test_dict_object_member()
6698 var lines =<< trim END
6699 vim9script
6700
6701 class Context
6702 public this.state: dict<number> = {}
6703 def GetState(): dict<number>
6704 return this.state
6705 enddef
6706 endclass
6707
6708 var ctx = Context.new()
6709 ctx.state->extend({a: 1})
6710 ctx.state['b'] = 2
6711 assert_equal({a: 1, b: 2}, ctx.GetState())
6712
6713 def F()
6714 ctx.state['c'] = 3
6715 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6716 enddef
6717 F()
6718 assert_equal(3, ctx.state.c)
6719 ctx.state.c = 4
6720 assert_equal(4, ctx.state.c)
6721 END
6722 v9.CheckSourceSuccess(lines)
6723enddef
6724
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006725" The following test was failing after 9.0.1914. This was caused by using a
6726" freed object from a previous method call.
6727def Test_freed_object_from_previous_method_call()
6728 var lines =<< trim END
6729 vim9script
6730
6731 class Context
6732 endclass
6733
6734 class Result
6735 endclass
6736
6737 def Failure(): Result
6738 return Result.new()
6739 enddef
6740
6741 def GetResult(ctx: Context): Result
6742 return Failure()
6743 enddef
6744
6745 def Test_GetResult()
6746 var ctx = Context.new()
6747 var result = GetResult(ctx)
6748 enddef
6749
6750 Test_GetResult()
6751 END
6752 v9.CheckSourceSuccess(lines)
6753enddef
6754
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006755" Test for duplicate object and class variable
6756def Test_duplicate_variable()
6757 # Object variable name is same as the class variable name
6758 var lines =<< trim END
6759 vim9script
6760 class A
6761 public static sval: number
6762 public this.sval: number
6763 endclass
6764 var a = A.new()
6765 END
6766 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6767
6768 # Duplicate variable name and calling a class method
6769 lines =<< trim END
6770 vim9script
6771 class A
6772 public static sval: number
6773 public this.sval: number
6774 def F1()
6775 echo this.sval
6776 enddef
6777 static def F2()
6778 echo sval
6779 enddef
6780 endclass
6781 A.F2()
6782 END
6783 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6784
6785 # Duplicate variable with an empty constructor
6786 lines =<< trim END
6787 vim9script
6788 class A
6789 public static sval: number
6790 public this.sval: number
6791 def new()
6792 enddef
6793 endclass
6794 var a = A.new()
6795 END
6796 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6797enddef
6798
6799" Test for using a reserved keyword as a variable name
6800def Test_reserved_varname()
6801 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6802 'null_function', 'null_list', 'null_partial', 'null_string',
6803 'null_channel', 'null_job', 'super', 'this']
6804
6805 var lines =<< trim eval END
6806 vim9script
6807 class C
6808 public this.{kword}: list<number> = [1, 2, 3]
6809 endclass
6810 var o = C.new()
6811 END
6812 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6813
6814 lines =<< trim eval END
6815 vim9script
6816 class C
6817 public this.{kword}: list<number> = [1, 2, 3]
6818 def new()
6819 enddef
6820 endclass
6821 var o = C.new()
6822 END
6823 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6824
6825 lines =<< trim eval END
6826 vim9script
6827 class C
6828 public this.{kword}: list<number> = [1, 2, 3]
6829 def new()
6830 enddef
6831 def F()
6832 echo this.{kword}
6833 enddef
6834 endclass
6835 var o = C.new()
6836 o.F()
6837 END
6838 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006839
6840 # class variable name
6841 if kword != 'this'
6842 lines =<< trim eval END
6843 vim9script
6844 class C
6845 public static {kword}: list<number> = [1, 2, 3]
6846 endclass
6847 END
6848 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6849 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006850 endfor
6851enddef
6852
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006853" Test for checking the type of the arguments and the return value of a object
6854" method in an extended class.
6855def Test_extended_obj_method_type_check()
6856 var lines =<< trim END
6857 vim9script
6858
6859 class A
6860 endclass
6861 class B extends A
6862 endclass
6863 class C extends B
6864 endclass
6865
6866 class Foo
6867 def Doit(p: B): B
6868 return B.new()
6869 enddef
6870 endclass
6871
6872 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006873 def Doit(p: C): B
6874 return B.new()
6875 enddef
6876 endclass
6877 END
6878 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6879
6880 lines =<< trim END
6881 vim9script
6882
6883 class A
6884 endclass
6885 class B extends A
6886 endclass
6887 class C extends B
6888 endclass
6889
6890 class Foo
6891 def Doit(p: B): B
6892 return B.new()
6893 enddef
6894 endclass
6895
6896 class Bar extends Foo
6897 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006898 return C.new()
6899 enddef
6900 endclass
6901 END
6902 v9.CheckSourceSuccess(lines)
6903
6904 lines =<< trim END
6905 vim9script
6906
6907 class A
6908 endclass
6909 class B extends A
6910 endclass
6911 class C extends B
6912 endclass
6913
6914 class Foo
6915 def Doit(p: B): B
6916 return B.new()
6917 enddef
6918 endclass
6919
6920 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006921 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006922 return B.new()
6923 enddef
6924 endclass
6925 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006926 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 +02006927
6928 lines =<< trim END
6929 vim9script
6930
6931 class A
6932 endclass
6933 class B extends A
6934 endclass
6935 class C extends B
6936 endclass
6937
6938 class Foo
6939 def Doit(p: B): B
6940 return B.new()
6941 enddef
6942 endclass
6943
6944 class Bar extends Foo
6945 def Doit(p: B): A
6946 return A.new()
6947 enddef
6948 endclass
6949 END
6950 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 +02006951
6952 # check varargs type mismatch
6953 lines =<< trim END
6954 vim9script
6955
6956 class B
6957 def F(...xxx: list<any>)
6958 enddef
6959 endclass
6960 class C extends B
6961 def F(xxx: list<any>)
6962 enddef
6963 endclass
6964 END
6965 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 +02006966enddef
6967
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006968" Test type checking for class variable in assignments
6969func Test_class_variable_complex_type_check()
6970 " class variable with a specific type. Try assigning a different type at
6971 " script level.
6972 let lines =<< trim END
6973 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006974 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006975 return {}
6976 enddef
6977 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006978 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006979 endclass
6980 test_garbagecollect_now()
6981 A.Fn = "abc"
6982 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006983 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 +02006984
6985 " class variable with a specific type. Try assigning a different type at
6986 " class def method level.
6987 let lines =<< trim END
6988 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006989 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006990 return {}
6991 enddef
6992 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006993 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006994 def Bar()
6995 Fn = "abc"
6996 enddef
6997 endclass
6998 var a = A.new()
6999 test_garbagecollect_now()
7000 a.Bar()
7001 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007002 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 +02007003
7004 " class variable with a specific type. Try assigning a different type at
7005 " script def method level.
7006 let lines =<< trim END
7007 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007008 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007009 return {}
7010 enddef
7011 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007012 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007013 endclass
7014 def Bar()
7015 A.Fn = "abc"
7016 enddef
7017 test_garbagecollect_now()
7018 Bar()
7019 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007020 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 +02007021
7022 " class variable without any type. Should be set to the initialization
7023 " expression type. Try assigning a different type from script level.
7024 let lines =<< trim END
7025 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007026 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007027 return {}
7028 enddef
7029 class A
7030 public static Fn = Foo
7031 endclass
7032 test_garbagecollect_now()
7033 A.Fn = "abc"
7034 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007035 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 +02007036
7037 " class variable without any type. Should be set to the initialization
7038 " expression type. Try assigning a different type at class def level.
7039 let lines =<< trim END
7040 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007041 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007042 return {}
7043 enddef
7044 class A
7045 public static Fn = Foo
7046 def Bar()
7047 Fn = "abc"
7048 enddef
7049 endclass
7050 var a = A.new()
7051 test_garbagecollect_now()
7052 a.Bar()
7053 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007054 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 +02007055
7056 " class variable without any type. Should be set to the initialization
7057 " expression type. Try assigning a different type at script def level.
7058 let lines =<< trim END
7059 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007060 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007061 return {}
7062 enddef
7063 class A
7064 public static Fn = Foo
7065 endclass
7066 def Bar()
7067 A.Fn = "abc"
7068 enddef
7069 test_garbagecollect_now()
7070 Bar()
7071 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007072 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 +02007073
7074 " class variable with 'any" type. Can be assigned different types.
7075 let lines =<< trim END
7076 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007077 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007078 return {}
7079 enddef
7080 class A
7081 public static Fn: any = Foo
7082 public static Fn2: any
7083 endclass
7084 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007085 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007086 A.Fn = "abc"
7087 test_garbagecollect_now()
7088 assert_equal('string', typename(A.Fn))
7089 A.Fn2 = Foo
7090 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007091 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007092 A.Fn2 = "xyz"
7093 test_garbagecollect_now()
7094 assert_equal('string', typename(A.Fn2))
7095 END
7096 call v9.CheckSourceSuccess(lines)
7097
7098 " class variable with 'any" type. Can be assigned different types.
7099 let lines =<< trim END
7100 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007101 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007102 return {}
7103 enddef
7104 class A
7105 public static Fn: any = Foo
7106 public static Fn2: any
7107
7108 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007109 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007110 Fn = "abc"
7111 assert_equal('string', typename(Fn))
7112 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007113 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007114 Fn2 = "xyz"
7115 assert_equal('string', typename(Fn2))
7116 enddef
7117 endclass
7118 var a = A.new()
7119 test_garbagecollect_now()
7120 a.Bar()
7121 test_garbagecollect_now()
7122 A.Fn = Foo
7123 a.Bar()
7124 END
7125 call v9.CheckSourceSuccess(lines)
7126
7127 " class variable with 'any" type. Can be assigned different types.
7128 let lines =<< trim END
7129 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007130 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007131 return {}
7132 enddef
7133 class A
7134 public static Fn: any = Foo
7135 public static Fn2: any
7136 endclass
7137
7138 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007139 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007140 A.Fn = "abc"
7141 assert_equal('string', typename(A.Fn))
7142 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007143 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007144 A.Fn2 = "xyz"
7145 assert_equal('string', typename(A.Fn2))
7146 enddef
7147 Bar()
7148 test_garbagecollect_now()
7149 A.Fn = Foo
7150 Bar()
7151 END
7152 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007153
7154 let lines =<< trim END
7155 vim9script
7156 class A
7157 public static foo = [0z10, 0z20]
7158 endclass
7159 assert_equal([0z10, 0z20], A.foo)
7160 A.foo = [0z30]
7161 assert_equal([0z30], A.foo)
7162 var a = A.foo
7163 assert_equal([0z30], a)
7164 END
7165 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007166endfunc
7167
7168" Test type checking for object variable in assignments
7169func Test_object_variable_complex_type_check()
7170 " object variable with a specific type. Try assigning a different type at
7171 " script level.
7172 let lines =<< trim END
7173 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007174 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007175 return {}
7176 enddef
7177 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007178 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007179 endclass
7180 var a = A.new()
7181 test_garbagecollect_now()
7182 a.Fn = "abc"
7183 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007184 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 +02007185
7186 " object variable with a specific type. Try assigning a different type at
7187 " object def method level.
7188 let lines =<< trim END
7189 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007190 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007191 return {}
7192 enddef
7193 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007194 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007195 def Bar()
7196 this.Fn = "abc"
7197 this.Fn = Foo
7198 enddef
7199 endclass
7200 var a = A.new()
7201 test_garbagecollect_now()
7202 a.Bar()
7203 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007204 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 +02007205
7206 " object variable with a specific type. Try assigning a different type at
7207 " script def method level.
7208 let lines =<< trim END
7209 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007210 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007211 return {}
7212 enddef
7213 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007214 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007215 endclass
7216 def Bar()
7217 var a = A.new()
7218 a.Fn = "abc"
7219 a.Fn = Foo
7220 enddef
7221 test_garbagecollect_now()
7222 Bar()
7223 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007224 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 +02007225
7226 " object variable without any type. Should be set to the initialization
7227 " expression type. Try assigning a different type from script level.
7228 let lines =<< trim END
7229 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007230 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007231 return {}
7232 enddef
7233 class A
7234 public this.Fn = Foo
7235 endclass
7236 var a = A.new()
7237 test_garbagecollect_now()
7238 a.Fn = "abc"
7239 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007240 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 +02007241
7242 " object variable without any type. Should be set to the initialization
7243 " expression type. Try assigning a different type at object def level.
7244 let lines =<< trim END
7245 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007246 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007247 return {}
7248 enddef
7249 class A
7250 public this.Fn = Foo
7251 def Bar()
7252 this.Fn = "abc"
7253 this.Fn = Foo
7254 enddef
7255 endclass
7256 var a = A.new()
7257 test_garbagecollect_now()
7258 a.Bar()
7259 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007260 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 +02007261
7262 " object variable without any type. Should be set to the initialization
7263 " expression type. Try assigning a different type at script def level.
7264 let lines =<< trim END
7265 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007266 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007267 return {}
7268 enddef
7269 class A
7270 public this.Fn = Foo
7271 endclass
7272 def Bar()
7273 var a = A.new()
7274 a.Fn = "abc"
7275 a.Fn = Foo
7276 enddef
7277 test_garbagecollect_now()
7278 Bar()
7279 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007280 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 +02007281
7282 " object variable with 'any" type. Can be assigned different types.
7283 let lines =<< trim END
7284 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007285 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007286 return {}
7287 enddef
7288 class A
7289 public this.Fn: any = Foo
7290 public this.Fn2: any
7291 endclass
7292
7293 var a = A.new()
7294 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007295 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007296 a.Fn = "abc"
7297 test_garbagecollect_now()
7298 assert_equal('string', typename(a.Fn))
7299 a.Fn2 = Foo
7300 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007301 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007302 a.Fn2 = "xyz"
7303 test_garbagecollect_now()
7304 assert_equal('string', typename(a.Fn2))
7305 END
7306 call v9.CheckSourceSuccess(lines)
7307
7308 " object variable with 'any" type. Can be assigned different types.
7309 let lines =<< trim END
7310 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007311 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007312 return {}
7313 enddef
7314 class A
7315 public this.Fn: any = Foo
7316 public this.Fn2: any
7317
7318 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007319 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007320 this.Fn = "abc"
7321 assert_equal('string', typename(this.Fn))
7322 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007323 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007324 this.Fn2 = "xyz"
7325 assert_equal('string', typename(this.Fn2))
7326 enddef
7327 endclass
7328
7329 var a = A.new()
7330 test_garbagecollect_now()
7331 a.Bar()
7332 test_garbagecollect_now()
7333 a.Fn = Foo
7334 a.Bar()
7335 END
7336 call v9.CheckSourceSuccess(lines)
7337
7338 " object variable with 'any" type. Can be assigned different types.
7339 let lines =<< trim END
7340 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007341 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007342 return {}
7343 enddef
7344 class A
7345 public this.Fn: any = Foo
7346 public this.Fn2: any
7347 endclass
7348
7349 def Bar()
7350 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007351 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007352 a.Fn = "abc"
7353 assert_equal('string', typename(a.Fn))
7354 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007355 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007356 a.Fn2 = "xyz"
7357 assert_equal('string', typename(a.Fn2))
7358 enddef
7359 test_garbagecollect_now()
7360 Bar()
7361 test_garbagecollect_now()
7362 Bar()
7363 END
7364 call v9.CheckSourceSuccess(lines)
7365endfunc
7366
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007367" Test for recursively calling an object method. This used to cause an
7368" use-after-free error.
7369def Test_recursive_object_method_call()
7370 var lines =<< trim END
7371 vim9script
7372 class A
7373 this.val: number = 0
7374 def Foo(): number
7375 if this.val >= 90
7376 return this.val
7377 endif
7378 this.val += 1
7379 return this.Foo()
7380 enddef
7381 endclass
7382 var a = A.new()
7383 assert_equal(90, a.Foo())
7384 END
7385 v9.CheckSourceSuccess(lines)
7386enddef
7387
7388" Test for recursively calling a class method.
7389def Test_recursive_class_method_call()
7390 var lines =<< trim END
7391 vim9script
7392 class A
7393 static val: number = 0
7394 static def Foo(): number
7395 if val >= 90
7396 return val
7397 endif
7398 val += 1
7399 return Foo()
7400 enddef
7401 endclass
7402 assert_equal(90, A.Foo())
7403 END
7404 v9.CheckSourceSuccess(lines)
7405enddef
7406
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007407" Test for checking the argument types and the return type when assigning a
7408" funcref to make sure the invariant class type is used.
7409def Test_funcref_argtype_returntype_check()
7410 var lines =<< trim END
7411 vim9script
7412 class A
7413 endclass
7414 class B extends A
7415 endclass
7416
7417 def Foo(p: B): B
7418 return B.new()
7419 enddef
7420
7421 var Bar: func(A): A = Foo
7422 END
7423 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7424
7425 lines =<< trim END
7426 vim9script
7427 class A
7428 endclass
7429 class B extends A
7430 endclass
7431
7432 def Foo(p: B): B
7433 return B.new()
7434 enddef
7435
7436 def Baz()
7437 var Bar: func(A): A = Foo
7438 enddef
7439 Baz()
7440 END
7441 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7442enddef
7443
Ernie Rael96952b22023-10-17 18:15:01 +02007444def Test_funcref_argtype_invariance_check()
7445 var lines =<< trim END
7446 vim9script
7447
7448 class A
7449 endclass
7450 class B extends A
7451 endclass
7452 class C extends B
7453 endclass
7454
7455 var Func: func(B): number
7456 Func = (o: B): number => 3
7457 assert_equal(3, Func(B.new()))
7458 END
7459 v9.CheckSourceSuccess(lines)
7460
7461 lines =<< trim END
7462 vim9script
7463
7464 class A
7465 endclass
7466 class B extends A
7467 endclass
7468 class C extends B
7469 endclass
7470
7471 var Func: func(B): number
7472 Func = (o: A): number => 3
7473 END
7474 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7475
7476 lines =<< trim END
7477 vim9script
7478
7479 class A
7480 endclass
7481 class B extends A
7482 endclass
7483 class C extends B
7484 endclass
7485
7486 var Func: func(B): number
7487 Func = (o: C): number => 3
7488 END
7489 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7490enddef
7491
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007492" Test for using an operator (e.g. +) with an assignment
7493def Test_op_and_assignment()
7494 # Using += with a class variable
7495 var lines =<< trim END
7496 vim9script
7497 class A
7498 public static val: list<number> = []
7499 static def Foo(): list<number>
7500 val += [1]
7501 return val
7502 enddef
7503 endclass
7504 def Bar(): list<number>
7505 A.val += [2]
7506 return A.val
7507 enddef
7508 assert_equal([1], A.Foo())
7509 assert_equal([1, 2], Bar())
7510 A.val += [3]
7511 assert_equal([1, 2, 3], A.val)
7512 END
7513 v9.CheckSourceSuccess(lines)
7514
7515 # Using += with an object variable
7516 lines =<< trim END
7517 vim9script
7518 class A
7519 public this.val: list<number> = []
7520 def Foo(): list<number>
7521 this.val += [1]
7522 return this.val
7523 enddef
7524 endclass
7525 def Bar(bar_a: A): list<number>
7526 bar_a.val += [2]
7527 return bar_a.val
7528 enddef
7529 var a = A.new()
7530 assert_equal([1], a.Foo())
7531 assert_equal([1, 2], Bar(a))
7532 a.val += [3]
7533 assert_equal([1, 2, 3], a.val)
7534 END
7535 v9.CheckSourceSuccess(lines)
7536enddef
7537
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007538" Test for using an object method as a funcref
7539def Test_object_funcref()
7540 # Using object method funcref from a def function
7541 var lines =<< trim END
7542 vim9script
7543 class A
7544 def Foo(): list<number>
7545 return [3, 2, 1]
7546 enddef
7547 endclass
7548 def Bar()
7549 var a = A.new()
7550 var Fn = a.Foo
7551 assert_equal([3, 2, 1], Fn())
7552 enddef
7553 Bar()
7554 END
7555 v9.CheckSourceSuccess(lines)
7556
7557 # Using object method funcref at the script level
7558 lines =<< trim END
7559 vim9script
7560 class A
7561 def Foo(): dict<number>
7562 return {a: 1, b: 2}
7563 enddef
7564 endclass
7565 var a = A.new()
7566 var Fn = a.Foo
7567 assert_equal({a: 1, b: 2}, Fn())
7568 END
7569 v9.CheckSourceSuccess(lines)
7570
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007571 # Using object method funcref at the script level
7572 lines =<< trim END
7573 vim9script
7574 class A
7575 this.val: number
7576 def Foo(): number
7577 return this.val
7578 enddef
7579 endclass
7580 var a = A.new(345)
7581 var Fn = a.Foo
7582 assert_equal(345, Fn())
7583 END
7584 v9.CheckSourceSuccess(lines)
7585
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007586 # Using object method funcref from another object method
7587 lines =<< trim END
7588 vim9script
7589 class A
7590 def Foo(): list<number>
7591 return [3, 2, 1]
7592 enddef
7593 def Bar()
7594 var Fn = this.Foo
7595 assert_equal([3, 2, 1], Fn())
7596 enddef
7597 endclass
7598 var a = A.new()
7599 a.Bar()
7600 END
7601 v9.CheckSourceSuccess(lines)
7602
7603 # Using function() to get a object method funcref
7604 lines =<< trim END
7605 vim9script
7606 class A
7607 def Foo(l: list<any>): list<any>
7608 return l
7609 enddef
7610 endclass
7611 var a = A.new()
7612 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7613 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7614 END
7615 v9.CheckSourceSuccess(lines)
7616
7617 # Use an object method with a function returning a funcref and then call the
7618 # funcref.
7619 lines =<< trim END
7620 vim9script
7621
7622 def Map(F: func(number): number): func(number): number
7623 return (n: number) => F(n)
7624 enddef
7625
7626 class Math
7627 def Double(n: number): number
7628 return 2 * n
7629 enddef
7630 endclass
7631
7632 const math = Math.new()
7633 assert_equal(48, Map(math.Double)(24))
7634 END
7635 v9.CheckSourceSuccess(lines)
7636
7637 # Try using a private object method funcref from a def function
7638 lines =<< trim END
7639 vim9script
7640 class A
7641 def _Foo()
7642 enddef
7643 endclass
7644 def Bar()
7645 var a = A.new()
7646 var Fn = a._Foo
7647 enddef
7648 Bar()
7649 END
7650 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
7651
7652 # Try using a private object method funcref at the script level
7653 lines =<< trim END
7654 vim9script
7655 class A
7656 def _Foo()
7657 enddef
7658 endclass
7659 var a = A.new()
7660 var Fn = a._Foo
7661 END
7662 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 7)
7663
7664 # Using a private object method funcref from another object method
7665 lines =<< trim END
7666 vim9script
7667 class A
7668 def _Foo(): list<number>
7669 return [3, 2, 1]
7670 enddef
7671 def Bar()
7672 var Fn = this._Foo
7673 assert_equal([3, 2, 1], Fn())
7674 enddef
7675 endclass
7676 var a = A.new()
7677 a.Bar()
7678 END
7679 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007680
7681 # Using object method funcref using call()
7682 lines =<< trim END
7683 vim9script
7684 class A
7685 this.val: number
7686 def Foo(): number
7687 return this.val
7688 enddef
7689 endclass
7690
7691 def Bar(obj: A)
7692 assert_equal(123, call(obj.Foo, []))
7693 enddef
7694
7695 var a = A.new(123)
7696 Bar(a)
7697 assert_equal(123, call(a.Foo, []))
7698 END
7699 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007700enddef
7701
7702" Test for using a class method as a funcref
7703def Test_class_funcref()
7704 # Using class method funcref in a def function
7705 var lines =<< trim END
7706 vim9script
7707 class A
7708 static def Foo(): list<number>
7709 return [3, 2, 1]
7710 enddef
7711 endclass
7712 def Bar()
7713 var Fn = A.Foo
7714 assert_equal([3, 2, 1], Fn())
7715 enddef
7716 Bar()
7717 END
7718 v9.CheckSourceSuccess(lines)
7719
7720 # Using class method funcref at script level
7721 lines =<< trim END
7722 vim9script
7723 class A
7724 static def Foo(): dict<number>
7725 return {a: 1, b: 2}
7726 enddef
7727 endclass
7728 var Fn = A.Foo
7729 assert_equal({a: 1, b: 2}, Fn())
7730 END
7731 v9.CheckSourceSuccess(lines)
7732
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007733 # Using class method funcref at the script level
7734 lines =<< trim END
7735 vim9script
7736 class A
7737 public static val: number
7738 static def Foo(): number
7739 return val
7740 enddef
7741 endclass
7742 A.val = 567
7743 var Fn = A.Foo
7744 assert_equal(567, Fn())
7745 END
7746 v9.CheckSourceSuccess(lines)
7747
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007748 # Using function() to get a class method funcref
7749 lines =<< trim END
7750 vim9script
7751 class A
7752 static def Foo(l: list<any>): list<any>
7753 return l
7754 enddef
7755 endclass
7756 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
7757 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7758 END
7759 v9.CheckSourceSuccess(lines)
7760
7761 # Using a class method funcref from another class method
7762 lines =<< trim END
7763 vim9script
7764 class A
7765 static def Foo(): list<number>
7766 return [3, 2, 1]
7767 enddef
7768 static def Bar()
7769 var Fn = Foo
7770 assert_equal([3, 2, 1], Fn())
7771 enddef
7772 endclass
7773 A.Bar()
7774 END
7775 v9.CheckSourceSuccess(lines)
7776
7777 # Use a class method with a function returning a funcref and then call the
7778 # funcref.
7779 lines =<< trim END
7780 vim9script
7781
7782 def Map(F: func(number): number): func(number): number
7783 return (n: number) => F(n)
7784 enddef
7785
7786 class Math
7787 static def StaticDouble(n: number): number
7788 return 2 * n
7789 enddef
7790 endclass
7791
7792 assert_equal(48, Map(Math.StaticDouble)(24))
7793 END
7794 v9.CheckSourceSuccess(lines)
7795
7796 # Try using a private class method funcref in a def function
7797 lines =<< trim END
7798 vim9script
7799 class A
7800 static def _Foo()
7801 enddef
7802 endclass
7803 def Bar()
7804 var Fn = A._Foo
7805 enddef
7806 Bar()
7807 END
7808 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 1)
7809
7810 # Try using a private class method funcref at script level
7811 lines =<< trim END
7812 vim9script
7813 class A
7814 static def _Foo()
7815 enddef
7816 endclass
7817 var Fn = A._Foo
7818 END
7819 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 6)
7820
7821 # Using a private class method funcref from another class method
7822 lines =<< trim END
7823 vim9script
7824 class A
7825 static def _Foo(): list<number>
7826 return [3, 2, 1]
7827 enddef
7828 static def Bar()
7829 var Fn = _Foo
7830 assert_equal([3, 2, 1], Fn())
7831 enddef
7832 endclass
7833 A.Bar()
7834 END
7835 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007836
7837 # Using class method funcref using call()
7838 lines =<< trim END
7839 vim9script
7840 class A
7841 public static val: number
7842 static def Foo(): number
7843 return val
7844 enddef
7845 endclass
7846
7847 def Bar()
7848 A.val = 468
7849 assert_equal(468, call(A.Foo, []))
7850 enddef
7851 Bar()
7852 assert_equal(468, call(A.Foo, []))
7853 END
7854 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007855enddef
7856
7857" Test for using an object member as a funcref
7858def Test_object_member_funcref()
7859 # Using a funcref object variable in an object method
7860 var lines =<< trim END
7861 vim9script
7862 def Foo(n: number): number
7863 return n * 10
7864 enddef
7865
7866 class A
7867 this.Cb: func(number): number = Foo
7868 def Bar()
7869 assert_equal(200, this.Cb(20))
7870 enddef
7871 endclass
7872
7873 var a = A.new()
7874 a.Bar()
7875 END
7876 v9.CheckSourceSuccess(lines)
7877
7878 # Using a funcref object variable in a def method
7879 lines =<< trim END
7880 vim9script
7881 def Foo(n: number): number
7882 return n * 10
7883 enddef
7884
7885 class A
7886 this.Cb: func(number): number = Foo
7887 endclass
7888
7889 def Bar()
7890 var a = A.new()
7891 assert_equal(200, a.Cb(20))
7892 enddef
7893 Bar()
7894 END
7895 v9.CheckSourceSuccess(lines)
7896
7897 # Using a funcref object variable at script level
7898 lines =<< trim END
7899 vim9script
7900 def Foo(n: number): number
7901 return n * 10
7902 enddef
7903
7904 class A
7905 this.Cb: func(number): number = Foo
7906 endclass
7907
7908 var a = A.new()
7909 assert_equal(200, a.Cb(20))
7910 END
7911 v9.CheckSourceSuccess(lines)
7912
7913 # Using a funcref object variable pointing to an object method in an object
7914 # method.
7915 lines =<< trim END
7916 vim9script
7917 class A
7918 this.Cb: func(number): number = this.Foo
7919 def Foo(n: number): number
7920 return n * 10
7921 enddef
7922 def Bar()
7923 assert_equal(200, this.Cb(20))
7924 enddef
7925 endclass
7926
7927 var a = A.new()
7928 a.Bar()
7929 END
7930 v9.CheckSourceSuccess(lines)
7931
7932 # Using a funcref object variable pointing to an object method in a def
7933 # method.
7934 lines =<< trim END
7935 vim9script
7936 class A
7937 this.Cb: func(number): number = this.Foo
7938 def Foo(n: number): number
7939 return n * 10
7940 enddef
7941 endclass
7942
7943 def Bar()
7944 var a = A.new()
7945 assert_equal(200, a.Cb(20))
7946 enddef
7947 Bar()
7948 END
7949 v9.CheckSourceSuccess(lines)
7950
7951 # Using a funcref object variable pointing to an object method at script
7952 # level.
7953 lines =<< trim END
7954 vim9script
7955 class A
7956 this.Cb = this.Foo
7957 def Foo(n: number): number
7958 return n * 10
7959 enddef
7960 endclass
7961
7962 var a = A.new()
7963 assert_equal(200, a.Cb(20))
7964 END
7965 v9.CheckSourceSuccess(lines)
7966enddef
7967
7968" Test for using a class member as a funcref
7969def Test_class_member_funcref()
7970 # Using a funcref class variable in a class method
7971 var lines =<< trim END
7972 vim9script
7973 def Foo(n: number): number
7974 return n * 10
7975 enddef
7976
7977 class A
7978 static Cb = Foo
7979 static def Bar()
7980 assert_equal(200, Cb(20))
7981 enddef
7982 endclass
7983
7984 A.Bar()
7985 END
7986 v9.CheckSourceSuccess(lines)
7987
7988 # Using a funcref class variable in a def method
7989 lines =<< trim END
7990 vim9script
7991 def Foo(n: number): number
7992 return n * 10
7993 enddef
7994
7995 class A
7996 public static Cb = Foo
7997 endclass
7998
7999 def Bar()
8000 assert_equal(200, A.Cb(20))
8001 enddef
8002 Bar()
8003 END
8004 v9.CheckSourceSuccess(lines)
8005
8006 # Using a funcref class variable at script level
8007 lines =<< trim END
8008 vim9script
8009 def Foo(n: number): number
8010 return n * 10
8011 enddef
8012
8013 class A
8014 public static Cb = Foo
8015 endclass
8016
8017 assert_equal(200, A.Cb(20))
8018 END
8019 v9.CheckSourceSuccess(lines)
8020
8021 # Using a funcref class variable pointing to a class method in a class
8022 # method.
8023 lines =<< trim END
8024 vim9script
8025 class A
8026 static Cb: func(number): number
8027 static def Foo(n: number): number
8028 return n * 10
8029 enddef
8030 static def Init()
8031 Cb = Foo
8032 enddef
8033 static def Bar()
8034 assert_equal(200, Cb(20))
8035 enddef
8036 endclass
8037
8038 A.Init()
8039 A.Bar()
8040 END
8041 v9.CheckSourceSuccess(lines)
8042
8043 # Using a funcref class variable pointing to a class method in a def method.
8044 lines =<< trim END
8045 vim9script
8046 class A
8047 static Cb: func(number): number
8048 static def Foo(n: number): number
8049 return n * 10
8050 enddef
8051 static def Init()
8052 Cb = Foo
8053 enddef
8054 endclass
8055
8056 def Bar()
8057 A.Init()
8058 assert_equal(200, A.Cb(20))
8059 enddef
8060 Bar()
8061 END
8062 v9.CheckSourceSuccess(lines)
8063
8064 # Using a funcref class variable pointing to a class method at script level.
8065 lines =<< trim END
8066 vim9script
8067 class A
8068 static Cb: func(number): number
8069 static def Foo(n: number): number
8070 return n * 10
8071 enddef
8072 static def Init()
8073 Cb = Foo
8074 enddef
8075 endclass
8076
8077 A.Init()
8078 assert_equal(200, A.Cb(20))
8079 END
8080 v9.CheckSourceSuccess(lines)
8081enddef
8082
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008083" Test for using object methods as popup callback functions
8084def Test_objmethod_popup_callback()
8085 # Use the popup from the script level
8086 var lines =<< trim END
8087 vim9script
8088
8089 class A
8090 this.selection: number = -1
8091 this.filterkeys: list<string> = []
8092
8093 def PopupFilter(id: number, key: string): bool
8094 add(this.filterkeys, key)
8095 return popup_filter_yesno(id, key)
8096 enddef
8097
8098 def PopupCb(id: number, result: number)
8099 this.selection = result ? 100 : 200
8100 enddef
8101 endclass
8102
8103 var a = A.new()
8104 feedkeys('', 'xt')
8105 var winid = popup_create('Y/N?',
8106 {filter: a.PopupFilter, callback: a.PopupCb})
8107 feedkeys('y', 'xt')
8108 popup_close(winid)
8109 assert_equal(100, a.selection)
8110 assert_equal(['y'], a.filterkeys)
8111 feedkeys('', 'xt')
8112 winid = popup_create('Y/N?',
8113 {filter: a.PopupFilter, callback: a.PopupCb})
8114 feedkeys('n', 'xt')
8115 popup_close(winid)
8116 assert_equal(200, a.selection)
8117 assert_equal(['y', 'n'], a.filterkeys)
8118 END
8119 v9.CheckSourceSuccess(lines)
8120
8121 # Use the popup from a def function
8122 lines =<< trim END
8123 vim9script
8124
8125 class A
8126 this.selection: number = -1
8127 this.filterkeys: list<string> = []
8128
8129 def PopupFilter(id: number, key: string): bool
8130 add(this.filterkeys, key)
8131 return popup_filter_yesno(id, key)
8132 enddef
8133
8134 def PopupCb(id: number, result: number)
8135 this.selection = result ? 100 : 200
8136 enddef
8137 endclass
8138
8139 def Foo()
8140 var a = A.new()
8141 feedkeys('', 'xt')
8142 var winid = popup_create('Y/N?',
8143 {filter: a.PopupFilter, callback: a.PopupCb})
8144 feedkeys('y', 'xt')
8145 popup_close(winid)
8146 assert_equal(100, a.selection)
8147 assert_equal(['y'], a.filterkeys)
8148 feedkeys('', 'xt')
8149 winid = popup_create('Y/N?',
8150 {filter: a.PopupFilter, callback: a.PopupCb})
8151 feedkeys('n', 'xt')
8152 popup_close(winid)
8153 assert_equal(200, a.selection)
8154 assert_equal(['y', 'n'], a.filterkeys)
8155 enddef
8156 Foo()
8157 END
8158 v9.CheckSourceSuccess(lines)
8159enddef
8160
8161" Test for using class methods as popup callback functions
8162def Test_classmethod_popup_callback()
8163 # Use the popup from the script level
8164 var lines =<< trim END
8165 vim9script
8166
8167 class A
8168 static selection: number = -1
8169 static filterkeys: list<string> = []
8170
8171 static def PopupFilter(id: number, key: string): bool
8172 add(filterkeys, key)
8173 return popup_filter_yesno(id, key)
8174 enddef
8175
8176 static def PopupCb(id: number, result: number)
8177 selection = result ? 100 : 200
8178 enddef
8179 endclass
8180
8181 feedkeys('', 'xt')
8182 var winid = popup_create('Y/N?',
8183 {filter: A.PopupFilter, callback: A.PopupCb})
8184 feedkeys('y', 'xt')
8185 popup_close(winid)
8186 assert_equal(100, A.selection)
8187 assert_equal(['y'], A.filterkeys)
8188 feedkeys('', 'xt')
8189 winid = popup_create('Y/N?',
8190 {filter: A.PopupFilter, callback: A.PopupCb})
8191 feedkeys('n', 'xt')
8192 popup_close(winid)
8193 assert_equal(200, A.selection)
8194 assert_equal(['y', 'n'], A.filterkeys)
8195 END
8196 v9.CheckSourceSuccess(lines)
8197
8198 # Use the popup from a def function
8199 lines =<< trim END
8200 vim9script
8201
8202 class A
8203 static selection: number = -1
8204 static filterkeys: list<string> = []
8205
8206 static def PopupFilter(id: number, key: string): bool
8207 add(filterkeys, key)
8208 return popup_filter_yesno(id, key)
8209 enddef
8210
8211 static def PopupCb(id: number, result: number)
8212 selection = result ? 100 : 200
8213 enddef
8214 endclass
8215
8216 def Foo()
8217 feedkeys('', 'xt')
8218 var winid = popup_create('Y/N?',
8219 {filter: A.PopupFilter, callback: A.PopupCb})
8220 feedkeys('y', 'xt')
8221 popup_close(winid)
8222 assert_equal(100, A.selection)
8223 assert_equal(['y'], A.filterkeys)
8224 feedkeys('', 'xt')
8225 winid = popup_create('Y/N?',
8226 {filter: A.PopupFilter, callback: A.PopupCb})
8227 feedkeys('n', 'xt')
8228 popup_close(winid)
8229 assert_equal(200, A.selection)
8230 assert_equal(['y', 'n'], A.filterkeys)
8231 enddef
8232 Foo()
8233 END
8234 v9.CheckSourceSuccess(lines)
8235enddef
8236
8237" Test for using an object method as a timer callback function
8238def Test_objmethod_timer_callback()
8239 # Use the timer callback from script level
8240 var lines =<< trim END
8241 vim9script
8242
8243 class A
8244 this.timerTick: number = -1
8245 def TimerCb(timerID: number)
8246 this.timerTick = 6
8247 enddef
8248 endclass
8249
8250 var a = A.new()
8251 timer_start(0, a.TimerCb)
8252 var maxWait = 5
8253 while maxWait > 0 && a.timerTick == -1
8254 :sleep 10m
8255 maxWait -= 1
8256 endwhile
8257 assert_equal(6, a.timerTick)
8258 END
8259 v9.CheckSourceSuccess(lines)
8260
8261 # Use the timer callback from a def function
8262 lines =<< trim END
8263 vim9script
8264
8265 class A
8266 this.timerTick: number = -1
8267 def TimerCb(timerID: number)
8268 this.timerTick = 6
8269 enddef
8270 endclass
8271
8272 def Foo()
8273 var a = A.new()
8274 timer_start(0, a.TimerCb)
8275 var maxWait = 5
8276 while maxWait > 0 && a.timerTick == -1
8277 :sleep 10m
8278 maxWait -= 1
8279 endwhile
8280 assert_equal(6, a.timerTick)
8281 enddef
8282 Foo()
8283 END
8284 v9.CheckSourceSuccess(lines)
8285enddef
8286
8287" Test for using a class method as a timer callback function
8288def Test_classmethod_timer_callback()
8289 # Use the timer callback from script level
8290 var lines =<< trim END
8291 vim9script
8292
8293 class A
8294 static timerTick: number = -1
8295 static def TimerCb(timerID: number)
8296 timerTick = 6
8297 enddef
8298 endclass
8299
8300 timer_start(0, A.TimerCb)
8301 var maxWait = 5
8302 while maxWait > 0 && A.timerTick == -1
8303 :sleep 10m
8304 maxWait -= 1
8305 endwhile
8306 assert_equal(6, A.timerTick)
8307 END
8308 v9.CheckSourceSuccess(lines)
8309
8310 # Use the timer callback from a def function
8311 lines =<< trim END
8312 vim9script
8313
8314 class A
8315 static timerTick: number = -1
8316 static def TimerCb(timerID: number)
8317 timerTick = 6
8318 enddef
8319 endclass
8320
8321 def Foo()
8322 timer_start(0, A.TimerCb)
8323 var maxWait = 5
8324 while maxWait > 0 && A.timerTick == -1
8325 :sleep 10m
8326 maxWait -= 1
8327 endwhile
8328 assert_equal(6, A.timerTick)
8329 enddef
8330 Foo()
8331 END
8332 v9.CheckSourceSuccess(lines)
8333enddef
8334
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008335" Test for using a class variable as the first and/or second operand of a binary
8336" operator.
8337def Test_class_variable_as_operands()
8338 var lines =<< trim END
8339 vim9script
8340 class Tests
8341 static truthy: bool = true
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008342 public static TruthyFn: func
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008343 static list: list<any> = []
8344 static four: number = 4
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008345 static str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008346
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008347 static def Str(): string
8348 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008349 enddef
8350
8351 static def Four(): number
8352 return four
8353 enddef
8354
8355 static def List(): list<any>
8356 return list
8357 enddef
8358
8359 static def Truthy(): bool
8360 return truthy
8361 enddef
8362
8363 def TestOps()
8364 assert_true(Tests.truthy == truthy)
8365 assert_true(truthy == Tests.truthy)
8366 assert_true(Tests.list isnot [])
8367 assert_true([] isnot Tests.list)
8368 assert_equal(2, Tests.four >> 1)
8369 assert_equal(16, 1 << Tests.four)
8370 assert_equal(8, Tests.four + four)
8371 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008372 assert_equal('hellohello', Tests.str .. str)
8373 assert_equal('hellohello', str .. Tests.str)
8374
8375 # Using class variable for list indexing
8376 var l = range(10)
8377 assert_equal(4, l[Tests.four])
8378 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8379
8380 # Using class variable for Dict key
8381 var d = {hello: 'abc'}
8382 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008383 enddef
8384 endclass
8385
8386 def TestOps2()
8387 assert_true(Tests.truthy == Tests.Truthy())
8388 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008389 assert_true(Tests.truthy == Tests.TruthyFn())
8390 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008391 assert_true(Tests.list is Tests.List())
8392 assert_true(Tests.List() is Tests.list)
8393 assert_equal(2, Tests.four >> 1)
8394 assert_equal(16, 1 << Tests.four)
8395 assert_equal(8, Tests.four + Tests.Four())
8396 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008397 assert_equal('hellohello', Tests.str .. Tests.Str())
8398 assert_equal('hellohello', Tests.Str() .. Tests.str)
8399
8400 # Using class variable for list indexing
8401 var l = range(10)
8402 assert_equal(4, l[Tests.four])
8403 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8404
8405 # Using class variable for Dict key
8406 var d = {hello: 'abc'}
8407 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008408 enddef
8409
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008410 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008411 var t = Tests.new()
8412 t.TestOps()
8413 TestOps2()
8414
8415 assert_true(Tests.truthy == Tests.Truthy())
8416 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008417 assert_true(Tests.truthy == Tests.TruthyFn())
8418 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008419 assert_true(Tests.list is Tests.List())
8420 assert_true(Tests.List() is Tests.list)
8421 assert_equal(2, Tests.four >> 1)
8422 assert_equal(16, 1 << Tests.four)
8423 assert_equal(8, Tests.four + Tests.Four())
8424 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008425 assert_equal('hellohello', Tests.str .. Tests.Str())
8426 assert_equal('hellohello', Tests.Str() .. Tests.str)
8427
8428 # Using class variable for list indexing
8429 var l = range(10)
8430 assert_equal(4, l[Tests.four])
8431 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8432
8433 # Using class variable for Dict key
8434 var d = {hello: 'abc'}
8435 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008436 END
8437 v9.CheckSourceSuccess(lines)
8438enddef
8439
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008440" Test for checking the type of the key used to access an object dict member.
8441def Test_dict_member_key_type_check()
8442 var lines =<< trim END
8443 vim9script
8444
8445 abstract class State
8446 this.numbers: dict<string> = {0: 'nil', 1: 'unity'}
8447 endclass
8448
8449 class Test extends State
8450 def ObjMethodTests()
8451 var cursor: number = 0
8452 var z: number = 0
8453 [this.numbers[cursor]] = ['zero.1']
8454 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8455 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8456 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8457 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8458 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8459 [this.numbers[cursor], z] = ['zero.4', 1]
8460 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8461 [z, this.numbers[cursor]] = [1, 'zero.5']
8462 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8463 enddef
8464
8465 static def ClassMethodTests(that: State)
8466 var cursor: number = 0
8467 var z: number = 0
8468 [that.numbers[cursor]] = ['zero.1']
8469 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8470 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8471 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8472 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8473 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8474 [that.numbers[cursor], z] = ['zero.4', 1]
8475 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8476 [z, that.numbers[cursor]] = [1, 'zero.5']
8477 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8478 enddef
8479
8480 def new()
8481 enddef
8482
8483 def newMethodTests()
8484 var cursor: number = 0
8485 var z: number
8486 [this.numbers[cursor]] = ['zero.1']
8487 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8488 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8489 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8490 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8491 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8492 [this.numbers[cursor], z] = ['zero.4', 1]
8493 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8494 [z, this.numbers[cursor]] = [1, 'zero.5']
8495 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8496 enddef
8497 endclass
8498
8499 def DefFuncTests(that: Test)
8500 var cursor: number = 0
8501 var z: number
8502 [that.numbers[cursor]] = ['zero.1']
8503 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8504 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8505 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8506 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8507 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8508 [that.numbers[cursor], z] = ['zero.4', 1]
8509 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8510 [z, that.numbers[cursor]] = [1, 'zero.5']
8511 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8512 enddef
8513
8514 Test.newMethodTests()
8515 Test.new().ObjMethodTests()
8516 Test.ClassMethodTests(Test.new())
8517 DefFuncTests(Test.new())
8518
8519 const test: Test = Test.new()
8520 var cursor: number = 0
8521 [test.numbers[cursor], cursor] = ['zero', 1]
8522 [cursor, test.numbers[cursor]] = [1, 'one']
8523 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8524 END
8525 v9.CheckSourceSuccess(lines)
8526
8527 lines =<< trim END
8528 vim9script
8529
8530 class A
8531 this.numbers: dict<string> = {a: '1', b: '2'}
8532
8533 def new()
8534 enddef
8535
8536 def Foo()
8537 var z: number
8538 [this.numbers.a, z] = [{}, 10]
8539 enddef
8540 endclass
8541
8542 var a = A.new()
8543 a.Foo()
8544 END
8545 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<unknown>', 2)
8546
8547 lines =<< trim END
8548 vim9script
8549
8550 class A
8551 this.numbers: dict<number> = {a: 1, b: 2}
8552
8553 def new()
8554 enddef
8555
8556 def Foo()
8557 var x: string = 'a'
8558 var y: number
8559 [this.numbers[x], y] = [{}, 10]
8560 enddef
8561 endclass
8562
8563 var a = A.new()
8564 a.Foo()
8565 END
8566 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<unknown>', 3)
8567enddef
8568
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008569" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker