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