blob: dc539aca4990c521fc7a7a5e486c8ceec8bdfeab [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 Lakshmanan00cd1822023-09-18 19:56:49 +020038 # Only the completed 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
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200135 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Something": state', 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 Lakshmananb90e3bc2023-09-28 23:06:48 +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 Lakshmananb90e3bc2023-09-28 23:06:48 +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 Lakshmananb90e3bc2023-09-28 23:06:48 +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 Lakshmananb90e3bc2023-09-28 23:06:48 +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 Lakshmananb90e3bc2023-09-28 23:06:48 +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 Lakshmananb90e3bc2023-09-28 23:06:48 +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
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200651 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Inner": someval', 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)
h-east2261c892023-08-16 21:49:54 +0900978enddef
979
Bram Moolenaar74e12742022-12-13 21:14:28 +0000980def Test_class_object_member_inits()
981 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200982 vim9script
983 class TextPosition
984 this.lnum: number
985 this.col = 1
986 this.addcol: number = 2
987 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000988
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200989 var pos = TextPosition.new()
990 assert_equal(0, pos.lnum)
991 assert_equal(1, pos.col)
992 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000993 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200994 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000995
996 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 vim9script
998 class TextPosition
999 this.lnum
1000 this.col = 1
1001 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001004
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001005 # If the type is not specified for a member, then it should be set during
1006 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001007 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var init_count = 0
1011 def Init(): string
1012 init_count += 1
1013 return 'foo'
1014 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001015
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 class A
1017 this.str1 = Init()
1018 this.str2: string = Init()
1019 this.col = 1
1020 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 assert_equal(init_count, 0)
1023 var a = A.new()
1024 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001027
1028 # Test for initializing an object member with an unknown variable/type
1029 lines =<< trim END
1030 vim9script
1031 class A
1032 this.value = init_val
1033 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001034 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001036 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001037
1038 # Test for initializing an object member with an special type
1039 lines =<< trim END
1040 vim9script
1041 class A
1042 this.value: void
1043 endclass
1044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001046enddef
1047
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048" Test for instance variable access
1049def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001050 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 vim9script
1052 class Triple
1053 this._one = 1
1054 this.two = 2
1055 public this.three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001056
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001057 def GetOne(): number
1058 return this._one
1059 enddef
1060 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var trip = Triple.new()
1063 assert_equal(1, trip.GetOne())
1064 assert_equal(2, trip.two)
1065 assert_equal(3, trip.three)
Ernie Rael64885642023-10-04 20:16:22 +02001066 assert_fails('echo trip._one', 'E1333: Cannot access private variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001067
Ernie Rael64885642023-10-04 20:16:22 +02001068 assert_fails('trip._one = 11', 'E1333: Cannot access private variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1070 trip.three = 33
1071 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 assert_fails('trip.four = 4', 'E1326: Variable not found on object "Triple": four')
Bram Moolenaard505d172022-12-18 21:42:55 +00001074 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001075 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001076
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001077 # Test for a public member variable name beginning with an underscore
1078 lines =<< trim END
1079 vim9script
1080 class A
1081 public this._val = 10
1082 endclass
1083 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001084 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001085
Bram Moolenaar590162c2022-12-24 21:24:06 +00001086 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001087 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001088
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001089 class MyCar
1090 this.make: string
1091 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001092
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001093 def new(make_arg: string)
1094 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001095 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001096
1097 def GetMake(): string
1098 return $"make = {this.make}"
1099 enddef
1100 def GetAge(): number
1101 return this.age
1102 enddef
1103 endclass
1104
1105 var c = MyCar.new("abc")
1106 assert_equal('make = abc', c.GetMake())
1107
1108 c = MyCar.new("def")
1109 assert_equal('make = def', c.GetMake())
1110
1111 var c2 = MyCar.new("123")
1112 assert_equal('make = 123', c2.GetMake())
1113
1114 def CheckCar()
1115 assert_equal("make = def", c.GetMake())
1116 assert_equal(5, c.GetAge())
1117 enddef
1118 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001119 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001120 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001121
1122 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001123 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001124
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001125 class MyCar
1126 this.make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001127
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001128 def new(make_arg: string)
1129 this.make = make_arg
1130 enddef
1131 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001132
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 var c = MyCar.new("abc")
1134 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001136 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001137
1138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001139 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001141 class Foo
1142 this.x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001143
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001144 def Add(n: number): any
1145 this.x->add(n)
1146 return this
1147 enddef
1148 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001150 echo Foo.new().Add(1).Add(2).x
1151 echo Foo.new().Add(1).Add(2)
1152 .x
1153 echo Foo.new().Add(1)
1154 .Add(2).x
1155 echo Foo.new()
1156 .Add(1).Add(2).x
1157 echo Foo.new()
1158 .Add(1)
1159 .Add(2)
1160 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001161 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001162 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001163
1164 # Test for "public" cannot be abbreviated
1165 lines =<< trim END
1166 vim9script
1167 class Something
1168 pub this.val = 1
1169 endclass
1170 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001171 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001172
1173 # Test for "public" keyword must be followed by "this" or "static".
1174 lines =<< trim END
1175 vim9script
1176 class Something
1177 public val = 1
1178 endclass
1179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001180 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001181
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001182 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001183 lines =<< trim END
1184 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001185 class A
1186 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001187 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001188 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001191
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001192 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001193 lines =<< trim END
1194 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001195 class A
1196 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001197 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001198 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001201
1202 # Modify a instance variable using the class name in a def function
1203 lines =<< trim END
1204 vim9script
1205 class A
1206 public this.val = 1
1207 endclass
1208 def T()
1209 A.val = 1
1210 enddef
1211 T()
1212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001213 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214
1215 # Read a instance variable using the class name in a def function
1216 lines =<< trim END
1217 vim9script
1218 class A
1219 public this.val = 1
1220 endclass
1221 def T()
1222 var i = A.val
1223 enddef
1224 T()
1225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001227
1228 # Access from child class extending a class:
1229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001230 vim9script
1231 class A
1232 this.ro_obj_var = 10
1233 public this.rw_obj_var = 20
1234 this._priv_obj_var = 30
1235 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001237 class B extends A
1238 def Foo()
1239 var x: number
1240 x = this.ro_obj_var
1241 this.ro_obj_var = 0
1242 x = this.rw_obj_var
1243 this.rw_obj_var = 0
1244 x = this._priv_obj_var
1245 this._priv_obj_var = 0
1246 enddef
1247 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 var b = B.new()
1250 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001251 END
1252 v9.CheckSourceSuccess(lines)
1253enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001254
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001255" Test for class variable access
1256def Test_class_variable_access()
1257 # Test for "static" cannot be abbreviated
1258 var lines =<< trim END
1259 vim9script
1260 class Something
1261 stat this.val = 1
1262 endclass
1263 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001264 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001265
1266 # Test for "static" cannot be followed by "this".
1267 lines =<< trim END
1268 vim9script
1269 class Something
1270 static this.val = 1
1271 endclass
1272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001274
1275 # Test for "static" cannot be followed by "public".
1276 lines =<< trim END
1277 vim9script
1278 class Something
1279 static public val = 1
1280 endclass
1281 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001282 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001283
1284 # A readonly class variable cannot be modified from a child class
1285 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 vim9script
1287 class A
1288 static ro_class_var = 40
1289 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001290
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001291 class B extends A
1292 def Foo()
1293 A.ro_class_var = 50
1294 enddef
1295 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001297 var b = B.new()
1298 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001299 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001301
1302 # A private class variable cannot be accessed from a child class
1303 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001304 vim9script
1305 class A
1306 static _priv_class_var = 60
1307 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001309 class B extends A
1310 def Foo()
1311 var i = A._priv_class_var
1312 enddef
1313 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001314
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001315 var b = B.new()
1316 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001317 END
Ernie Rael64885642023-10-04 20:16:22 +02001318 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001319
1320 # A private class variable cannot be modified from a child class
1321 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001322 vim9script
1323 class A
1324 static _priv_class_var = 60
1325 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001327 class B extends A
1328 def Foo()
1329 A._priv_class_var = 0
1330 enddef
1331 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001332
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001333 var b = B.new()
1334 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001335 END
Ernie Rael64885642023-10-04 20:16:22 +02001336 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001337
1338 # Access from child class extending a class and from script context
1339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 vim9script
1341 class A
1342 static ro_class_var = 10
1343 public static rw_class_var = 20
1344 static _priv_class_var = 30
1345 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001347 class B extends A
1348 def Foo()
1349 var x: number
1350 x = A.ro_class_var
1351 assert_equal(10, x)
1352 x = A.rw_class_var
1353 assert_equal(25, x)
1354 A.rw_class_var = 20
1355 assert_equal(20, A.rw_class_var)
1356 enddef
1357 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 assert_equal(10, A.ro_class_var)
1360 assert_equal(20, A.rw_class_var)
1361 A.rw_class_var = 25
1362 assert_equal(25, A.rw_class_var)
1363 var b = B.new()
1364 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 END
1366 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001367enddef
1368
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001369def Test_class_object_compare()
1370 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001371 vim9script
1372 class Item
1373 this.nr = 0
1374 this.name = 'xx'
1375 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001376 END
1377
1378 # used at the script level and in a compiled function
1379 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001380 var i1 = Item.new()
1381 assert_equal(i1, i1)
1382 assert_true(i1 is i1)
1383 var i2 = Item.new()
1384 assert_equal(i1, i2)
1385 assert_false(i1 is i2)
1386 var i3 = Item.new(0, 'xx')
1387 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001388
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001389 var io1 = Item.new(1, 'xx')
1390 assert_notequal(i1, io1)
1391 var io2 = Item.new(0, 'yy')
1392 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001393 END
1394
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001395 v9.CheckSourceSuccess(class_lines + test_lines)
1396 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001397 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001398
1399 for op in ['>', '>=', '<', '<=', '=~', '!~']
1400 var op_lines = [
1401 'var i1 = Item.new()',
1402 'var i2 = Item.new()',
1403 'echo i1 ' .. op .. ' i2',
1404 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001407 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001408 endfor
1409enddef
1410
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001411def Test_object_type()
1412 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001413 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001414
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001415 class One
1416 this.one = 1
1417 endclass
1418 class Two
1419 this.two = 2
1420 endclass
1421 class TwoMore extends Two
1422 this.more = 9
1423 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001425 var o: One = One.new()
1426 var t: Two = Two.new()
1427 var m: TwoMore = TwoMore.new()
1428 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001429
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001430 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001431 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001433
1434 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
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001443
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001445 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001447
1448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001449 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001451 interface One
1452 def GetMember(): number
1453 endinterface
1454 class Two implements One
1455 this.one = 1
1456 def GetMember(): number
1457 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001458 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001460
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001461 var o: One = Two.new(5)
1462 assert_equal(5, o.GetMember())
1463 END
1464 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001466 lines =<< trim END
1467 vim9script
1468
1469 class Num
1470 this.n: number = 0
1471 endclass
1472
1473 def Ref(name: string): func(Num): Num
1474 return (arg: Num): Num => {
1475 return eval(name)(arg)
1476 }
1477 enddef
1478
1479 const Fn = Ref('Double')
1480 var Double = (m: Num): Num => Num.new(m.n * 2)
1481
1482 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001483 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001484 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001485enddef
1486
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001487def Test_class_member()
1488 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001489 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 vim9script
1491 class TextPos
1492 this.lnum = 1
1493 this.col = 1
1494 static counter = 0
1495 static _secret = 7
1496 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 static def AddToCounter(nr: number)
1499 counter += nr
1500 enddef
1501 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001502
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001503 assert_equal(0, TextPos.counter)
1504 TextPos.AddToCounter(3)
1505 assert_equal(3, TextPos.counter)
1506 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 def GetCounter(): number
1509 return TextPos.counter
1510 enddef
1511 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1514 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1515 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001516
Ernie Rael64885642023-10-04 20:16:22 +02001517 assert_fails('echo TextPos._secret', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
1518 assert_fails('TextPos._secret = 8', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001519
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 assert_equal(42, TextPos.anybody)
1521 TextPos.anybody = 12
1522 assert_equal(12, TextPos.anybody)
1523 TextPos.anybody += 5
1524 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001525 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001527
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001528 # example in the help
1529 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 vim9script
1531 class OtherThing
1532 this.size: number
1533 static totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 def new(this.size)
1536 totalSize += this.size
1537 enddef
1538 endclass
1539 assert_equal(0, OtherThing.totalSize)
1540 var to3 = OtherThing.new(3)
1541 assert_equal(3, OtherThing.totalSize)
1542 var to7 = OtherThing.new(7)
1543 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001544 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001545 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001546
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001547 # using static class member twice
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001550
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 class HTML
1552 static author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 static def MacroSubstitute(s: string): string
1555 return substitute(s, '{{author}}', author, 'gi')
1556 enddef
1557 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001559 assert_equal('some text', HTML.MacroSubstitute('some text'))
1560 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001561 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001562 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001563
Bram Moolenaar62a69232023-01-24 15:07:04 +00001564 # access private member in lambda
1565 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001566 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 class Foo
1569 this._x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001570
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 def Add(n: number): number
1572 const F = (): number => this._x + n
1573 return F()
1574 enddef
1575 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001576
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001577 var foo = Foo.new()
1578 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001579 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001580 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001581
h-east2bd6a092023-05-19 19:01:17 +01001582 # access private member in lambda body
1583 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001585
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 class Foo
1587 this._x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001588
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 def Add(n: number): number
1590 var Lam = () => {
1591 this._x = this._x + n
1592 }
1593 Lam()
1594 return this._x
1595 enddef
1596 endclass
h-east2bd6a092023-05-19 19:01:17 +01001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var foo = Foo.new()
1599 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001600 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001601 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001602
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001603 # check shadowing
1604 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001605 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001606
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001607 class Some
1608 static count = 0
1609 def Method(count: number)
1610 echo count
1611 enddef
1612 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 var s = Some.new()
1615 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001617 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001618
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001619 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001620 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001622
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001623 class Some
1624 static count = 0
1625 def Method(arg: number)
1626 var count = 3
1627 echo arg count
1628 enddef
1629 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001630
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 var s = Some.new()
1632 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001635
1636 # Test for using an invalid type for a member variable
1637 lines =<< trim END
1638 vim9script
1639 class A
1640 this.val: xxx
1641 endclass
1642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001643 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001644
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001645 # Test for setting a member on a null object
1646 lines =<< trim END
1647 vim9script
1648 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001649 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001650 endclass
1651
1652 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var obj: A
1654 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001655 enddef
1656 F()
1657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001659
1660 # Test for accessing a member on a null object
1661 lines =<< trim END
1662 vim9script
1663 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001664 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001665 endclass
1666
1667 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 var obj: A
1669 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001670 enddef
1671 F()
1672 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001673 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001674
1675 # Test for setting a member on a null object, at script level
1676 lines =<< trim END
1677 vim9script
1678 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001680 endclass
1681
1682 var obj: A
1683 obj.val = ""
1684 END
1685 # FIXME(in source): this should give E1360 as well!
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001687
1688 # Test for accessing a member on a null object, at script level
1689 lines =<< trim END
1690 vim9script
1691 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001692 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001693 endclass
1694
1695 var obj: A
1696 echo obj.val
1697 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001698 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001699
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001700 # Test for no space before or after the '=' when initializing a member
1701 # variable
1702 lines =<< trim END
1703 vim9script
1704 class A
1705 this.val: number= 10
1706 endclass
1707 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001709 lines =<< trim END
1710 vim9script
1711 class A
1712 this.val: number =10
1713 endclass
1714 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001716
1717 # Access a non-existing member
1718 lines =<< trim END
1719 vim9script
1720 class A
1721 endclass
1722 var a = A.new()
1723 var v = a.bar
1724 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": bar', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001726enddef
1727
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001728func Test_class_garbagecollect()
1729 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001730 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001731
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001732 class Point
1733 this.p = [2, 3]
1734 static pl = ['a', 'b']
1735 static pd = {a: 'a', b: 'b'}
1736 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001737
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001738 echo Point.pl Point.pd
1739 call test_garbagecollect_now()
1740 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001742 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001743
1744 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001745 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001746
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001747 interface View
1748 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001750 class Widget
1751 this.view: View
1752 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 class MyView implements View
1755 this.widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001756
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001757 def new()
1758 # this will result in a circular reference to this object
1759 this.widget = Widget.new(this)
1760 enddef
1761 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001764
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001765 # overwrite "view", will be garbage-collected next
1766 view = MyView.new()
1767 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001768 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001769 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001770endfunc
1771
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001772" Test interface garbage collection
1773func Test_interface_garbagecollect()
1774 let lines =<< trim END
1775 vim9script
1776
1777 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001778 this.ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001779
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001780 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001781 endinterface
1782
1783 class A implements I
1784 static ro_class_var: number = 10
1785 public static rw_class_var: number = 20
1786 static _priv_class_var: number = 30
1787 this.ro_obj_var: number = 40
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001788 this._priv_obj_var: number = 60
1789
1790 static def _ClassBar(): number
1791 return _priv_class_var
1792 enddef
1793
1794 static def ClassFoo(): number
1795 return ro_class_var + rw_class_var + A._ClassBar()
1796 enddef
1797
1798 def _ObjBar(): number
1799 return this._priv_obj_var
1800 enddef
1801
1802 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001803 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001804 enddef
1805 endclass
1806
1807 assert_equal(60, A.ClassFoo())
1808 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001809 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001810 test_garbagecollect_now()
1811 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001812 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001813 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001814 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001815endfunc
1816
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001817def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001818 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001819 vim9script
1820 class Value
1821 this.value = 0
1822 static objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001823
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001824 def new(v: number)
1825 this.value = v
1826 ++objects
1827 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001828
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001829 static def GetCount(): number
1830 return objects
1831 enddef
1832 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001833
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 assert_equal(0, Value.GetCount())
1835 var v1 = Value.new(2)
1836 assert_equal(1, Value.GetCount())
1837 var v2 = Value.new(7)
1838 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001839 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001840 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001841
1842 # Test for cleaning up after a class definition failure when using class
1843 # functions.
1844 lines =<< trim END
1845 vim9script
1846 class A
1847 static def Foo()
1848 enddef
1849 aaa
1850 endclass
1851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001852 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001853
1854 # Test for calling a class method from another class method without the class
1855 # name prefix.
1856 lines =<< trim END
1857 vim9script
1858 class A
1859 static myList: list<number> = [1]
1860 static def Foo(n: number)
1861 myList->add(n)
1862 enddef
1863 static def Bar()
1864 Foo(2)
1865 enddef
1866 def Baz()
1867 Foo(3)
1868 enddef
1869 endclass
1870 A.Bar()
1871 var a = A.new()
1872 a.Baz()
1873 assert_equal([1, 2, 3], A.myList)
1874 END
1875 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001876enddef
1877
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001878def Test_class_defcompile()
1879 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001880 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001881
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001882 class C
1883 def Fo(i: number): string
1884 return i
1885 enddef
1886 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001888 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001889 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001890 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001891
1892 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001893 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001894
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001895 class C
1896 static def Fc(): number
1897 return 'x'
1898 enddef
1899 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001900
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001901 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001903 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001904
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001905 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001906 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001907
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001908 class C
1909 static def new()
1910 enddef
1911 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001912
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001913 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001914 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001915 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001916
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001917 # Trying to compile a function using a non-existing class variable
1918 lines =<< trim END
1919 vim9script
1920 defcompile x.Foo()
1921 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001922 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001923
1924 # Trying to compile a function using a variable which is not a class
1925 lines =<< trim END
1926 vim9script
1927 var x: number
1928 defcompile x.Foo()
1929 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001930 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001931
1932 # Trying to compile a function without specifying the name
1933 lines =<< trim END
1934 vim9script
1935 class A
1936 endclass
1937 defcompile A.
1938 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001939 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001940
1941 # Trying to compile a non-existing class object member function
1942 lines =<< trim END
1943 vim9script
1944 class A
1945 endclass
1946 var a = A.new()
1947 defcompile a.Foo()
1948 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001949 v9.CheckSourceFailureList(lines, ['E1326: Variable not found on object "A": Foo', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001950enddef
1951
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001952def Test_class_object_to_string()
1953 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001954 vim9script
1955 class TextPosition
1956 this.lnum = 1
1957 this.col = 22
1958 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001960 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001962 var pos = TextPosition.new()
1963 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001964 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001965 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001966enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001967
Bram Moolenaar554d0312023-01-05 19:59:18 +00001968def Test_interface_basics()
1969 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001970 vim9script
1971 interface Something
1972 this.ro_var: list<number>
1973 def GetCount(): number
1974 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00001975 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001976 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001977
1978 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001979 interface SomethingWrong
1980 static count = 7
1981 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00001982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001983 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001984
1985 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001986 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00001987
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001988 interface Some
1989 this.value: number
1990 def Method(value: number)
1991 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001992 END
h-east61378a12023-04-18 19:07:29 +01001993 # The argument name and the object member name are the same, but this is not a
1994 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001995 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001996
1997 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001998 vim9script
1999 interface somethingWrong
2000 static count = 7
2001 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002003 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002004
2005 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002006 vim9script
2007 interface SomethingWrong
2008 this.value: string
2009 this.count = 7
2010 def GetCount(): number
2011 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002012 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002013 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002014
2015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 vim9script
2017 interface SomethingWrong
2018 this.value: string
2019 this.count: number
2020 def GetCount(): number
2021 return 5
2022 enddef
2023 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002024 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002025 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002026
2027 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002028 vim9script
2029 export interface EnterExit
2030 def Enter(): void
2031 def Exit(): void
2032 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002033 END
2034 writefile(lines, 'XdefIntf.vim', 'D')
2035
2036 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 vim9script
2038 import './XdefIntf.vim' as defIntf
2039 export def With(ee: defIntf.EnterExit, F: func)
2040 ee.Enter()
2041 try
2042 F()
2043 finally
2044 ee.Exit()
2045 endtry
2046 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002047 END
2048 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002049
2050 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002051 vim9script
2052 export abstract class EnterExit
2053 def Enter(): void
2054 enddef
2055 def Exit(): void
2056 enddef
2057 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002058 END
2059 writefile(imported, 'XdefIntf2.vim', 'D')
2060
2061 lines[1] = " import './XdefIntf2.vim' as defIntf"
2062 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002063enddef
2064
Bram Moolenaar94674f22023-01-06 18:42:20 +00002065def Test_class_implements_interface()
2066 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002067 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002068
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002069 interface Some
2070 this.count: number
2071 def Method(nr: number)
2072 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002073
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002074 class SomeImpl implements Some
2075 this.count: number
2076 def Method(nr: number)
2077 echo nr
2078 enddef
2079 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002080
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002081 interface Another
2082 this.member: string
2083 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002085 class AnotherImpl implements Some, Another
2086 this.member = 'abc'
2087 this.count = 20
2088 def Method(nr: number)
2089 echo nr
2090 enddef
2091 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002092 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002093 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002094
2095 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002096 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002097
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002098 interface Some
2099 this.count: number
2100 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002101
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002102 class SomeImpl implements Some implements Some
2103 this.count: number
2104 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002105 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002106 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002107
2108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002109 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002111 interface Some
2112 this.count: number
2113 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002114
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002115 class SomeImpl implements Some, Some
2116 this.count: number
2117 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002118 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002120
2121 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002122 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002123
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002124 interface Some
2125 this.counter: number
2126 def Method(nr: number)
2127 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002128
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002129 class SomeImpl implements Some
2130 this.count: number
2131 def Method(nr: number)
2132 echo nr
2133 enddef
2134 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002136 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002137
2138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002139 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002141 interface Some
2142 this.count: number
2143 def Methods(nr: number)
2144 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002145
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002146 class SomeImpl implements Some
2147 this.count: number
2148 def Method(nr: number)
2149 echo nr
2150 enddef
2151 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002153 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002154
2155 # Check different order of members in class and interface works.
2156 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002157 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002158
2159 interface Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002160 this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002161 this.errpos: number
2162 endinterface
2163
2164 # order of members is opposite of interface
2165 class Failure implements Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002166 public this.lnum: number = 5
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002167 this.errpos: number = 42
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002168 this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002169 endclass
2170
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 def Test()
2172 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002173
2174 assert_equal('label', result.label)
2175 assert_equal(42, result.errpos)
2176 enddef
2177
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002178 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002181
2182 # Interface name after "extends" doesn't end in a space or NUL character
2183 lines =<< trim END
2184 vim9script
2185 interface A
2186 endinterface
2187 class B extends A"
2188 endclass
2189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002190 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002191
2192 # Trailing characters after a class name
2193 lines =<< trim END
2194 vim9script
2195 class A bbb
2196 endclass
2197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002199
2200 # using "implements" with a non-existing class
2201 lines =<< trim END
2202 vim9script
2203 class A implements B
2204 endclass
2205 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002206 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002207
2208 # using "implements" with a regular class
2209 lines =<< trim END
2210 vim9script
2211 class A
2212 endclass
2213 class B implements A
2214 endclass
2215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002217
2218 # using "implements" with a variable
2219 lines =<< trim END
2220 vim9script
2221 var T: number = 10
2222 class A implements T
2223 endclass
2224 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002225 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002226
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002227 # implements should be followed by a white space
2228 lines =<< trim END
2229 vim9script
2230 interface A
2231 endinterface
2232 class B implements A;
2233 endclass
2234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002235 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002236
LemonBoyc5d27442023-08-19 13:02:35 +02002237 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002238 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002240 interface One
2241 def IsEven(nr: number): bool
2242 endinterface
2243 class Two implements One
2244 def IsEven(nr: number): string
2245 enddef
2246 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002247 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002248 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002249
2250 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002252
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002253 interface One
2254 def IsEven(nr: number): bool
2255 endinterface
2256 class Two implements One
2257 def IsEven(nr: bool): bool
2258 enddef
2259 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002260 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002261 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002262
2263 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002265
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 interface One
2267 def IsEven(nr: number): bool
2268 endinterface
2269 class Two implements One
2270 def IsEven(nr: number, ...extra: list<number>): bool
2271 enddef
2272 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002273 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002274 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 +02002275
2276 # access superclass interface members from subclass, mix variable order
2277 lines =<< trim END
2278 vim9script
2279
2280 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 this.mvar1: number
2282 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002283 endinterface
2284
2285 # NOTE: the order is swapped
2286 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002287 this.mvar2: number
2288 this.mvar1: number
2289 public static svar2: number
2290 public static svar1: number
2291 def new()
2292 svar1 = 11
2293 svar2 = 12
2294 this.mvar1 = 111
2295 this.mvar2 = 112
2296 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002297 endclass
2298
2299 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002300 def new()
2301 this.mvar1 = 121
2302 this.mvar2 = 122
2303 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002304 endclass
2305
2306 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002307 def new()
2308 this.mvar1 = 131
2309 this.mvar2 = 132
2310 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002311 endclass
2312
Ernie Raelcf138d42023-09-06 20:45:03 +02002313 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002314 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002315 enddef
2316
2317 var oa = A.new()
2318 var ob = B.new()
2319 var oc = C.new()
2320
Ernie Raelcf138d42023-09-06 20:45:03 +02002321 assert_equal([111, 112], F2(oa))
2322 assert_equal([121, 122], F2(ob))
2323 assert_equal([131, 132], F2(oc))
2324 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002325 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002326
2327 # Access superclass interface members from subclass, mix variable order.
2328 # Two interfaces, one on A, one on B; each has both kinds of variables
2329 lines =<< trim END
2330 vim9script
2331
2332 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002333 this.mvar1: number
2334 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002335 endinterface
2336
2337 interface I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 this.mvar3: number
2339 this.mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002340 endinterface
2341
2342 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 public static svar1: number
2344 public static svar2: number
2345 this.mvar1: number
2346 this.mvar2: number
2347 def new()
2348 svar1 = 11
2349 svar2 = 12
2350 this.mvar1 = 111
2351 this.mvar2 = 112
2352 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002353 endclass
2354
2355 class B extends A implements I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002356 static svar3: number
2357 static svar4: number
2358 this.mvar3: number
2359 this.mvar4: number
2360 def new()
2361 svar3 = 23
2362 svar4 = 24
2363 this.mvar1 = 121
2364 this.mvar2 = 122
2365 this.mvar3 = 123
2366 this.mvar4 = 124
2367 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002368 endclass
2369
2370 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002371 public static svar5: number
2372 def new()
2373 svar5 = 1001
2374 this.mvar1 = 131
2375 this.mvar2 = 132
2376 this.mvar3 = 133
2377 this.mvar4 = 134
2378 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002379 endclass
2380
Ernie Raelcf138d42023-09-06 20:45:03 +02002381 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002383 enddef
2384
Ernie Raelcf138d42023-09-06 20:45:03 +02002385 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002386 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002387 enddef
2388
Ernie Raelcf138d42023-09-06 20:45:03 +02002389 var oa = A.new()
2390 var ob = B.new()
2391 var oc = C.new()
2392
Ernie Raelcf138d42023-09-06 20:45:03 +02002393 assert_equal([[111, 112]], [F2(oa)])
2394 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2395 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002396 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002397 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002398
2399 # Using two interface names without a space after the ","
2400 lines =<< trim END
2401 vim9script
2402 interface A
2403 endinterface
2404 interface B
2405 endinterface
2406 class C implements A,B
2407 endclass
2408 END
2409 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2410
2411 # No interface name after a comma
2412 lines =<< trim END
2413 vim9script
2414 interface A
2415 endinterface
2416 class B implements A,
2417 endclass
2418 END
2419 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2420
2421 # No interface name after implements
2422 lines =<< trim END
2423 vim9script
2424 class A implements
2425 endclass
2426 END
2427 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002428enddef
2429
Bram Moolenaard0200c82023-01-28 15:19:40 +00002430def Test_call_interface_method()
2431 var lines =<< trim END
2432 vim9script
2433 interface Base
2434 def Enter(): void
2435 endinterface
2436
2437 class Child implements Base
2438 def Enter(): void
2439 g:result ..= 'child'
2440 enddef
2441 endclass
2442
2443 def F(obj: Base)
2444 obj.Enter()
2445 enddef
2446
2447 g:result = ''
2448 F(Child.new())
2449 assert_equal('child', g:result)
2450 unlet g:result
2451 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002452 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002453
2454 lines =<< trim END
2455 vim9script
2456 class Base
2457 def Enter(): void
2458 g:result ..= 'base'
2459 enddef
2460 endclass
2461
2462 class Child extends Base
2463 def Enter(): void
2464 g:result ..= 'child'
2465 enddef
2466 endclass
2467
2468 def F(obj: Base)
2469 obj.Enter()
2470 enddef
2471
2472 g:result = ''
2473 F(Child.new())
2474 assert_equal('child', g:result)
2475 unlet g:result
2476 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002477 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002478
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002479 # method of interface returns a value
2480 lines =<< trim END
2481 vim9script
2482 interface Base
2483 def Enter(): string
2484 endinterface
2485
2486 class Child implements Base
2487 def Enter(): string
2488 g:result ..= 'child'
2489 return "/resource"
2490 enddef
2491 endclass
2492
2493 def F(obj: Base)
2494 var r = obj.Enter()
2495 g:result ..= r
2496 enddef
2497
2498 g:result = ''
2499 F(Child.new())
2500 assert_equal('child/resource', g:result)
2501 unlet g:result
2502 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002503 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002504
2505 lines =<< trim END
2506 vim9script
2507 class Base
2508 def Enter(): string
2509 return null_string
2510 enddef
2511 endclass
2512
2513 class Child extends Base
2514 def Enter(): string
2515 g:result ..= 'child'
2516 return "/resource"
2517 enddef
2518 endclass
2519
2520 def F(obj: Base)
2521 var r = obj.Enter()
2522 g:result ..= r
2523 enddef
2524
2525 g:result = ''
2526 F(Child.new())
2527 assert_equal('child/resource', g:result)
2528 unlet g:result
2529 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002530 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002531
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002532 # No class that implements the interface.
2533 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002536 interface IWithEE
2537 def Enter(): any
2538 def Exit(): void
2539 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002540
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002541 def With1(ee: IWithEE, F: func)
2542 var r = ee.Enter()
2543 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002544
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002545 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002547 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002548enddef
2549
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002550def Test_class_used_as_type()
2551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002552 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002554 class Point
2555 this.x = 0
2556 this.y = 0
2557 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002559 var p: Point
2560 p = Point.new(2, 33)
2561 assert_equal(2, p.x)
2562 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002563 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002564 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002565
2566 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002567 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002568
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 interface HasX
2570 this.x: number
2571 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002572
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002573 class Point implements HasX
2574 this.x = 0
2575 this.y = 0
2576 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002577
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002578 var p: Point
2579 p = Point.new(2, 33)
2580 var hx = p
2581 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002582 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002583 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002584
2585 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002586 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002587
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 class Point
2589 this.x = 0
2590 this.y = 0
2591 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002593 var p: Point
2594 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002596 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002597enddef
2598
Bram Moolenaar83677162023-01-08 19:54:10 +00002599def Test_class_extends()
2600 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002601 vim9script
2602 class Base
2603 this.one = 1
2604 def GetOne(): number
2605 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002606 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 endclass
2608 class Child extends Base
2609 this.two = 2
2610 def GetTotal(): number
2611 return this.one + this.two
2612 enddef
2613 endclass
2614 var o = Child.new()
2615 assert_equal(1, o.one)
2616 assert_equal(2, o.two)
2617 assert_equal(1, o.GetOne())
2618 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002619 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002620 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002621
2622 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002623 vim9script
2624 class Base
2625 this.one = 1
2626 endclass
2627 class Child extends Base
2628 this.two = 2
2629 endclass
2630 var o = Child.new(3, 44)
2631 assert_equal(3, o.one)
2632 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002634 v9.CheckSourceSuccess(lines)
2635
2636 lines =<< trim END
2637 vim9script
2638 class Base
2639 this.one = 1
2640 endclass
2641 class Child extends Base extends Base
2642 this.two = 2
2643 endclass
2644 END
2645 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2646
2647 lines =<< trim END
2648 vim9script
2649 class Child extends BaseClass
2650 this.two = 2
2651 endclass
2652 END
2653 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2654
2655 lines =<< trim END
2656 vim9script
2657 var SomeVar = 99
2658 class Child extends SomeVar
2659 this.two = 2
2660 endclass
2661 END
2662 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2663
2664 lines =<< trim END
2665 vim9script
2666 class Base
2667 this.name: string
2668 def ToString(): string
2669 return this.name
2670 enddef
2671 endclass
2672
2673 class Child extends Base
2674 this.age: number
2675 def ToString(): string
2676 return super.ToString() .. ': ' .. this.age
2677 enddef
2678 endclass
2679
2680 var o = Child.new('John', 42)
2681 assert_equal('John: 42', o.ToString())
2682 END
2683 v9.CheckSourceSuccess(lines)
2684
2685 lines =<< trim END
2686 vim9script
2687 class Child
2688 this.age: number
2689 def ToString(): number
2690 return this.age
2691 enddef
2692 def ToString(): string
2693 return this.age
2694 enddef
2695 endclass
2696 END
2697 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2698
2699 lines =<< trim END
2700 vim9script
2701 class Child
2702 this.age: number
2703 def ToString(): string
2704 return super .ToString() .. ': ' .. this.age
2705 enddef
2706 endclass
2707 var o = Child.new(42)
2708 echo o.ToString()
2709 END
2710 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2711
2712 lines =<< trim END
2713 vim9script
2714 class Base
2715 this.name: string
2716 def ToString(): string
2717 return this.name
2718 enddef
2719 endclass
2720
2721 var age = 42
2722 def ToString(): string
2723 return super.ToString() .. ': ' .. age
2724 enddef
2725 echo ToString()
2726 END
2727 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2728
2729 lines =<< trim END
2730 vim9script
2731 class Child
2732 this.age: number
2733 def ToString(): string
2734 return super.ToString() .. ': ' .. this.age
2735 enddef
2736 endclass
2737 var o = Child.new(42)
2738 echo o.ToString()
2739 END
2740 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2741
2742 lines =<< trim END
2743 vim9script
2744 class Base
2745 this.name: string
2746 static def ToString(): string
2747 return 'Base class'
2748 enddef
2749 endclass
2750
2751 class Child extends Base
2752 this.age: number
2753 def ToString(): string
2754 return Base.ToString() .. ': ' .. this.age
2755 enddef
2756 endclass
2757
2758 var o = Child.new('John', 42)
2759 assert_equal('Base class: 42', o.ToString())
2760 END
2761 v9.CheckSourceSuccess(lines)
2762
2763 lines =<< trim END
2764 vim9script
2765 class Base
2766 this.value = 1
2767 def new(init: number)
2768 this.value = number + 1
2769 enddef
2770 endclass
2771 class Child extends Base
2772 def new()
2773 this.new(3)
2774 enddef
2775 endclass
2776 var c = Child.new()
2777 END
2778 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002779
2780 # base class with more than one object member
2781 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002782 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 class Result
2785 this.success: bool
2786 this.value: any = null
2787 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002788
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002789 class Success extends Result
2790 def new(this.value = v:none)
2791 this.success = true
2792 enddef
2793 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002794
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002795 var v = Success.new('asdf')
2796 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002797 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002798 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002799
2800 # class name after "extends" doesn't end in a space or NUL character
2801 lines =<< trim END
2802 vim9script
2803 class A
2804 endclass
2805 class B extends A"
2806 endclass
2807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002808 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00002809enddef
2810
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002811def Test_using_base_class()
2812 var lines =<< trim END
2813 vim9script
2814
2815 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002816 def Enter(): any
2817 return null
2818 enddef
2819 def Exit(resource: any): void
2820 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002821 endclass
2822
2823 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002824 def Enter(): any
2825 return 42
2826 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002827
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002828 def Exit(resource: number): void
2829 g:result ..= '/exit'
2830 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002831 endclass
2832
2833 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002834 var r = ee.Enter()
2835 try
2836 g:result ..= r
2837 finally
2838 g:result ..= '/finally'
2839 ee.Exit(r)
2840 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002841 enddef
2842
2843 g:result = ''
2844 With(ChildEE.new())
2845 assert_equal('42/finally/exit', g:result)
2846 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002847 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002848 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002849
2850 # Using super, Child invokes Base method which has optional arg. #12471
2851 lines =<< trim END
2852 vim9script
2853
2854 class Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002855 this.success: bool = false
2856 def Method(arg = 0)
2857 this.success = true
2858 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002859 endclass
2860
2861 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002862 def new()
2863 super.Method()
2864 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002865 endclass
2866
2867 var obj = Child.new()
2868 assert_equal(true, obj.success)
2869 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002870 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002871enddef
2872
Bram Moolenaara86655a2023-01-12 17:06:27 +00002873def Test_class_import()
2874 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002875 vim9script
2876 export class Animal
2877 this.kind: string
2878 this.name: string
2879 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00002880 END
2881 writefile(lines, 'Xanimal.vim', 'D')
2882
2883 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002884 vim9script
2885 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00002886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002887 var a: animal.Animal
2888 a = animal.Animal.new('fish', 'Eric')
2889 assert_equal('fish', a.kind)
2890 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002891
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002892 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2893 assert_equal('cat', b.kind)
2894 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002895 END
2896 v9.CheckScriptSuccess(lines)
2897enddef
2898
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002899def Test_abstract_class()
2900 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002901 vim9script
2902 abstract class Base
2903 this.name: string
2904 endclass
2905 class Person extends Base
2906 this.age: number
2907 endclass
2908 var p: Base = Person.new('Peter', 42)
2909 assert_equal('Peter', p.name)
2910 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002912 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002913
2914 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002915 vim9script
2916 abstract class Base
2917 this.name: string
2918 endclass
2919 class Person extends Base
2920 this.age: number
2921 endclass
2922 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002923 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002924 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002925
2926 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002927 abstract class Base
2928 this.name: string
2929 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002930 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002931 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002932
2933 # Abstract class cannot have a "new" function
2934 lines =<< trim END
2935 vim9script
2936 abstract class Base
2937 def new()
2938 enddef
2939 endclass
2940 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002942enddef
2943
Bram Moolenaar486fc252023-01-18 14:51:07 +00002944def Test_closure_in_class()
2945 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002946 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00002947
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002948 class Foo
2949 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00002950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002951 def new()
2952 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2953 enddef
2954 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00002955
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002956 Foo.new()
2957 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00002958 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002959 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00002960enddef
2961
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002962def Test_call_constructor_from_legacy()
2963 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002964 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002965
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002966 var newCalled = 'false'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002967
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 class A
2969 def new()
2970 newCalled = 'true'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002971 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002972 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002973
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002974 export def F(options = {}): any
2975 return A
2976 enddef
2977
2978 g:p = F()
2979 legacy call p.new()
2980 assert_equal('true', newCalled)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002981 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002982 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002983enddef
2984
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002985def Test_defer_with_object()
2986 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002987 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002988
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 class CWithEE
2990 def Enter()
2991 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002992 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002993 def Exit()
2994 g:result ..= "exited"
2995 enddef
2996 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002997
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002998 def With(ee: CWithEE, F: func)
2999 ee.Enter()
3000 defer ee.Exit()
3001 F()
3002 enddef
3003
3004 g:result = ''
3005 var obj = CWithEE.new()
3006 obj->With(() => {
3007 g:result ..= "called/"
3008 })
3009 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003011 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003012 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003013
3014 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003015 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003016
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003017 class BaseWithEE
3018 def Enter()
3019 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003020 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 def Exit()
3022 g:result ..= "exited-base"
3023 enddef
3024 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003026 class CWithEE extends BaseWithEE
3027 def Enter()
3028 g:result ..= "entered-child/"
3029 enddef
3030 def Exit()
3031 g:result ..= "exited-child"
3032 enddef
3033 endclass
3034
3035 def With(ee: BaseWithEE, F: func)
3036 ee.Enter()
3037 defer ee.Exit()
3038 F()
3039 enddef
3040
3041 g:result = ''
3042 var obj = CWithEE.new()
3043 obj->With(() => {
3044 g:result ..= "called/"
3045 })
3046 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003047 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003048 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003049 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003050enddef
3051
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003052" The following test used to crash Vim (Github issue #12676)
3053def Test_extends_method_crashes_vim()
3054 var lines =<< trim END
3055 vim9script
3056
3057 class Observer
3058 endclass
3059
3060 class Property
3061 this.value: any
3062
3063 def Set(v: any)
3064 if v != this.value
3065 this.value = v
3066 endif
3067 enddef
3068
3069 def Register(observer: Observer)
3070 enddef
3071 endclass
3072
3073 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003074 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003075 endclass
3076
3077 def Observe(obj: Property, who: Observer)
3078 obj.Register(who)
3079 enddef
3080
3081 var p = Bool.new(false)
3082 var myObserver = Observer.new()
3083
3084 Observe(p, myObserver)
3085
3086 p.Set(true)
3087 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003088 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003089enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003090
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003091" Test for calling a method in a class that is extended
3092def Test_call_method_in_extended_class()
3093 var lines =<< trim END
3094 vim9script
3095
3096 var prop_init_called = false
3097 var prop_register_called = false
3098
3099 class Property
3100 def Init()
3101 prop_init_called = true
3102 enddef
3103
3104 def Register()
3105 prop_register_called = true
3106 enddef
3107 endclass
3108
3109 class Bool extends Property
3110 endclass
3111
3112 def Observe(obj: Property)
3113 obj.Register()
3114 enddef
3115
3116 var p = Property.new()
3117 Observe(p)
3118
3119 p.Init()
3120 assert_true(prop_init_called)
3121 assert_true(prop_register_called)
3122 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003123 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003124enddef
3125
LemonBoyafe04662023-08-23 21:08:11 +02003126def Test_instanceof()
3127 var lines =<< trim END
3128 vim9script
3129
3130 class Base1
3131 endclass
3132
3133 class Base2 extends Base1
3134 endclass
3135
3136 interface Intf1
3137 endinterface
3138
3139 class Mix1 implements Intf1
3140 endclass
3141
3142 class Base3 extends Mix1
3143 endclass
3144
3145 var b1 = Base1.new()
3146 var b2 = Base2.new()
3147 var b3 = Base3.new()
3148
3149 assert_true(instanceof(b1, Base1))
3150 assert_true(instanceof(b2, Base1))
3151 assert_false(instanceof(b1, Base2))
3152 assert_true(instanceof(b3, Mix1))
3153 assert_false(instanceof(b3, []))
3154 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003155
3156 def Foo()
3157 var a1 = Base1.new()
3158 var a2 = Base2.new()
3159 var a3 = Base3.new()
3160
3161 assert_true(instanceof(a1, Base1))
3162 assert_true(instanceof(a2, Base1))
3163 assert_false(instanceof(a1, Base2))
3164 assert_true(instanceof(a3, Mix1))
3165 assert_false(instanceof(a3, []))
3166 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3167 enddef
3168 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003169
3170 var o_null: Base1
3171 assert_false(instanceof(o_null, Base1))
3172
LemonBoyafe04662023-08-23 21:08:11 +02003173 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003174 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003175enddef
3176
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003177" Test for calling a method in the parent class that is extended partially.
3178" This used to fail with the 'E118: Too many arguments for function: Text' error
3179" message (Github issue #12524).
3180def Test_call_method_in_parent_class()
3181 var lines =<< trim END
3182 vim9script
3183
3184 class Widget
3185 this._lnum: number = 1
3186
3187 def SetY(lnum: number)
3188 this._lnum = lnum
3189 enddef
3190
3191 def Text(): string
3192 return ''
3193 enddef
3194 endclass
3195
3196 class Foo extends Widget
3197 def Text(): string
3198 return '<Foo>'
3199 enddef
3200 endclass
3201
3202 def Stack(w1: Widget, w2: Widget): list<Widget>
3203 w1.SetY(1)
3204 w2.SetY(2)
3205 return [w1, w2]
3206 enddef
3207
3208 var foo1 = Foo.new()
3209 var foo2 = Foo.new()
3210 var l = Stack(foo1, foo2)
3211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003212 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003213enddef
3214
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003215" Test for calling methods from three levels of classes
3216def Test_multi_level_method_call()
3217 var lines =<< trim END
3218 vim9script
3219
3220 var A_func1: number = 0
3221 var A_func2: number = 0
3222 var A_func3: number = 0
3223 var B_func2: number = 0
3224 var B_func3: number = 0
3225 var C_func3: number = 0
3226
3227 class A
3228 def Func1()
3229 A_func1 += 1
3230 enddef
3231
3232 def Func2()
3233 A_func2 += 1
3234 enddef
3235
3236 def Func3()
3237 A_func3 += 1
3238 enddef
3239 endclass
3240
3241 class B extends A
3242 def Func2()
3243 B_func2 += 1
3244 enddef
3245
3246 def Func3()
3247 B_func3 += 1
3248 enddef
3249 endclass
3250
3251 class C extends B
3252 def Func3()
3253 C_func3 += 1
3254 enddef
3255 endclass
3256
3257 def A_CallFuncs(a: A)
3258 a.Func1()
3259 a.Func2()
3260 a.Func3()
3261 enddef
3262
3263 def B_CallFuncs(b: B)
3264 b.Func1()
3265 b.Func2()
3266 b.Func3()
3267 enddef
3268
3269 def C_CallFuncs(c: C)
3270 c.Func1()
3271 c.Func2()
3272 c.Func3()
3273 enddef
3274
3275 var cobj = C.new()
3276 A_CallFuncs(cobj)
3277 B_CallFuncs(cobj)
3278 C_CallFuncs(cobj)
3279 assert_equal(3, A_func1)
3280 assert_equal(0, A_func2)
3281 assert_equal(0, A_func3)
3282 assert_equal(3, B_func2)
3283 assert_equal(0, B_func3)
3284 assert_equal(3, C_func3)
3285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003286 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003287enddef
3288
3289" Test for using members from three levels of classes
3290def Test_multi_level_member_access()
3291 var lines =<< trim END
3292 vim9script
3293
3294 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003295 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003296 endclass
3297
3298 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003299 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003300 endclass
3301
3302 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003303 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003304 endclass
3305
3306 def A_members(a: A)
3307 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003308 enddef
3309
3310 def B_members(b: B)
3311 b.val1 += 1
3312 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003313 enddef
3314
3315 def C_members(c: C)
3316 c.val1 += 1
3317 c.val2 += 1
3318 c.val3 += 1
3319 enddef
3320
3321 var cobj = C.new()
3322 A_members(cobj)
3323 B_members(cobj)
3324 C_members(cobj)
3325 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003326 assert_equal(2, cobj.val2)
3327 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003328 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003329 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003330enddef
3331
LemonBoy0ffc17a2023-08-20 18:09:11 +02003332" Test expansion of <stack> with class methods.
3333def Test_stack_expansion_with_methods()
3334 var lines =<< trim END
3335 vim9script
3336
3337 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003338 def M1()
3339 F0()
3340 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003341 endclass
3342
3343 def F0()
3344 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3345 enddef
3346
3347 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003348 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003349 enddef
3350
3351 F()
3352 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003353 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003354enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003355
3356" Test the return type of the new() constructor
3357def Test_new_return_type()
3358 # new() uses the default return type and there is no return statement
3359 var lines =<< trim END
3360 vim9script
3361
3362 class C
3363 this._bufnr: number
3364
3365 def new(this._bufnr)
3366 if !bufexists(this._bufnr)
3367 this._bufnr = -1
3368 endif
3369 enddef
3370 endclass
3371
3372 var c = C.new(12345)
3373 assert_equal('object<C>', typename(c))
3374
3375 var v1: C
3376 v1 = C.new(12345)
3377 assert_equal('object<C>', typename(v1))
3378
3379 def F()
3380 var v2: C
3381 v2 = C.new(12345)
3382 assert_equal('object<C>', typename(v2))
3383 enddef
3384 F()
3385 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003386 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003387
3388 # new() uses the default return type and an empty 'return' statement
3389 lines =<< trim END
3390 vim9script
3391
3392 class C
3393 this._bufnr: number
3394
3395 def new(this._bufnr)
3396 if !bufexists(this._bufnr)
3397 this._bufnr = -1
3398 return
3399 endif
3400 enddef
3401 endclass
3402
3403 var c = C.new(12345)
3404 assert_equal('object<C>', typename(c))
3405
3406 var v1: C
3407 v1 = C.new(12345)
3408 assert_equal('object<C>', typename(v1))
3409
3410 def F()
3411 var v2: C
3412 v2 = C.new(12345)
3413 assert_equal('object<C>', typename(v2))
3414 enddef
3415 F()
3416 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003417 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003418
3419 # new() uses "any" return type and returns "this"
3420 lines =<< trim END
3421 vim9script
3422
3423 class C
3424 this._bufnr: number
3425
3426 def new(this._bufnr): any
3427 if !bufexists(this._bufnr)
3428 this._bufnr = -1
3429 return this
3430 endif
3431 enddef
3432 endclass
3433 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003434 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003435
3436 # new() uses 'Dict' return type and returns a Dict
3437 lines =<< trim END
3438 vim9script
3439
3440 class C
3441 this._state: dict<any>
3442
3443 def new(): dict<any>
3444 this._state = {}
3445 return this._state
3446 enddef
3447 endclass
3448
3449 var c = C.new()
3450 assert_equal('object<C>', typename(c))
3451 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003452 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003453enddef
3454
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003455" Test for checking a member initialization type at run time.
3456def Test_runtime_type_check_for_member_init()
3457 var lines =<< trim END
3458 vim9script
3459
3460 var retnum: bool = false
3461
3462 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003463 retnum = !retnum
3464 if retnum
3465 return 1
3466 else
3467 return "hello"
3468 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003469 enddef
3470
3471 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003472 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003473 endclass
3474
3475 var c1 = C.new()
3476 var c2 = C.new()
3477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003478 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003479enddef
3480
3481" Test for locking a variable referring to an object and reassigning to another
3482" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003483def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003484 var lines =<< trim END
3485 vim9script
3486
3487 class C
3488 this.val: number
3489 def new(this.val)
3490 enddef
3491 endclass
3492
3493 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3494 lockvar 2 some_dict
3495
3496 var current: C
3497 current = some_dict['c']
3498 assert_equal(3, current.val)
3499 current = some_dict['b']
3500 assert_equal(2, current.val)
3501
3502 def F()
3503 current = some_dict['c']
3504 enddef
3505
3506 def G()
3507 current = some_dict['b']
3508 enddef
3509
3510 F()
3511 assert_equal(3, current.val)
3512 G()
3513 assert_equal(2, current.val)
3514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003516enddef
3517
Ernie Raelee865f32023-09-29 19:53:55 +02003518" Test trying to lock an object variable from various places
3519def Test_lockvar_object_variable()
3520 # An object variable lockvar has several cases:
3521 # object method, scriptlevel, scriplevel from :def, :def arg
3522 # method arg, static method arg.
3523 # Also different depths
3524
Ernie Raelee865f32023-09-29 19:53:55 +02003525 #
3526 # lockvar of read-only object variable
3527 #
3528
3529 # read-only lockvar from object method
3530 var lines =<< trim END
3531 vim9script
3532
3533 class C
3534 this.val1: number
3535 def Lock()
3536 lockvar this.val1
3537 enddef
3538 endclass
3539 var o = C.new(3)
3540 o.Lock()
3541 END
Ernie Rael64885642023-10-04 20:16:22 +02003542 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003543
3544 # read-only lockvar from scriptlevel
3545 lines =<< trim END
3546 vim9script
3547
3548 class C
3549 this.val2: number
3550 endclass
3551 var o = C.new(3)
3552 lockvar o.val2
3553 END
3554 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3555
3556 # read-only lockvar of scriptlevel variable from def
3557 lines =<< trim END
3558 vim9script
3559
3560 class C
3561 this.val3: number
3562 endclass
3563 var o = C.new(3)
3564 def Lock()
3565 lockvar o.val3
3566 enddef
3567 Lock()
3568 END
3569 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3570
3571 # read-only lockvar of def argument variable
3572 lines =<< trim END
3573 vim9script
3574
3575 class C
3576 this.val4: number
3577 endclass
3578 def Lock(o: C)
3579 lockvar o.val4
3580 enddef
3581 Lock(C.new(3))
3582 END
3583 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3584
3585 # TODO: the following tests use type "any" for argument. Need a run time
3586 # check for access. Probably OK as is for now.
3587
3588 # read-only lockvar from object method arg
3589 lines =<< trim END
3590 vim9script
3591
3592 class C
3593 this.val5: number
3594 def Lock(o_any: any)
3595 lockvar o_any.val5
3596 enddef
3597 endclass
3598 var o = C.new(3)
3599 o.Lock(C.new(5))
3600 END
Ernie Rael64885642023-10-04 20:16:22 +02003601 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003602
3603 # read-only lockvar from class method arg
3604 lines =<< trim END
3605 vim9script
3606
3607 class C
3608 this.val6: number
3609 static def Lock(o_any: any)
3610 lockvar o_any.val6
3611 enddef
3612 endclass
3613 var o = C.new(3)
3614 C.Lock(o)
3615 END
Ernie Rael64885642023-10-04 20:16:22 +02003616 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003617
3618 #
3619 # lockvar of public object variable
3620 #
3621
3622 # lockvar from object method
3623 lines =<< trim END
3624 vim9script
3625
3626 class C
3627 public this.val1: number
3628 def Lock()
3629 lockvar this.val1
3630 enddef
3631 endclass
3632 var o = C.new(3)
3633 o.Lock()
3634 END
3635 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3636
3637 # lockvar from scriptlevel
3638 lines =<< trim END
3639 vim9script
3640
3641 class C
3642 public this.val2: number
3643 endclass
3644 var o = C.new(3)
3645 lockvar o.val2
3646 END
3647 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3648
3649 # lockvar of scriptlevel variable from def
3650 lines =<< trim END
3651 vim9script
3652
3653 class C
3654 public this.val3: number
3655 endclass
3656 var o = C.new(3)
3657 def Lock()
3658 lockvar o.val3
3659 enddef
3660 Lock()
3661 END
3662 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3663
3664 # lockvar of def argument variable
3665 lines =<< trim END
3666 vim9script
3667
3668 class C
3669 public this.val4: number
3670 endclass
3671 def Lock(o: C)
3672 lockvar o.val4
3673 enddef
3674 Lock(C.new(3))
3675 END
3676 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3677
3678 # lockvar from object method arg
3679 lines =<< trim END
3680 vim9script
3681
3682 class C
3683 public this.val5: number
3684 def Lock(o_any: any)
3685 lockvar o_any.val5
3686 enddef
3687 endclass
3688 var o = C.new(3)
3689 o.Lock(C.new(5))
3690 END
3691 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3692
3693 # lockvar from class method arg
3694 lines =<< trim END
3695 vim9script
3696
3697 class C
3698 public this.val6: number
3699 static def Lock(o_any: any)
3700 lockvar o_any.val6
3701 enddef
3702 endclass
3703 var o = C.new(3)
3704 C.Lock(o)
3705 END
3706 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3707enddef
3708
3709" Test trying to lock a class variable from various places
3710def Test_lockvar_class_variable()
3711
3712 # lockvar bare static from object method
3713 var lines =<< trim END
3714 vim9script
3715
3716 class C
3717 public static sval1: number
3718 def Lock()
3719 lockvar sval1
3720 enddef
3721 endclass
3722 var o = C.new()
3723 o.Lock()
3724 END
3725 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3726
3727 # lockvar C.static from object method
3728 lines =<< trim END
3729 vim9script
3730
3731 class C
3732 public static sval2: number
3733 def Lock()
3734 lockvar C.sval2
3735 enddef
3736 endclass
3737 var o = C.new()
3738 o.Lock()
3739 END
3740 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3741
3742 # lockvar bare static from class method
3743 lines =<< trim END
3744 vim9script
3745
3746 class C
3747 public static sval3: number
3748 static def Lock()
3749 lockvar sval3
3750 enddef
3751 endclass
3752 C.Lock()
3753 END
3754 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
3755
3756 # lockvar C.static from class method
3757 lines =<< trim END
3758 vim9script
3759
3760 class C
3761 public static sval4: number
3762 static def Lock()
3763 lockvar C.sval4
3764 enddef
3765 endclass
3766 C.Lock()
3767 END
3768 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
3769
3770 # lockvar C.static from script level
3771 lines =<< trim END
3772 vim9script
3773
3774 class C
3775 public static sval5: number
3776 endclass
3777 lockvar C.sval5
3778 END
3779 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
3780
3781 # lockvar o.static from script level
3782 lines =<< trim END
3783 vim9script
3784
3785 class C
3786 public static sval6: number
3787 endclass
3788 var o = C.new()
3789 lockvar o.sval6
3790 END
3791 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
3792enddef
3793
3794" Test locking an argument to :def
3795def Test_lockvar_argument()
3796 # Lockvar a function arg
3797 var lines =<< trim END
3798 vim9script
3799
3800 def Lock(val: any)
3801 lockvar val
3802 enddef
3803
3804 var d = {a: 1, b: 2}
3805 Lock(d)
3806
3807 d->extend({c: 3})
3808 END
3809 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
3810
3811 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
3812 # class member in "C". This tests lval_root_is_arg.
3813 lines =<< trim END
3814 vim9script
3815
3816 class C
3817 public static sval: list<number>
3818 endclass
3819
3820 def Lock2(sval: any)
3821 lockvar sval
3822 enddef
3823
3824 var o = C.new()
3825 Lock2(o)
3826 END
3827 v9.CheckSourceSuccess(lines)
3828
3829 # Lock a class.
3830 lines =<< trim END
3831 vim9script
3832
3833 class C
3834 public static sval: list<number>
3835 endclass
3836
3837 def Lock2(sval: any)
3838 lockvar sval
3839 enddef
3840
3841 Lock2(C)
3842 END
3843 v9.CheckSourceSuccess(lines)
3844
3845 # Lock an object.
3846 lines =<< trim END
3847 vim9script
3848
3849 class C
3850 public static sval: list<number>
3851 endclass
3852
3853 def Lock2(sval: any)
3854 lockvar sval
3855 enddef
3856
3857 Lock2(C.new())
3858 END
3859 v9.CheckSourceSuccess(lines)
3860
3861 # In this case (unlike previous) "lockvar sval" is a class member.
3862 lines =<< trim END
3863 vim9script
3864
3865 class C
3866 public static sval: list<number>
3867 def Lock2()
3868 lockvar sval
3869 enddef
3870 endclass
3871
3872
3873 var o = C.new()
3874 o.Lock2()
3875 END
3876 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
3877enddef
3878
3879" Test that this can be locked without error
3880def Test_lockvar_this()
3881 # lockvar this
3882 var lines =<< trim END
3883 vim9script
3884 class C
3885 def TLock()
3886 lockvar this
3887 enddef
3888 endclass
3889 var o = C.new()
3890 o.TLock()
3891 END
3892 v9.CheckSourceSuccess(lines)
3893
3894 # lockvar four (four letter word, but not this)
3895 lines =<< trim END
3896 vim9script
3897 class C
3898 def TLock4()
3899 var four: number
3900 lockvar four
3901 enddef
3902 endclass
3903 var o = C.new()
3904 o.TLock4()
3905 END
3906 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
3907
3908 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
3909 lines =<< trim END
3910 vim9script
3911 class C
3912 def TLock5()
3913 var this5: number
3914 lockvar this5
3915 enddef
3916 endclass
3917 var o = C.new()
3918 o.TLock5()
3919 END
3920 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
3921enddef
3922
3923" Test some general lockvar cases
3924def Test_lockvar_general()
3925 # lockvar an object and a class. It does nothing
3926 var lines =<< trim END
3927 vim9script
3928 class C
3929 endclass
3930 var o = C.new()
3931 lockvar o
3932 lockvar C
3933 END
3934 v9.CheckSourceSuccess(lines)
3935
3936 # Lock a list element that's nested in an object variable from a :def
3937 lines =<< trim END
3938 vim9script
3939
3940 class C
3941 public this.val: list<list<number>> = [ [1], [2], [3] ]
3942 endclass
3943 def Lock2(obj: any)
3944 lockvar obj.val[1]
3945 enddef
3946
3947 var o = C.new()
3948 Lock2(o)
3949 o.val[0] = [9]
3950 assert_equal([ [9], [2], [3] ], o.val)
3951 try
3952 o.val[1] = [999]
3953 call assert_false(true, 'assign should have failed')
3954 catch
3955 assert_exception('E741:')
3956 endtry
3957 o.val[2] = [8]
3958 assert_equal([ [9], [2], [8] ], o.val)
3959 END
3960 v9.CheckSourceSuccess(lines)
3961
3962 # Lock a list element that's nested in an object variable from scriptlevel
3963 lines =<< trim END
3964 vim9script
3965
3966 class C
3967 public this.val: list<list<number>> = [ [1], [2], [3] ]
3968 endclass
3969
3970 var o = C.new()
3971 lockvar o.val[1]
3972 o.val[0] = [9]
3973 assert_equal([ [9], [2], [3] ], o.val)
3974 try
3975 o.val[1] = [999]
3976 call assert_false(true, 'assign should have failed')
3977 catch
3978 assert_exception('E741:')
3979 endtry
3980 o.val[2] = [8]
3981 assert_equal([ [9], [2], [8] ], o.val)
3982 END
3983 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02003984
3985 # lock a script level variable from an object method
3986 lines =<< trim END
3987 vim9script
3988
3989 class C
3990 def Lock()
3991 lockvar l
3992 enddef
3993 endclass
3994
3995 var l = [1]
3996 C.new().Lock()
3997 l[0] = 11
3998 END
3999 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4000
4001 # lock a list element referenced by a private object variable
4002 # in an object fetched via a script level list
4003 lines =<< trim END
4004 vim9script
4005
4006 class C
4007 this._v1: list<list<number>>
4008 def Lock()
4009 lockvar lc[0]._v1[1]
4010 enddef
4011 endclass
4012
4013 var l = [[1], [2], [3]]
4014 var o = C.new(l)
4015 var lc: list<C> = [ o ]
4016
4017 o.Lock()
4018 l[0] = [22]
4019 l[1] = [33]
4020 END
4021 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4022
4023 # similar to the previous test, except the locking code is executing
4024 # in a class that does not own the private variable.
4025 # Note that the locking code is in a class has a private variable of
4026 # the same name.
4027 lines =<< trim END
4028 vim9script
4029
4030 class C2
4031 this._v1: list<list<number>>
4032 def Lock(obj: any)
4033 lockvar lc[0]._v1[1]
4034 enddef
4035 endclass
4036
4037 class C
4038 this._v1: list<list<number>>
4039 endclass
4040
4041 var l = [[1], [2], [3]]
4042 var o = C.new(l)
4043 var lc: list<C> = [ o ]
4044
4045 var o2 = C2.new()
4046 o2.Lock(o)
4047 END
4048 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004049enddef
4050
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004051" Test for a private object method
4052def Test_private_object_method()
4053 # Try calling a private method using an object (at the script level)
4054 var lines =<< trim END
4055 vim9script
4056
4057 class A
4058 def _Foo(): number
4059 return 1234
4060 enddef
4061 endclass
4062 var a = A.new()
4063 a._Foo()
4064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004065 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004066
4067 # Try calling a private method using an object (from a def function)
4068 lines =<< trim END
4069 vim9script
4070
4071 class A
4072 def _Foo(): number
4073 return 1234
4074 enddef
4075 endclass
4076 def T()
4077 var a = A.new()
4078 a._Foo()
4079 enddef
4080 T()
4081 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004082 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004083
4084 # Use a private method from another object method (in script context)
4085 lines =<< trim END
4086 vim9script
4087
4088 class A
4089 def _Foo(): number
4090 return 1234
4091 enddef
4092 def Bar(): number
4093 return this._Foo()
4094 enddef
4095 endclass
4096 var a = A.new()
4097 assert_equal(1234, a.Bar())
4098 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004099 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004100
4101 # Use a private method from another object method (def function context)
4102 lines =<< trim END
4103 vim9script
4104
4105 class A
4106 def _Foo(): number
4107 return 1234
4108 enddef
4109 def Bar(): number
4110 return this._Foo()
4111 enddef
4112 endclass
4113 def T()
4114 var a = A.new()
4115 assert_equal(1234, a.Bar())
4116 enddef
4117 T()
4118 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004119 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004120
4121 # Try calling a private method without the "this" prefix
4122 lines =<< trim END
4123 vim9script
4124
4125 class A
4126 def _Foo(): number
4127 return 1234
4128 enddef
4129 def Bar(): number
4130 return _Foo()
4131 enddef
4132 endclass
4133 var a = A.new()
4134 a.Bar()
4135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004136 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004137
4138 # Try calling a private method using the class name
4139 lines =<< trim END
4140 vim9script
4141
4142 class A
4143 def _Foo(): number
4144 return 1234
4145 enddef
4146 endclass
4147 A._Foo()
4148 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004149 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004150
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004151 # Define two private methods with the same name
4152 lines =<< trim END
4153 vim9script
4154
4155 class A
4156 def _Foo()
4157 enddef
4158 def _Foo()
4159 enddef
4160 endclass
4161 var a = A.new()
4162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004163 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004164
4165 # Define a private method and a object method with the same name
4166 lines =<< trim END
4167 vim9script
4168
4169 class A
4170 def _Foo()
4171 enddef
4172 def Foo()
4173 enddef
4174 endclass
4175 var a = A.new()
4176 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004177 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004178
4179 # Define an object method and a private method with the same name
4180 lines =<< trim END
4181 vim9script
4182
4183 class A
4184 def Foo()
4185 enddef
4186 def _Foo()
4187 enddef
4188 endclass
4189 var a = A.new()
4190 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004191 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004192
4193 # Call a public method and a private method from a private method
4194 lines =<< trim END
4195 vim9script
4196
4197 class A
4198 def Foo(): number
4199 return 100
4200 enddef
4201 def _Bar(): number
4202 return 200
4203 enddef
4204 def _Baz()
4205 assert_equal(100, this.Foo())
4206 assert_equal(200, this._Bar())
4207 enddef
4208 def T()
4209 this._Baz()
4210 enddef
4211 endclass
4212 var a = A.new()
4213 a.T()
4214 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004215 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004216
4217 # Try calling a private method from another class
4218 lines =<< trim END
4219 vim9script
4220
4221 class A
4222 def _Foo(): number
4223 return 100
4224 enddef
4225 endclass
4226 class B
4227 def Foo(): number
4228 var a = A.new()
4229 a._Foo()
4230 enddef
4231 endclass
4232 var b = B.new()
4233 b.Foo()
4234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004235 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004236
4237 # Call a private object method from a child class object method
4238 lines =<< trim END
4239 vim9script
4240 class A
4241 def _Foo(): number
4242 return 1234
4243 enddef
4244 endclass
4245 class B extends A
4246 def Bar()
4247 enddef
4248 endclass
4249 class C extends B
4250 def Baz(): number
4251 return this._Foo()
4252 enddef
4253 endclass
4254 var c = C.new()
4255 assert_equal(1234, c.Baz())
4256 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004257 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004258
4259 # Call a private object method from a child class object
4260 lines =<< trim END
4261 vim9script
4262 class A
4263 def _Foo(): number
4264 return 1234
4265 enddef
4266 endclass
4267 class B extends A
4268 def Bar()
4269 enddef
4270 endclass
4271 class C extends B
4272 def Baz(): number
4273 enddef
4274 endclass
4275 var c = C.new()
4276 assert_equal(1234, c._Foo())
4277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004278 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004279
4280 # Using "_" prefix in a method name should fail outside of a class
4281 lines =<< trim END
4282 vim9script
4283 def _Foo(): number
4284 return 1234
4285 enddef
4286 var a = _Foo()
4287 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004288 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004289enddef
4290
4291" Test for an private class method
4292def Test_private_class_method()
4293 # Try calling a class private method (at the script level)
4294 var lines =<< trim END
4295 vim9script
4296
4297 class A
4298 static def _Foo(): number
4299 return 1234
4300 enddef
4301 endclass
4302 A._Foo()
4303 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004304 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004305
4306 # Try calling a class private method (from a def function)
4307 lines =<< trim END
4308 vim9script
4309
4310 class A
4311 static def _Foo(): number
4312 return 1234
4313 enddef
4314 endclass
4315 def T()
4316 A._Foo()
4317 enddef
4318 T()
4319 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004320 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004321
4322 # Try calling a class private method using an object (at the script level)
4323 lines =<< trim END
4324 vim9script
4325
4326 class A
4327 static def _Foo(): number
4328 return 1234
4329 enddef
4330 endclass
4331 var a = A.new()
4332 a._Foo()
4333 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004334 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004335
4336 # Try calling a class private method using an object (from a def function)
4337 lines =<< trim END
4338 vim9script
4339
4340 class A
4341 static def _Foo(): number
4342 return 1234
4343 enddef
4344 endclass
4345 def T()
4346 var a = A.new()
4347 a._Foo()
4348 enddef
4349 T()
4350 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004351 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004352
4353 # Use a class private method from an object method
4354 lines =<< trim END
4355 vim9script
4356
4357 class A
4358 static def _Foo(): number
4359 return 1234
4360 enddef
4361 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004362 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004363 enddef
4364 endclass
4365 var a = A.new()
4366 a.Bar()
4367 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004368 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004369
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004370 # Use a class private method from another class private method without the
4371 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004372 lines =<< trim END
4373 vim9script
4374
4375 class A
4376 static def _Foo1(): number
4377 return 1234
4378 enddef
4379 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004380 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004381 enddef
4382 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004383 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004384 enddef
4385 endclass
4386 var a = A.new()
4387 a.Bar()
4388 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004389 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004390
4391 # Declare a class method and a class private method with the same name
4392 lines =<< trim END
4393 vim9script
4394
4395 class A
4396 static def _Foo()
4397 enddef
4398 static def Foo()
4399 enddef
4400 endclass
4401 var a = A.new()
4402 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004403 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004404
4405 # Try calling a class private method from another class
4406 lines =<< trim END
4407 vim9script
4408
4409 class A
4410 static def _Foo(): number
4411 return 1234
4412 enddef
4413 endclass
4414 class B
4415 def Foo(): number
4416 return A._Foo()
4417 enddef
4418 endclass
4419 var b = B.new()
4420 assert_equal(1234, b.Foo())
4421 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004422 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004423
4424 # Call a private class method from a child class object method
4425 lines =<< trim END
4426 vim9script
4427 class A
4428 static def _Foo(): number
4429 return 1234
4430 enddef
4431 endclass
4432 class B extends A
4433 def Bar()
4434 enddef
4435 endclass
4436 class C extends B
4437 def Baz(): number
4438 return A._Foo()
4439 enddef
4440 endclass
4441 var c = C.new()
4442 assert_equal(1234, c.Baz())
4443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004444 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004445
4446 # Call a private class method from a child class private class method
4447 lines =<< trim END
4448 vim9script
4449 class A
4450 static def _Foo(): number
4451 return 1234
4452 enddef
4453 endclass
4454 class B extends A
4455 def Bar()
4456 enddef
4457 endclass
4458 class C extends B
4459 static def Baz(): number
4460 return A._Foo()
4461 enddef
4462 endclass
4463 assert_equal(1234, C.Baz())
4464 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004465 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004466
4467 # Call a private class method from a child class object
4468 lines =<< trim END
4469 vim9script
4470 class A
4471 static def _Foo(): number
4472 return 1234
4473 enddef
4474 endclass
4475 class B extends A
4476 def Bar()
4477 enddef
4478 endclass
4479 class C extends B
4480 def Baz(): number
4481 enddef
4482 endclass
4483 var c = C.new()
4484 assert_equal(1234, C._Foo())
4485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004486 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004487enddef
4488
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004489" Test for using the return value of a class/object method as a function
4490" argument.
4491def Test_objmethod_funcarg()
4492 var lines =<< trim END
4493 vim9script
4494
4495 class C
4496 def Foo(): string
4497 return 'foo'
4498 enddef
4499 endclass
4500
4501 def Bar(a: number, s: string): string
4502 return s
4503 enddef
4504
4505 def Baz(c: C)
4506 assert_equal('foo', Bar(10, c.Foo()))
4507 enddef
4508
4509 var t = C.new()
4510 Baz(t)
4511 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004512 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004513
4514 lines =<< trim END
4515 vim9script
4516
4517 class C
4518 static def Foo(): string
4519 return 'foo'
4520 enddef
4521 endclass
4522
4523 def Bar(a: number, s: string): string
4524 return s
4525 enddef
4526
4527 def Baz()
4528 assert_equal('foo', Bar(10, C.Foo()))
4529 enddef
4530
4531 Baz()
4532 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004533 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004534enddef
4535
Ernie Raelcf138d42023-09-06 20:45:03 +02004536def Test_static_inheritence()
4537 # subclasses get their own static copy
4538 var lines =<< trim END
4539 vim9script
4540
4541 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004542 static _svar: number
4543 this._mvar: number
4544 def new()
4545 _svar = 1
4546 this._mvar = 101
4547 enddef
4548 def AccessObject(): number
4549 return this._mvar
4550 enddef
4551 def AccessStaticThroughObject(): number
4552 return _svar
4553 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004554 endclass
4555
4556 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004557 def new()
4558 this._mvar = 102
4559 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004560 endclass
4561
4562 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004563 def new()
4564 this._mvar = 103
4565 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004566
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004567 def AccessPrivateStaticThroughClassName(): number
4568 assert_equal(1, A._svar)
4569 return 444
4570 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004571 endclass
4572
4573 var oa = A.new()
4574 var ob = B.new()
4575 var oc = C.new()
4576 assert_equal(101, oa.AccessObject())
4577 assert_equal(102, ob.AccessObject())
4578 assert_equal(103, oc.AccessObject())
4579
Ernie Rael64885642023-10-04 20:16:22 +02004580 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02004581
4582 # verify object properly resolves to correct static
4583 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004584 assert_equal(1, ob.AccessStaticThroughObject())
4585 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02004586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004587 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02004588enddef
4589
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004590" Test for declaring duplicate object and class members
4591def Test_dup_member_variable()
4592 # Duplicate member variable
4593 var lines =<< trim END
4594 vim9script
4595 class C
4596 this.val = 10
4597 this.val = 20
4598 endclass
4599 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004600 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004601
4602 # Duplicate private member variable
4603 lines =<< trim END
4604 vim9script
4605 class C
4606 this._val = 10
4607 this._val = 20
4608 endclass
4609 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004610 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004611
4612 # Duplicate public member variable
4613 lines =<< trim END
4614 vim9script
4615 class C
4616 public this.val = 10
4617 public this.val = 20
4618 endclass
4619 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004620 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004621
4622 # Duplicate private member variable
4623 lines =<< trim END
4624 vim9script
4625 class C
4626 this.val = 10
4627 this._val = 20
4628 endclass
4629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004630 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004631
4632 # Duplicate public and private member variable
4633 lines =<< trim END
4634 vim9script
4635 class C
4636 this._val = 20
4637 public this.val = 10
4638 endclass
4639 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004640 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004641
4642 # Duplicate class member variable
4643 lines =<< trim END
4644 vim9script
4645 class C
4646 static s: string = "abc"
4647 static _s: string = "def"
4648 endclass
4649 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004650 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004651
4652 # Duplicate public and private class member variable
4653 lines =<< trim END
4654 vim9script
4655 class C
4656 public static s: string = "abc"
4657 static _s: string = "def"
4658 endclass
4659 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004660 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004661
4662 # Duplicate class and object member variable
4663 lines =<< trim END
4664 vim9script
4665 class C
4666 static val = 10
4667 this.val = 20
4668 def new()
4669 enddef
4670 endclass
4671 var c = C.new()
4672 assert_equal(10, C.val)
4673 assert_equal(20, c.val)
4674 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02004675 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004676
4677 # Duplicate object member variable in a derived class
4678 lines =<< trim END
4679 vim9script
4680 class A
4681 this.val = 10
4682 endclass
4683 class B extends A
4684 endclass
4685 class C extends B
4686 this.val = 20
4687 endclass
4688 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004689 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004690
4691 # Duplicate object private member variable in a derived class
4692 lines =<< trim END
4693 vim9script
4694 class A
4695 this._val = 10
4696 endclass
4697 class B extends A
4698 endclass
4699 class C extends B
4700 this._val = 20
4701 endclass
4702 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004703 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004704
4705 # Duplicate object private member variable in a derived class
4706 lines =<< trim END
4707 vim9script
4708 class A
4709 this.val = 10
4710 endclass
4711 class B extends A
4712 endclass
4713 class C extends B
4714 this._val = 20
4715 endclass
4716 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004717 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004718
4719 # Duplicate object member variable in a derived class
4720 lines =<< trim END
4721 vim9script
4722 class A
4723 this._val = 10
4724 endclass
4725 class B extends A
4726 endclass
4727 class C extends B
4728 this.val = 20
4729 endclass
4730 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004731 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004732
4733 # Two member variables with a common prefix
4734 lines =<< trim END
4735 vim9script
4736 class A
4737 public static svar2: number
4738 public static svar: number
4739 endclass
4740 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004741 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004742enddef
4743
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004744" Test for accessing a private member outside a class in a def function
4745def Test_private_member_access_outside_class()
4746 # private object member variable
4747 var lines =<< trim END
4748 vim9script
4749 class A
4750 this._val = 10
4751 def GetVal(): number
4752 return this._val
4753 enddef
4754 endclass
4755 def T()
4756 var a = A.new()
4757 a._val = 20
4758 enddef
4759 T()
4760 END
Ernie Rael64885642023-10-04 20:16:22 +02004761 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004762
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004763 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004764 lines =<< trim END
4765 vim9script
4766 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004767 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004768 endclass
4769 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004770 var a = A.new()
4771 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004772 enddef
4773 T()
4774 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004775 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004776
4777 # private static member variable
4778 lines =<< trim END
4779 vim9script
4780 class A
4781 static _val = 10
4782 endclass
4783 def T()
4784 var a = A.new()
4785 var x = a._val
4786 enddef
4787 T()
4788 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004789 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004790
4791 # private static member variable
4792 lines =<< trim END
4793 vim9script
4794 class A
4795 static _val = 10
4796 endclass
4797 def T()
4798 var a = A.new()
4799 a._val = 3
4800 enddef
4801 T()
4802 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004803 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004804
4805 # private static class variable
4806 lines =<< trim END
4807 vim9script
4808 class A
4809 static _val = 10
4810 endclass
4811 def T()
4812 var x = A._val
4813 enddef
4814 T()
4815 END
Ernie Rael64885642023-10-04 20:16:22 +02004816 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02004817
4818 # private static class variable
4819 lines =<< trim END
4820 vim9script
4821 class A
4822 static _val = 10
4823 endclass
4824 def T()
4825 A._val = 3
4826 enddef
4827 T()
4828 END
Ernie Rael64885642023-10-04 20:16:22 +02004829 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004830enddef
4831
4832" Test for changing the member access of an interface in a implementation class
4833def Test_change_interface_member_access()
4834 var lines =<< trim END
4835 vim9script
4836 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004837 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004838 endinterface
4839 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004840 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004841 endclass
4842 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004843 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004844
4845 lines =<< trim END
4846 vim9script
4847 interface A
4848 this.val: number
4849 endinterface
4850 class B implements A
4851 public this.val = 10
4852 endclass
4853 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004854 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004855enddef
4856
4857" Test for trying to change a readonly member from a def function
4858def Test_readonly_member_change_in_def_func()
4859 var lines =<< trim END
4860 vim9script
4861 class A
4862 this.val: number
4863 endclass
4864 def T()
4865 var a = A.new()
4866 a.val = 20
4867 enddef
4868 T()
4869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004870 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004871enddef
4872
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004873" Test for reading and writing a class member from a def function
4874def Test_modify_class_member_from_def_function()
4875 var lines =<< trim END
4876 vim9script
4877 class A
4878 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004879 public static var2: list<number> = [1, 2]
4880 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004881 static _priv_var4: number = 40
4882 endclass
4883 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004884 assert_equal([1, 2], A.var2)
4885 assert_equal({a: 1, b: 2}, A.var3)
4886 A.var2 = [3, 4]
4887 A.var3 = {c: 3, d: 4}
4888 assert_equal([3, 4], A.var2)
4889 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael64885642023-10-04 20:16:22 +02004890 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004891 enddef
4892 T()
4893 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004894 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004895enddef
4896
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004897" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004898def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004899 var lines =<< trim END
4900 vim9script
4901 class A
4902 public static svar1: list<number> = [1]
4903 public static svar2: list<number> = [2]
4904 endclass
4905
4906 A.svar1->add(3)
4907 A.svar2->add(4)
4908 assert_equal([1, 3], A.svar1)
4909 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004910
4911 def Foo()
4912 A.svar1->add(7)
4913 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004914 assert_equal([1, 3, 7], A.svar1)
4915 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004916 enddef
4917 Foo()
4918 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004919 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004920
4921 # Cannot read from a class variable using an object in script context
4922 lines =<< trim END
4923 vim9script
4924 class A
4925 public this.var1: number
4926 public static svar2: list<number> = [1]
4927 endclass
4928
4929 var a = A.new()
4930 echo a.svar2
4931 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004932 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004933
4934 # Cannot write to a class variable using an object in script context
4935 lines =<< trim END
4936 vim9script
4937 class A
4938 public this.var1: number
4939 public static svar2: list<number> = [1]
4940 endclass
4941
4942 var a = A.new()
4943 a.svar2 = [2]
4944 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004945 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004946
4947 # Cannot read from a class variable using an object in def method context
4948 lines =<< trim END
4949 vim9script
4950 class A
4951 public this.var1: number
4952 public static svar2: list<number> = [1]
4953 endclass
4954
4955 def T()
4956 var a = A.new()
4957 echo a.svar2
4958 enddef
4959 T()
4960 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004961 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004962
4963 # Cannot write to a class variable using an object in def method context
4964 lines =<< trim END
4965 vim9script
4966 class A
4967 public this.var1: number
4968 public static svar2: list<number> = [1]
4969 endclass
4970
4971 def T()
4972 var a = A.new()
4973 a.svar2 = [2]
4974 enddef
4975 T()
4976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004977 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004978enddef
4979
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004980" Test for using a interface method using a child object
4981def Test_interface_method_from_child()
4982 var lines =<< trim END
4983 vim9script
4984
4985 interface A
4986 def Foo(): string
4987 endinterface
4988
4989 class B implements A
4990 def Foo(): string
4991 return 'foo'
4992 enddef
4993 endclass
4994
4995 class C extends B
4996 def Bar(): string
4997 return 'bar'
4998 enddef
4999 endclass
5000
5001 def T1(a: A)
5002 assert_equal('foo', a.Foo())
5003 enddef
5004
5005 def T2(b: B)
5006 assert_equal('foo', b.Foo())
5007 enddef
5008
5009 var c = C.new()
5010 T1(c)
5011 T2(c)
5012 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005013 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005014enddef
5015
5016" Test for using an interface method using a child object when it is overridden
5017" by the child class.
5018" FIXME: This test fails.
5019" def Test_interface_overridden_method_from_child()
5020" var lines =<< trim END
5021" vim9script
5022"
5023" interface A
5024" def Foo(): string
5025" endinterface
5026"
5027" class B implements A
5028" def Foo(): string
5029" return 'b-foo'
5030" enddef
5031" endclass
5032"
5033" class C extends B
5034" def Bar(): string
5035" return 'bar'
5036" enddef
5037" def Foo(): string
5038" return 'c-foo'
5039" enddef
5040" endclass
5041"
5042" def T1(a: A)
5043" assert_equal('c-foo', a.Foo())
5044" enddef
5045"
5046" def T2(b: B)
5047" assert_equal('c-foo', b.Foo())
5048" enddef
5049"
5050" var c = C.new()
5051" T1(c)
5052" T2(c)
5053" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005054" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005055" enddef
5056
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005057" Test for abstract methods
5058def Test_abstract_method()
5059 # Use two abstract methods
5060 var lines =<< trim END
5061 vim9script
5062 abstract class A
5063 def M1(): number
5064 return 10
5065 enddef
5066 abstract def M2(): number
5067 abstract def M3(): number
5068 endclass
5069 class B extends A
5070 def M2(): number
5071 return 20
5072 enddef
5073 def M3(): number
5074 return 30
5075 enddef
5076 endclass
5077 var b = B.new()
5078 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5079 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005080 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005081
5082 # Don't define an abstract method
5083 lines =<< trim END
5084 vim9script
5085 abstract class A
5086 abstract def Foo()
5087 endclass
5088 class B extends A
5089 endclass
5090 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005091 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005092
5093 # Use abstract method in a concrete class
5094 lines =<< trim END
5095 vim9script
5096 class A
5097 abstract def Foo()
5098 endclass
5099 class B extends A
5100 endclass
5101 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005102 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005103
5104 # Use abstract method in an interface
5105 lines =<< trim END
5106 vim9script
5107 interface A
5108 abstract def Foo()
5109 endinterface
5110 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005111 def Foo()
5112 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005113 endclass
5114 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005115 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005116
5117 # Abbreviate the "abstract" keyword
5118 lines =<< trim END
5119 vim9script
5120 class A
5121 abs def Foo()
5122 endclass
5123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005124 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005125
5126 # Use "abstract" with a member variable
5127 lines =<< trim END
5128 vim9script
5129 abstract class A
5130 abstract this.val = 10
5131 endclass
5132 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005133 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005134
5135 # Use a static abstract method
5136 lines =<< trim END
5137 vim9script
5138 abstract class A
5139 abstract static def Foo(): number
5140 endclass
5141 class B extends A
5142 static def Foo(): number
5143 return 4
5144 enddef
5145 endclass
5146 assert_equal(4, B.Foo())
5147 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005148 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005149
5150 # Type mismatch between abstract method and concrete method
5151 lines =<< trim END
5152 vim9script
5153 abstract class A
5154 abstract def Foo(a: string, b: number): list<number>
5155 endclass
5156 class B extends A
5157 def Foo(a: number, b: string): list<string>
5158 return []
5159 enddef
5160 endclass
5161 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005162 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 +02005163
5164 # Use an abstract class to invoke an abstract method
5165 # FIXME: This should fail
5166 lines =<< trim END
5167 vim9script
5168 abstract class A
5169 abstract static def Foo()
5170 endclass
5171 A.Foo()
5172 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005173 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005174
5175 # Invoke an abstract method from a def function
5176 lines =<< trim END
5177 vim9script
5178 abstract class A
5179 abstract def Foo(): list<number>
5180 endclass
5181 class B extends A
5182 def Foo(): list<number>
5183 return [3, 5]
5184 enddef
5185 endclass
5186 def Bar(c: B)
5187 assert_equal([3, 5], c.Foo())
5188 enddef
5189 var b = B.new()
5190 Bar(b)
5191 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005192 v9.CheckSourceSuccess(lines)
5193enddef
5194
5195" Test for calling a class method from a subclass
5196def Test_class_method_call_from_subclass()
5197 # class method call from a subclass
5198 var lines =<< trim END
5199 vim9script
5200
5201 class A
5202 static def Foo()
5203 echo "foo"
5204 enddef
5205 endclass
5206
5207 class B extends A
5208 def Bar()
5209 Foo()
5210 enddef
5211 endclass
5212
5213 var b = B.new()
5214 b.Bar()
5215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005216 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005217enddef
5218
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005219" Test for calling a class method using an object in a def function context and
5220" script context.
5221def Test_class_method_call_using_object()
5222 # script context
5223 var lines =<< trim END
5224 vim9script
5225 class A
5226 static def Foo(): list<string>
5227 return ['a', 'b']
5228 enddef
5229 def Bar()
5230 assert_equal(['a', 'b'], A.Foo())
5231 assert_equal(['a', 'b'], Foo())
5232 enddef
5233 endclass
5234
5235 def T()
5236 assert_equal(['a', 'b'], A.Foo())
5237 var t_a = A.new()
5238 t_a.Bar()
5239 enddef
5240
5241 assert_equal(['a', 'b'], A.Foo())
5242 var a = A.new()
5243 a.Bar()
5244 T()
5245 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005246 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005247
5248 # script context
5249 lines =<< trim END
5250 vim9script
5251 class A
5252 static def Foo(): string
5253 return 'foo'
5254 enddef
5255 endclass
5256
5257 var a = A.new()
5258 assert_equal('foo', a.Foo())
5259 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005260 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005261
5262 # def function context
5263 lines =<< trim END
5264 vim9script
5265 class A
5266 static def Foo(): string
5267 return 'foo'
5268 enddef
5269 endclass
5270
5271 def T()
5272 var a = A.new()
5273 assert_equal('foo', a.Foo())
5274 enddef
5275 T()
5276 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005277 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005278enddef
5279
5280def Test_class_variable()
5281 var lines =<< trim END
5282 vim9script
5283
5284 class A
5285 public static val: number = 10
5286 static def ClassFunc()
5287 assert_equal(10, val)
5288 enddef
5289 def ObjFunc()
5290 assert_equal(10, val)
5291 enddef
5292 endclass
5293
5294 class B extends A
5295 endclass
5296
5297 assert_equal(10, A.val)
5298 A.ClassFunc()
5299 var a = A.new()
5300 a.ObjFunc()
5301 var b = B.new()
5302 b.ObjFunc()
5303
5304 def T1(a1: A)
5305 a1.ObjFunc()
5306 A.ClassFunc()
5307 enddef
5308 T1(b)
5309
5310 A.val = 20
5311 assert_equal(20, A.val)
5312 END
5313 v9.CheckSourceSuccess(lines)
5314
5315 # Modifying a parent class variable from a child class method
5316 lines =<< trim END
5317 vim9script
5318
5319 class A
5320 static val: number = 10
5321 endclass
5322
5323 class B extends A
5324 static def ClassFunc()
5325 val = 20
5326 enddef
5327 endclass
5328 B.ClassFunc()
5329 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005330 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005331
5332 # Reading a parent class variable from a child class method
5333 lines =<< trim END
5334 vim9script
5335
5336 class A
5337 static val: number = 10
5338 endclass
5339
5340 class B extends A
5341 static def ClassFunc()
5342 var i = val
5343 enddef
5344 endclass
5345 B.ClassFunc()
5346 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005347 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005348
5349 # Modifying a parent class variable from a child object method
5350 lines =<< trim END
5351 vim9script
5352
5353 class A
5354 static val: number = 10
5355 endclass
5356
5357 class B extends A
5358 def ObjFunc()
5359 val = 20
5360 enddef
5361 endclass
5362 var b = B.new()
5363 b.ObjFunc()
5364 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005365 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005366
5367 # Reading a parent class variable from a child object method
5368 lines =<< trim END
5369 vim9script
5370
5371 class A
5372 static val: number = 10
5373 endclass
5374
5375 class B extends A
5376 def ObjFunc()
5377 var i = val
5378 enddef
5379 endclass
5380 var b = B.new()
5381 b.ObjFunc()
5382 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005383 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005384
5385 # Modifying a class variable using an object at script level
5386 lines =<< trim END
5387 vim9script
5388
5389 class A
5390 static val: number = 10
5391 endclass
5392 var a = A.new()
5393 a.val = 20
5394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005395 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005396
5397 # Reading a class variable using an object at script level
5398 lines =<< trim END
5399 vim9script
5400
5401 class A
5402 static val: number = 10
5403 endclass
5404 var a = A.new()
5405 var i = a.val
5406 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005407 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005408
5409 # Modifying a class variable using an object at function level
5410 lines =<< trim END
5411 vim9script
5412
5413 class A
5414 static val: number = 10
5415 endclass
5416
5417 def T()
5418 var a = A.new()
5419 a.val = 20
5420 enddef
5421 T()
5422 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005423 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005424
5425 # Reading a class variable using an object at function level
5426 lines =<< trim END
5427 vim9script
5428
5429 class A
5430 static val: number = 10
5431 endclass
5432 def T()
5433 var a = A.new()
5434 var i = a.val
5435 enddef
5436 T()
5437 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005438 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005439enddef
5440
5441" Test for using a duplicate class method and class variable in a child class
5442def Test_dup_class_member()
5443 # duplicate class variable, class method and overridden object method
5444 var lines =<< trim END
5445 vim9script
5446 class A
5447 static sval = 100
5448 static def Check()
5449 assert_equal(100, sval)
5450 enddef
5451 def GetVal(): number
5452 return sval
5453 enddef
5454 endclass
5455
5456 class B extends A
5457 static sval = 200
5458 static def Check()
5459 assert_equal(200, sval)
5460 enddef
5461 def GetVal(): number
5462 return sval
5463 enddef
5464 endclass
5465
5466 def T1(aa: A): number
5467 return aa.GetVal()
5468 enddef
5469
5470 def T2(bb: B): number
5471 return bb.GetVal()
5472 enddef
5473
5474 assert_equal(100, A.sval)
5475 assert_equal(200, B.sval)
5476 var a = A.new()
5477 assert_equal(100, a.GetVal())
5478 var b = B.new()
5479 assert_equal(200, b.GetVal())
5480 assert_equal(200, T1(b))
5481 assert_equal(200, T2(b))
5482 END
5483 v9.CheckSourceSuccess(lines)
5484
5485 # duplicate class variable and class method
5486 lines =<< trim END
5487 vim9script
5488 class A
5489 static sval = 100
5490 static def Check()
5491 assert_equal(100, sval)
5492 enddef
5493 def GetVal(): number
5494 return sval
5495 enddef
5496 endclass
5497
5498 class B extends A
5499 static sval = 200
5500 static def Check()
5501 assert_equal(200, sval)
5502 enddef
5503 endclass
5504
5505 def T1(aa: A): number
5506 return aa.GetVal()
5507 enddef
5508
5509 def T2(bb: B): number
5510 return bb.GetVal()
5511 enddef
5512
5513 assert_equal(100, A.sval)
5514 assert_equal(200, B.sval)
5515 var a = A.new()
5516 assert_equal(100, a.GetVal())
5517 var b = B.new()
5518 assert_equal(100, b.GetVal())
5519 assert_equal(100, T1(b))
5520 assert_equal(100, T2(b))
5521 END
5522 v9.CheckSourceSuccess(lines)
5523enddef
5524
5525" Test for calling an instance method using the class
5526def Test_instance_method_call_using_class()
5527 # Invoke an object method using a class in script context
5528 var lines =<< trim END
5529 vim9script
5530 class A
5531 def Foo()
5532 echo "foo"
5533 enddef
5534 endclass
5535 A.Foo()
5536 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005537 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005538
5539 # Invoke an object method using a class in def function context
5540 lines =<< trim END
5541 vim9script
5542 class A
5543 def Foo()
5544 echo "foo"
5545 enddef
5546 endclass
5547 def T()
5548 A.Foo()
5549 enddef
5550 T()
5551 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005552 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005553enddef
5554
5555" Test for duplicate class method and instance method
5556def Test_dup_classmethod_objmethod()
5557 # Duplicate instance method
5558 var lines =<< trim END
5559 vim9script
5560 class A
5561 static def Foo()
5562 enddef
5563 def Foo()
5564 enddef
5565 endclass
5566 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005567 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005568
5569 # Duplicate private instance method
5570 lines =<< trim END
5571 vim9script
5572 class A
5573 static def Foo()
5574 enddef
5575 def _Foo()
5576 enddef
5577 endclass
5578 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005579 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005580
5581 # Duplicate class method
5582 lines =<< trim END
5583 vim9script
5584 class A
5585 def Foo()
5586 enddef
5587 static def Foo()
5588 enddef
5589 endclass
5590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005591 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005592
5593 # Duplicate private class method
5594 lines =<< trim END
5595 vim9script
5596 class A
5597 def Foo()
5598 enddef
5599 static def _Foo()
5600 enddef
5601 endclass
5602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005603 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005604
5605 # Duplicate private class and object method
5606 lines =<< trim END
5607 vim9script
5608 class A
5609 def _Foo()
5610 enddef
5611 static def _Foo()
5612 enddef
5613 endclass
5614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005615 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005616enddef
5617
5618" Test for an instance method access level comparison with parent instance
5619" methods.
5620def Test_instance_method_access_level()
5621 # Private method in subclass
5622 var lines =<< trim END
5623 vim9script
5624 class A
5625 def Foo()
5626 enddef
5627 endclass
5628 class B extends A
5629 endclass
5630 class C extends B
5631 def _Foo()
5632 enddef
5633 endclass
5634 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005635 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005636
5637 # Public method in subclass
5638 lines =<< trim END
5639 vim9script
5640 class A
5641 def _Foo()
5642 enddef
5643 endclass
5644 class B extends A
5645 endclass
5646 class C extends B
5647 def Foo()
5648 enddef
5649 endclass
5650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005651 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005652enddef
5653
5654def Test_extend_empty_class()
5655 var lines =<< trim END
5656 vim9script
5657 class A
5658 endclass
5659 class B extends A
5660 endclass
5661 class C extends B
5662 public static rw_class_var = 1
5663 public this.rw_obj_var = 2
5664 static def ClassMethod(): number
5665 return 3
5666 enddef
5667 def ObjMethod(): number
5668 return 4
5669 enddef
5670 endclass
5671 assert_equal(1, C.rw_class_var)
5672 assert_equal(3, C.ClassMethod())
5673 var c = C.new()
5674 assert_equal(2, c.rw_obj_var)
5675 assert_equal(4, c.ObjMethod())
5676 END
5677 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005678enddef
5679
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005680" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005681" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005682def Test_interface_with_unsupported_members()
5683 var lines =<< trim END
5684 vim9script
5685 interface A
5686 static num: number
5687 endinterface
5688 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005689 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005690
5691 lines =<< trim END
5692 vim9script
5693 interface A
5694 static _num: number
5695 endinterface
5696 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005697 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005698
5699 lines =<< trim END
5700 vim9script
5701 interface A
5702 public static num: number
5703 endinterface
5704 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005705 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005706
5707 lines =<< trim END
5708 vim9script
5709 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005710 public static num: number
5711 endinterface
5712 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005713 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005714
5715 lines =<< trim END
5716 vim9script
5717 interface A
5718 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005719 endinterface
5720 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005721 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005722
5723 lines =<< trim END
5724 vim9script
5725 interface A
5726 static def Foo(d: dict<any>): list<string>
5727 endinterface
5728 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005729 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005730
5731 lines =<< trim END
5732 vim9script
5733 interface A
5734 static def _Foo(d: dict<any>): list<string>
5735 endinterface
5736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005737 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005738
5739 lines =<< trim END
5740 vim9script
5741 interface A
5742 this._Foo: list<string>
5743 endinterface
5744 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005745 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005746
5747 lines =<< trim END
5748 vim9script
5749 interface A
5750 def _Foo(d: dict<any>): list<string>
5751 endinterface
5752 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005753 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005754enddef
5755
5756" Test for extending an interface
5757def Test_extend_interface()
5758 var lines =<< trim END
5759 vim9script
5760 interface A
5761 this.var1: list<string>
5762 def Foo()
5763 endinterface
5764 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005765 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005766 def Bar()
5767 endinterface
5768 class C implements A, B
5769 this.var1 = [1, 2]
5770 def Foo()
5771 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005772 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005773 def Bar()
5774 enddef
5775 endclass
5776 END
5777 v9.CheckSourceSuccess(lines)
5778
5779 lines =<< trim END
5780 vim9script
5781 interface A
5782 def Foo()
5783 endinterface
5784 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005785 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005786 endinterface
5787 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005788 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005789 endclass
5790 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005791 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005792
5793 lines =<< trim END
5794 vim9script
5795 interface A
5796 def Foo()
5797 endinterface
5798 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005799 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005800 endinterface
5801 class C implements A, B
5802 def Foo()
5803 enddef
5804 endclass
5805 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005806 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005807
5808 # interface cannot extend a class
5809 lines =<< trim END
5810 vim9script
5811 class A
5812 endclass
5813 interface B extends A
5814 endinterface
5815 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005816 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005817
5818 # class cannot extend an interface
5819 lines =<< trim END
5820 vim9script
5821 interface A
5822 endinterface
5823 class B extends A
5824 endclass
5825 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005826 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005827
5828 # interface cannot implement another interface
5829 lines =<< trim END
5830 vim9script
5831 interface A
5832 endinterface
5833 interface B implements A
5834 endinterface
5835 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005836 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005837
5838 # interface cannot extend multiple interfaces
5839 lines =<< trim END
5840 vim9script
5841 interface A
5842 endinterface
5843 interface B
5844 endinterface
5845 interface C extends A, B
5846 endinterface
5847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005848 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005849
5850 # Variable type in an extended interface is of different type
5851 lines =<< trim END
5852 vim9script
5853 interface A
5854 this.val1: number
5855 endinterface
5856 interface B extends A
5857 this.val2: string
5858 endinterface
5859 interface C extends B
5860 this.val1: string
5861 this.val2: number
5862 endinterface
5863 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005864 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005865enddef
5866
5867" Test for a child class implementing an interface when some of the methods are
5868" defined in the parent class.
5869def Test_child_class_implements_interface()
5870 var lines =<< trim END
5871 vim9script
5872
5873 interface Intf
5874 def F1(): list<list<number>>
5875 def F2(): list<list<number>>
5876 def F3(): list<list<number>>
5877 this.var1: list<dict<number>>
5878 this.var2: list<dict<number>>
5879 this.var3: list<dict<number>>
5880 endinterface
5881
5882 class A
5883 def A1()
5884 enddef
5885 def F3(): list<list<number>>
5886 return [[3]]
5887 enddef
5888 this.v1: list<list<number>> = [[0]]
5889 this.var3 = [{c: 30}]
5890 endclass
5891
5892 class B extends A
5893 def B1()
5894 enddef
5895 def F2(): list<list<number>>
5896 return [[2]]
5897 enddef
5898 this.v2: list<list<number>> = [[0]]
5899 this.var2 = [{b: 20}]
5900 endclass
5901
5902 class C extends B implements Intf
5903 def C1()
5904 enddef
5905 def F1(): list<list<number>>
5906 return [[1]]
5907 enddef
5908 this.v3: list<list<number>> = [[0]]
5909 this.var1 = [{a: 10}]
5910 endclass
5911
5912 def T(if: Intf)
5913 assert_equal([[1]], if.F1())
5914 assert_equal([[2]], if.F2())
5915 assert_equal([[3]], if.F3())
5916 assert_equal([{a: 10}], if.var1)
5917 assert_equal([{b: 20}], if.var2)
5918 assert_equal([{c: 30}], if.var3)
5919 enddef
5920
5921 var c = C.new()
5922 T(c)
5923 assert_equal([[1]], c.F1())
5924 assert_equal([[2]], c.F2())
5925 assert_equal([[3]], c.F3())
5926 assert_equal([{a: 10}], c.var1)
5927 assert_equal([{b: 20}], c.var2)
5928 assert_equal([{c: 30}], c.var3)
5929 END
5930 v9.CheckSourceSuccess(lines)
5931
5932 # One of the interface methods is not found
5933 lines =<< trim END
5934 vim9script
5935
5936 interface Intf
5937 def F1()
5938 def F2()
5939 def F3()
5940 endinterface
5941
5942 class A
5943 def A1()
5944 enddef
5945 endclass
5946
5947 class B extends A
5948 def B1()
5949 enddef
5950 def F2()
5951 enddef
5952 endclass
5953
5954 class C extends B implements Intf
5955 def C1()
5956 enddef
5957 def F1()
5958 enddef
5959 endclass
5960 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005961 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005962
5963 # One of the interface methods is of different type
5964 lines =<< trim END
5965 vim9script
5966
5967 interface Intf
5968 def F1()
5969 def F2()
5970 def F3()
5971 endinterface
5972
5973 class A
5974 def F3(): number
5975 return 0
5976 enddef
5977 def A1()
5978 enddef
5979 endclass
5980
5981 class B extends A
5982 def B1()
5983 enddef
5984 def F2()
5985 enddef
5986 endclass
5987
5988 class C extends B implements Intf
5989 def C1()
5990 enddef
5991 def F1()
5992 enddef
5993 endclass
5994 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005995 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005996
5997 # One of the interface variables is not present
5998 lines =<< trim END
5999 vim9script
6000
6001 interface Intf
6002 this.var1: list<dict<number>>
6003 this.var2: list<dict<number>>
6004 this.var3: list<dict<number>>
6005 endinterface
6006
6007 class A
6008 this.v1: list<list<number>> = [[0]]
6009 endclass
6010
6011 class B extends A
6012 this.v2: list<list<number>> = [[0]]
6013 this.var2 = [{b: 20}]
6014 endclass
6015
6016 class C extends B implements Intf
6017 this.v3: list<list<number>> = [[0]]
6018 this.var1 = [{a: 10}]
6019 endclass
6020 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006021 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006022
6023 # One of the interface variables is of different type
6024 lines =<< trim END
6025 vim9script
6026
6027 interface Intf
6028 this.var1: list<dict<number>>
6029 this.var2: list<dict<number>>
6030 this.var3: list<dict<number>>
6031 endinterface
6032
6033 class A
6034 this.v1: list<list<number>> = [[0]]
6035 this.var3: list<dict<string>>
6036 endclass
6037
6038 class B extends A
6039 this.v2: list<list<number>> = [[0]]
6040 this.var2 = [{b: 20}]
6041 endclass
6042
6043 class C extends B implements Intf
6044 this.v3: list<list<number>> = [[0]]
6045 this.var1 = [{a: 10}]
6046 endclass
6047 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006048 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 +02006049enddef
6050
6051" Test for extending an interface with duplicate variables and methods
6052def Test_interface_extends_with_dup_members()
6053 var lines =<< trim END
6054 vim9script
6055 interface A
6056 this.n1: number
6057 def Foo1(): number
6058 endinterface
6059 interface B extends A
6060 this.n2: number
6061 this.n1: number
6062 def Foo2(): number
6063 def Foo1(): number
6064 endinterface
6065 class C implements B
6066 this.n1 = 10
6067 this.n2 = 20
6068 def Foo1(): number
6069 return 30
6070 enddef
6071 def Foo2(): number
6072 return 40
6073 enddef
6074 endclass
6075 def T1(a: A)
6076 assert_equal(10, a.n1)
6077 assert_equal(30, a.Foo1())
6078 enddef
6079 def T2(b: B)
6080 assert_equal(10, b.n1)
6081 assert_equal(20, b.n2)
6082 assert_equal(30, b.Foo1())
6083 assert_equal(40, b.Foo2())
6084 enddef
6085 var c = C.new()
6086 T1(c)
6087 T2(c)
6088 END
6089 v9.CheckSourceSuccess(lines)
6090enddef
6091
6092" Test for using "any" type for a variable in a sub-class while it has a
6093" concrete type in the interface
6094def Test_implements_using_var_type_any()
6095 var lines =<< trim END
6096 vim9script
6097 interface A
6098 this.val: list<dict<string>>
6099 endinterface
6100 class B implements A
6101 this.val = [{a: '1'}, {b: '2'}]
6102 endclass
6103 var b = B.new()
6104 assert_equal([{a: '1'}, {b: '2'}], b.val)
6105 END
6106 v9.CheckSourceSuccess(lines)
6107
6108 # initialize instance variable using a different type
6109 lines =<< trim END
6110 vim9script
6111 interface A
6112 this.val: list<dict<string>>
6113 endinterface
6114 class B implements A
6115 this.val = {a: 1, b: 2}
6116 endclass
6117 var b = B.new()
6118 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006119 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006120enddef
6121
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006122" Test for assigning to a member variable in a nested class
6123def Test_nested_object_assignment()
6124 var lines =<< trim END
6125 vim9script
6126
6127 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006128 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006129 endclass
6130
6131 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006132 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006133 endclass
6134
6135 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006136 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006137 endclass
6138
6139 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006140 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006141 endclass
6142
6143 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006144 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006145 enddef
6146
6147 var d = D.new()
6148 T(d)
6149 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006150 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006151enddef
6152
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006153" Test for calling methods using a null object
6154def Test_null_object_method_call()
6155 # Calling a object method using a null object in script context
6156 var lines =<< trim END
6157 vim9script
6158
6159 class C
6160 def Foo()
6161 assert_report('This method should not be executed')
6162 enddef
6163 endclass
6164
6165 var o: C
6166 o.Foo()
6167 END
6168 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6169
6170 # Calling a object method using a null object in def function context
6171 lines =<< trim END
6172 vim9script
6173
6174 class C
6175 def Foo()
6176 assert_report('This method should not be executed')
6177 enddef
6178 endclass
6179
6180 def T()
6181 var o: C
6182 o.Foo()
6183 enddef
6184 T()
6185 END
6186 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6187
6188 # Calling a object method through another class method using a null object in
6189 # script context
6190 lines =<< trim END
6191 vim9script
6192
6193 class C
6194 def Foo()
6195 assert_report('This method should not be executed')
6196 enddef
6197
6198 static def Bar(o_any: any)
6199 var o_typed: C = o_any
6200 o_typed.Foo()
6201 enddef
6202 endclass
6203
6204 var o: C
6205 C.Bar(o)
6206 END
6207 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6208
6209 # Calling a object method through another class method using a null object in
6210 # def function context
6211 lines =<< trim END
6212 vim9script
6213
6214 class C
6215 def Foo()
6216 assert_report('This method should not be executed')
6217 enddef
6218
6219 static def Bar(o_any: any)
6220 var o_typed: C = o_any
6221 o_typed.Foo()
6222 enddef
6223 endclass
6224
6225 def T()
6226 var o: C
6227 C.Bar(o)
6228 enddef
6229 T()
6230 END
6231 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6232enddef
6233
6234" Test for using a dict as an object member
6235def Test_dict_object_member()
6236 var lines =<< trim END
6237 vim9script
6238
6239 class Context
6240 public this.state: dict<number> = {}
6241 def GetState(): dict<number>
6242 return this.state
6243 enddef
6244 endclass
6245
6246 var ctx = Context.new()
6247 ctx.state->extend({a: 1})
6248 ctx.state['b'] = 2
6249 assert_equal({a: 1, b: 2}, ctx.GetState())
6250
6251 def F()
6252 ctx.state['c'] = 3
6253 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6254 enddef
6255 F()
6256 assert_equal(3, ctx.state.c)
6257 ctx.state.c = 4
6258 assert_equal(4, ctx.state.c)
6259 END
6260 v9.CheckSourceSuccess(lines)
6261enddef
6262
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006263" The following test was failing after 9.0.1914. This was caused by using a
6264" freed object from a previous method call.
6265def Test_freed_object_from_previous_method_call()
6266 var lines =<< trim END
6267 vim9script
6268
6269 class Context
6270 endclass
6271
6272 class Result
6273 endclass
6274
6275 def Failure(): Result
6276 return Result.new()
6277 enddef
6278
6279 def GetResult(ctx: Context): Result
6280 return Failure()
6281 enddef
6282
6283 def Test_GetResult()
6284 var ctx = Context.new()
6285 var result = GetResult(ctx)
6286 enddef
6287
6288 Test_GetResult()
6289 END
6290 v9.CheckSourceSuccess(lines)
6291enddef
6292
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006293" Test for duplicate object and class variable
6294def Test_duplicate_variable()
6295 # Object variable name is same as the class variable name
6296 var lines =<< trim END
6297 vim9script
6298 class A
6299 public static sval: number
6300 public this.sval: number
6301 endclass
6302 var a = A.new()
6303 END
6304 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6305
6306 # Duplicate variable name and calling a class method
6307 lines =<< trim END
6308 vim9script
6309 class A
6310 public static sval: number
6311 public this.sval: number
6312 def F1()
6313 echo this.sval
6314 enddef
6315 static def F2()
6316 echo sval
6317 enddef
6318 endclass
6319 A.F2()
6320 END
6321 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6322
6323 # Duplicate variable with an empty constructor
6324 lines =<< trim END
6325 vim9script
6326 class A
6327 public static sval: number
6328 public this.sval: number
6329 def new()
6330 enddef
6331 endclass
6332 var a = A.new()
6333 END
6334 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6335enddef
6336
6337" Test for using a reserved keyword as a variable name
6338def Test_reserved_varname()
6339 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6340 'null_function', 'null_list', 'null_partial', 'null_string',
6341 'null_channel', 'null_job', 'super', 'this']
6342
6343 var lines =<< trim eval END
6344 vim9script
6345 class C
6346 public this.{kword}: list<number> = [1, 2, 3]
6347 endclass
6348 var o = C.new()
6349 END
6350 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6351
6352 lines =<< trim eval END
6353 vim9script
6354 class C
6355 public this.{kword}: list<number> = [1, 2, 3]
6356 def new()
6357 enddef
6358 endclass
6359 var o = C.new()
6360 END
6361 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6362
6363 lines =<< trim eval END
6364 vim9script
6365 class C
6366 public this.{kword}: list<number> = [1, 2, 3]
6367 def new()
6368 enddef
6369 def F()
6370 echo this.{kword}
6371 enddef
6372 endclass
6373 var o = C.new()
6374 o.F()
6375 END
6376 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6377 endfor
6378enddef
6379
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006380" Test for checking the type of the arguments and the return value of a object
6381" method in an extended class.
6382def Test_extended_obj_method_type_check()
6383 var lines =<< trim END
6384 vim9script
6385
6386 class A
6387 endclass
6388 class B extends A
6389 endclass
6390 class C extends B
6391 endclass
6392
6393 class Foo
6394 def Doit(p: B): B
6395 return B.new()
6396 enddef
6397 endclass
6398
6399 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006400 def Doit(p: C): B
6401 return B.new()
6402 enddef
6403 endclass
6404 END
6405 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6406
6407 lines =<< trim END
6408 vim9script
6409
6410 class A
6411 endclass
6412 class B extends A
6413 endclass
6414 class C extends B
6415 endclass
6416
6417 class Foo
6418 def Doit(p: B): B
6419 return B.new()
6420 enddef
6421 endclass
6422
6423 class Bar extends Foo
6424 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006425 return C.new()
6426 enddef
6427 endclass
6428 END
6429 v9.CheckSourceSuccess(lines)
6430
6431 lines =<< trim END
6432 vim9script
6433
6434 class A
6435 endclass
6436 class B extends A
6437 endclass
6438 class C extends B
6439 endclass
6440
6441 class Foo
6442 def Doit(p: B): B
6443 return B.new()
6444 enddef
6445 endclass
6446
6447 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006448 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006449 return B.new()
6450 enddef
6451 endclass
6452 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006453 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 +02006454
6455 lines =<< trim END
6456 vim9script
6457
6458 class A
6459 endclass
6460 class B extends A
6461 endclass
6462 class C extends B
6463 endclass
6464
6465 class Foo
6466 def Doit(p: B): B
6467 return B.new()
6468 enddef
6469 endclass
6470
6471 class Bar extends Foo
6472 def Doit(p: B): A
6473 return A.new()
6474 enddef
6475 endclass
6476 END
6477 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
6478enddef
6479
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006480" Test type checking for class variable in assignments
6481func Test_class_variable_complex_type_check()
6482 " class variable with a specific type. Try assigning a different type at
6483 " script level.
6484 let lines =<< trim END
6485 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006486 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006487 return {}
6488 enddef
6489 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006490 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006491 endclass
6492 test_garbagecollect_now()
6493 A.Fn = "abc"
6494 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006495 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 +02006496
6497 " class variable with a specific type. Try assigning a different type at
6498 " class def method level.
6499 let lines =<< trim END
6500 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006501 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006502 return {}
6503 enddef
6504 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006505 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006506 def Bar()
6507 Fn = "abc"
6508 enddef
6509 endclass
6510 var a = A.new()
6511 test_garbagecollect_now()
6512 a.Bar()
6513 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006514 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 +02006515
6516 " class variable with a specific type. Try assigning a different type at
6517 " script def method level.
6518 let lines =<< trim END
6519 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006520 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006521 return {}
6522 enddef
6523 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006524 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006525 endclass
6526 def Bar()
6527 A.Fn = "abc"
6528 enddef
6529 test_garbagecollect_now()
6530 Bar()
6531 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006532 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 +02006533
6534 " class variable without any type. Should be set to the initialization
6535 " expression type. Try assigning a different type from script level.
6536 let lines =<< trim END
6537 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006538 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006539 return {}
6540 enddef
6541 class A
6542 public static Fn = Foo
6543 endclass
6544 test_garbagecollect_now()
6545 A.Fn = "abc"
6546 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006547 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 +02006548
6549 " class variable without any type. Should be set to the initialization
6550 " expression type. Try assigning a different type at class def level.
6551 let lines =<< trim END
6552 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006553 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006554 return {}
6555 enddef
6556 class A
6557 public static Fn = Foo
6558 def Bar()
6559 Fn = "abc"
6560 enddef
6561 endclass
6562 var a = A.new()
6563 test_garbagecollect_now()
6564 a.Bar()
6565 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006566 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 +02006567
6568 " class variable without any type. Should be set to the initialization
6569 " expression type. Try assigning a different type at script def level.
6570 let lines =<< trim END
6571 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006572 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006573 return {}
6574 enddef
6575 class A
6576 public static Fn = Foo
6577 endclass
6578 def Bar()
6579 A.Fn = "abc"
6580 enddef
6581 test_garbagecollect_now()
6582 Bar()
6583 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006584 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 +02006585
6586 " class variable with 'any" type. Can be assigned different types.
6587 let lines =<< trim END
6588 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006589 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006590 return {}
6591 enddef
6592 class A
6593 public static Fn: any = Foo
6594 public static Fn2: any
6595 endclass
6596 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006597 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006598 A.Fn = "abc"
6599 test_garbagecollect_now()
6600 assert_equal('string', typename(A.Fn))
6601 A.Fn2 = Foo
6602 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006603 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006604 A.Fn2 = "xyz"
6605 test_garbagecollect_now()
6606 assert_equal('string', typename(A.Fn2))
6607 END
6608 call v9.CheckSourceSuccess(lines)
6609
6610 " class variable with 'any" type. Can be assigned different types.
6611 let lines =<< trim END
6612 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006613 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006614 return {}
6615 enddef
6616 class A
6617 public static Fn: any = Foo
6618 public static Fn2: any
6619
6620 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006621 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006622 Fn = "abc"
6623 assert_equal('string', typename(Fn))
6624 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006625 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006626 Fn2 = "xyz"
6627 assert_equal('string', typename(Fn2))
6628 enddef
6629 endclass
6630 var a = A.new()
6631 test_garbagecollect_now()
6632 a.Bar()
6633 test_garbagecollect_now()
6634 A.Fn = Foo
6635 a.Bar()
6636 END
6637 call v9.CheckSourceSuccess(lines)
6638
6639 " class variable with 'any" type. Can be assigned different types.
6640 let lines =<< trim END
6641 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006642 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006643 return {}
6644 enddef
6645 class A
6646 public static Fn: any = Foo
6647 public static Fn2: any
6648 endclass
6649
6650 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006651 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006652 A.Fn = "abc"
6653 assert_equal('string', typename(A.Fn))
6654 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006655 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006656 A.Fn2 = "xyz"
6657 assert_equal('string', typename(A.Fn2))
6658 enddef
6659 Bar()
6660 test_garbagecollect_now()
6661 A.Fn = Foo
6662 Bar()
6663 END
6664 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006665
6666 let lines =<< trim END
6667 vim9script
6668 class A
6669 public static foo = [0z10, 0z20]
6670 endclass
6671 assert_equal([0z10, 0z20], A.foo)
6672 A.foo = [0z30]
6673 assert_equal([0z30], A.foo)
6674 var a = A.foo
6675 assert_equal([0z30], a)
6676 END
6677 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006678endfunc
6679
6680" Test type checking for object variable in assignments
6681func Test_object_variable_complex_type_check()
6682 " object variable with a specific type. Try assigning a different type at
6683 " script level.
6684 let lines =<< trim END
6685 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006686 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006687 return {}
6688 enddef
6689 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006690 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006691 endclass
6692 var a = A.new()
6693 test_garbagecollect_now()
6694 a.Fn = "abc"
6695 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006696 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 +02006697
6698 " object variable with a specific type. Try assigning a different type at
6699 " object def method level.
6700 let lines =<< trim END
6701 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006702 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006703 return {}
6704 enddef
6705 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006706 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006707 def Bar()
6708 this.Fn = "abc"
6709 this.Fn = Foo
6710 enddef
6711 endclass
6712 var a = A.new()
6713 test_garbagecollect_now()
6714 a.Bar()
6715 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006716 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 +02006717
6718 " object variable with a specific type. Try assigning a different type at
6719 " script def method level.
6720 let lines =<< trim END
6721 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006722 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006723 return {}
6724 enddef
6725 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006726 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006727 endclass
6728 def Bar()
6729 var a = A.new()
6730 a.Fn = "abc"
6731 a.Fn = Foo
6732 enddef
6733 test_garbagecollect_now()
6734 Bar()
6735 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006736 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 +02006737
6738 " object variable without any type. Should be set to the initialization
6739 " expression type. Try assigning a different type from script level.
6740 let lines =<< trim END
6741 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006742 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006743 return {}
6744 enddef
6745 class A
6746 public this.Fn = Foo
6747 endclass
6748 var a = A.new()
6749 test_garbagecollect_now()
6750 a.Fn = "abc"
6751 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006752 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 +02006753
6754 " object variable without any type. Should be set to the initialization
6755 " expression type. Try assigning a different type at object def level.
6756 let lines =<< trim END
6757 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006758 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006759 return {}
6760 enddef
6761 class A
6762 public this.Fn = Foo
6763 def Bar()
6764 this.Fn = "abc"
6765 this.Fn = Foo
6766 enddef
6767 endclass
6768 var a = A.new()
6769 test_garbagecollect_now()
6770 a.Bar()
6771 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006772 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 +02006773
6774 " object variable without any type. Should be set to the initialization
6775 " expression type. Try assigning a different type at script def level.
6776 let lines =<< trim END
6777 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006778 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006779 return {}
6780 enddef
6781 class A
6782 public this.Fn = Foo
6783 endclass
6784 def Bar()
6785 var a = A.new()
6786 a.Fn = "abc"
6787 a.Fn = Foo
6788 enddef
6789 test_garbagecollect_now()
6790 Bar()
6791 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006792 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 +02006793
6794 " object variable with 'any" type. Can be assigned different types.
6795 let lines =<< trim END
6796 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006797 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006798 return {}
6799 enddef
6800 class A
6801 public this.Fn: any = Foo
6802 public this.Fn2: any
6803 endclass
6804
6805 var a = A.new()
6806 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006807 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006808 a.Fn = "abc"
6809 test_garbagecollect_now()
6810 assert_equal('string', typename(a.Fn))
6811 a.Fn2 = Foo
6812 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006813 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006814 a.Fn2 = "xyz"
6815 test_garbagecollect_now()
6816 assert_equal('string', typename(a.Fn2))
6817 END
6818 call v9.CheckSourceSuccess(lines)
6819
6820 " object variable with 'any" type. Can be assigned different types.
6821 let lines =<< trim END
6822 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006823 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006824 return {}
6825 enddef
6826 class A
6827 public this.Fn: any = Foo
6828 public this.Fn2: any
6829
6830 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006831 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006832 this.Fn = "abc"
6833 assert_equal('string', typename(this.Fn))
6834 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006835 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006836 this.Fn2 = "xyz"
6837 assert_equal('string', typename(this.Fn2))
6838 enddef
6839 endclass
6840
6841 var a = A.new()
6842 test_garbagecollect_now()
6843 a.Bar()
6844 test_garbagecollect_now()
6845 a.Fn = Foo
6846 a.Bar()
6847 END
6848 call v9.CheckSourceSuccess(lines)
6849
6850 " object variable with 'any" type. Can be assigned different types.
6851 let lines =<< trim END
6852 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006853 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006854 return {}
6855 enddef
6856 class A
6857 public this.Fn: any = Foo
6858 public this.Fn2: any
6859 endclass
6860
6861 def Bar()
6862 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006863 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006864 a.Fn = "abc"
6865 assert_equal('string', typename(a.Fn))
6866 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006867 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006868 a.Fn2 = "xyz"
6869 assert_equal('string', typename(a.Fn2))
6870 enddef
6871 test_garbagecollect_now()
6872 Bar()
6873 test_garbagecollect_now()
6874 Bar()
6875 END
6876 call v9.CheckSourceSuccess(lines)
6877endfunc
6878
Bram Moolenaar00b28d62022-12-08 15:32:33 +00006879" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker