blob: 0c8fd7057a2712ed90a7f686b57b340611236b61 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020038 # Only the completed word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020070 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000071 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020072 vim9script
73 class Something
74 this
75 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020077 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020079 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000080 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020081 vim9script
82 class Something
83 this.
84 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000085 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020086 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000087
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020088 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000089 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020090 vim9script
91 class Something
92 this .count
93 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000094 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020095 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000096
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020099 vim9script
100 class Something
101 this. count
102 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200104 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200108 vim9script
109 class Something
110 this.count: number
111 that.count
112 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000113 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200114 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000115
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200116 # Member variable without a type or initialization
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200118 vim9script
119 class Something
120 this.count
121 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000122 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200123 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200125 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000126 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200127 vim9script
128 class Something
129 def new()
130 this.state = 0
131 enddef
132 endclass
133 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200135 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Something": state', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000136
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200137 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200139 vim9script
140 class Something
141 this.count : number
142 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200144 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000145
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200146 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000147 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200148 vim9script
149 class Something
150 this.count:number
151 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200153 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000154
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200155 # Test for unsupported comment specifier
156 lines =<< trim END
157 vim9script
158 class Something
159 # comment
160 #{
161 endclass
162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200164
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200165 # Test for using class as a bool
166 lines =<< trim END
167 vim9script
168 class A
169 endclass
170 if A
171 endif
172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200173 v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200174
175 # Test for using object as a bool
176 lines =<< trim END
177 vim9script
178 class A
179 endclass
180 var a = A.new()
181 if a
182 endif
183 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200184 v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200185
186 # Test for using class as a float
187 lines =<< trim END
188 vim9script
189 class A
190 endclass
191 sort([1.1, A], 'f')
192 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200193 v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200194
195 # Test for using object as a float
196 lines =<< trim END
197 vim9script
198 class A
199 endclass
200 var a = A.new()
201 sort([1.1, a], 'f')
202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200203 v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200204
205 # Test for using class as a string
206 lines =<< trim END
207 vim9script
208 class A
209 endclass
210 :exe 'call ' .. A
211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 v9.CheckSourceFailure(lines, 'E1323: Using a class as a String', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200213
214 # Test for using object as a string
215 lines =<< trim END
216 vim9script
217 class A
218 endclass
219 var a = A.new()
220 :exe 'call ' .. a
221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200222 v9.CheckSourceFailure(lines, 'E1324: Using an object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200223
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200224 # Test creating a class with member variables and methods, calling a object
225 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200227 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200229 class TextPosition
230 this.lnum: number
231 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000232
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200233 # make a nicely formatted string
234 def ToString(): string
235 return $'({this.lnum}, {this.col})'
236 enddef
237 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000238
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200239 # use the automatically generated new() method
240 var pos = TextPosition.new(2, 12)
241 assert_equal(2, pos.lnum)
242 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000243
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200244 # call an object method
245 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000246
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200247 assert_equal(v:t_class, type(TextPosition))
248 assert_equal(v:t_object, type(pos))
249 assert_equal('class<TextPosition>', typename(TextPosition))
250 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200253
254 # When referencing object methods, space cannot be used after a "."
255 lines =<< trim END
256 vim9script
257 class A
258 def Foo(): number
259 return 10
260 enddef
261 endclass
262 var a = A.new()
263 var v = a. Foo()
264 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200265 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200266
267 # Using an object without specifying a method or a member variable
268 lines =<< trim END
269 vim9script
270 class A
271 def Foo(): number
272 return 10
273 enddef
274 endclass
275 var a = A.new()
276 var v = a.
277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200278 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279
280 # Error when parsing the arguments of an object method.
281 lines =<< trim END
282 vim9script
283 class A
284 def Foo()
285 enddef
286 endclass
287 var a = A.new()
288 var v = a.Foo(,)
289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200290 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200291
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200292 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200293 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200294 vim9script
295 class A
296 this.y = {
297 X: 1
298 }
299 endclass
300 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200301 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200302 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000303enddef
304
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200305" Tests for object/class methods in a class
306def Test_class_def_method()
307 # Using the "public" keyword when defining an object method
308 var lines =<< trim END
309 vim9script
310 class A
311 public def Foo()
312 enddef
313 endclass
314 END
315 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
316
317 # Using the "public" keyword when defining a class method
318 lines =<< trim END
319 vim9script
320 class A
321 public static def Foo()
322 enddef
323 endclass
324 END
325 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
326
327 # Using the "public" keyword when defining an object private method
328 lines =<< trim END
329 vim9script
330 class A
331 public def _Foo()
332 enddef
333 endclass
334 END
335 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
336
337 # Using the "public" keyword when defining a class private method
338 lines =<< trim END
339 vim9script
340 class A
341 public static def _Foo()
342 enddef
343 endclass
344 END
345 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
346
347 # Using a "def" keyword without an object method name
348 lines =<< trim END
349 vim9script
350 class A
351 def
352 enddef
353 endclass
354 END
355 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
356
357 # Using a "def" keyword without a class method name
358 lines =<< trim END
359 vim9script
360 class A
361 static def
362 enddef
363 endclass
364 END
365 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
366enddef
367
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000368def Test_class_defined_twice()
369 # class defined twice should fail
370 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200371 vim9script
372 class There
373 endclass
374 class There
375 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200377 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000378
379 # one class, reload same script twice is OK
380 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200381 vim9script
382 class There
383 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000384 END
385 writefile(lines, 'XclassTwice.vim', 'D')
386 source XclassTwice.vim
387 source XclassTwice.vim
388enddef
389
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000390def Test_returning_null_object()
391 # this was causing an internal error
392 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200393 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200395 class BufferList
396 def Current(): any
397 return null_object
398 enddef
399 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000400
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 var buffers = BufferList.new()
402 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000403 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200404 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000405enddef
406
Bram Moolenaard13dd302023-03-11 20:56:35 +0000407def Test_using_null_class()
408 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200409 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000410 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200411 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000412enddef
413
Bram Moolenaar657aea72023-01-27 13:16:19 +0000414def Test_class_interface_wrong_end()
415 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200416 vim9script
417 abstract class SomeName
418 this.member = 'text'
419 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000420 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200421 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000422
423 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200424 vim9script
425 export interface AnotherName
426 this.member: string
427 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200429 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000430enddef
431
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000432def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200433 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000434 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200435 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200437 class State
438 this.value = 'xyz'
439 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200441 var state: State
442 var db = {'xyz': 789}
443 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000444 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200445 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000446
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200447 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200449 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200451 class Class
452 this.id: string
453 def Method1()
454 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000455 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200456 endclass
457
458 var obj: Class
459 def Func()
460 obj.Method1()
461 enddef
462 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200464 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000465
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200466 # Pass an uninitialized object variable to a "new" function and try to call an
467 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000468 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200469 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000470
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200471 class Background
472 this.background = 'dark'
473 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000474
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200475 class Colorscheme
476 this._bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000477
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200478 def GetBackground(): string
479 return this._bg.background
480 enddef
481 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 var bg: Background # UNINITIALIZED
484 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200486 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000487
488 # TODO: this should not give an error but be handled at runtime
489 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200490 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000491
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200492 class Class
493 this.id: string
494 def Method1()
495 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000496 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200497 endclass
498
499 var obj = null_object
500 def Func()
501 obj.Method1()
502 enddef
503 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200505 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000506enddef
507
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200508" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200509def Test_null_object_assign_compare()
510 var lines =<< trim END
511 vim9script
512
513 var nullo = null_object
514 def F(): any
515 return nullo
516 enddef
517 assert_equal('object<Unknown>', typename(F()))
518
519 var o0 = F()
520 assert_true(o0 == null_object)
521 assert_true(o0 == null)
522
523 var o1: any = nullo
524 assert_true(o1 == null_object)
525 assert_true(o1 == null)
526
527 def G()
528 var x = null_object
529 enddef
530
531 class C
532 endclass
533 var o2: C
534 assert_true(o2 == null_object)
535 assert_true(o2 == null)
536
537 o2 = null_object
538 assert_true(o2 == null)
539
540 o2 = C.new()
541 assert_true(o2 != null)
542
543 o2 = null_object
544 assert_true(o2 == null)
545 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200546 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200547enddef
548
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200549" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000550def Test_class_member_initializer()
551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200554 class TextPosition
555 this.lnum: number = 1
556 this.col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000557
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200558 # constructor with only the line number
559 def new(lnum: number)
560 this.lnum = lnum
561 enddef
562 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000563
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200564 var pos = TextPosition.new(3)
565 assert_equal(3, pos.lnum)
566 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200568 var instr = execute('disassemble TextPosition.new')
569 assert_match('new\_s*' ..
570 '0 NEW TextPosition size \d\+\_s*' ..
571 '\d PUSHNR 1\_s*' ..
572 '\d STORE_THIS 0\_s*' ..
573 '\d PUSHNR 1\_s*' ..
574 '\d STORE_THIS 1\_s*' ..
575 'this.lnum = lnum\_s*' ..
576 '\d LOAD arg\[-1]\_s*' ..
577 '\d PUSHNR 0\_s*' ..
578 '\d LOAD $0\_s*' ..
579 '\d\+ STOREINDEX object\_s*' ..
580 '\d\+ RETURN object.*',
581 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000582 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200583 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000584enddef
585
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000586def Test_member_any_used_as_object()
587 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200588 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000589
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200590 class Inner
591 this.value: number = 0
592 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000593
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200594 class Outer
595 this.inner: any
596 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200598 def F(outer: Outer)
599 outer.inner.value = 1
600 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000601
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200602 var inner_obj = Inner.new(0)
603 var outer_obj = Outer.new(inner_obj)
604 F(outer_obj)
605 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000606 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200607 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000608
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200609 # Try modifying a private variable using an "any" object
610 lines =<< trim END
611 vim9script
612
613 class Inner
614 this._value: string = ''
615 endclass
616
617 class Outer
618 this.inner: any
619 endclass
620
621 def F(outer: Outer)
622 outer.inner._value = 'b'
623 enddef
624
625 var inner_obj = Inner.new('a')
626 var outer_obj = Outer.new(inner_obj)
627 F(outer_obj)
628 END
Ernie Rael64885642023-10-04 20:16:22 +0200629 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200630
631 # Try modifying a non-existing variable using an "any" object
632 lines =<< trim END
633 vim9script
634
635 class Inner
636 this.value: string = ''
637 endclass
638
639 class Outer
640 this.inner: any
641 endclass
642
643 def F(outer: Outer)
644 outer.inner.someval = 'b'
645 enddef
646
647 var inner_obj = Inner.new('a')
648 var outer_obj = Outer.new(inner_obj)
649 F(outer_obj)
650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200651 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Inner": someval', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000652enddef
653
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200654" Nested assignment to a object variable which is of another class type
655def Test_assignment_nested_type()
656 var lines =<< trim END
657 vim9script
658
659 class Inner
660 public this.value: number = 0
661 endclass
662
663 class Outer
664 this.inner: Inner
665 endclass
666
667 def F(outer: Outer)
668 outer.inner.value = 1
669 enddef
670
671 def Test_assign_to_nested_typed_member()
672 var inner = Inner.new(0)
673 var outer = Outer.new(inner)
674 F(outer)
675 assert_equal(1, inner.value)
676 enddef
677
678 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200679
680 var script_inner = Inner.new(0)
681 var script_outer = Outer.new(script_inner)
682 script_outer.inner.value = 1
683 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200684 END
685 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200686
687 # Assignment where target item is read only in :def
688 lines =<< trim END
689 vim9script
690
691 class Inner
692 this.value: number = 0
693 endclass
694
695 class Outer
696 this.inner: Inner
697 endclass
698
699 def F(outer: Outer)
700 outer.inner.value = 1
701 enddef
702
703 def Test_assign_to_nested_typed_member()
704 var inner = Inner.new(0)
705 var outer = Outer.new(inner)
706 F(outer)
707 assert_equal(1, inner.value)
708 enddef
709
710 Test_assign_to_nested_typed_member()
711 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200713
714 # Assignment where target item is read only script level
715 lines =<< trim END
716 vim9script
717
718 class Inner
719 this.value: number = 0
720 endclass
721
722 class Outer
723 this.inner: Inner
724 endclass
725
726 def F(outer: Outer)
727 outer.inner.value = 1
728 enddef
729
730 var script_inner = Inner.new(0)
731 var script_outer = Outer.new(script_inner)
732 script_outer.inner.value = 1
733 assert_equal(1, script_inner.value)
734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200735 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200736enddef
737
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000738def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200739 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000740 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200741 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000742
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200743 class Foo
744 public this.x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 def Add(n: number)
747 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100748 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200749 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200751 var f = Foo.new(3)
752 f.Add(17)
753 assert_equal(20, f.x)
754
755 def AddToFoo(obj: Foo)
756 obj.x += 3
757 enddef
758
759 AddToFoo(f)
760 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000761 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200762 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000763enddef
764
Bram Moolenaarf4508042023-01-15 16:54:57 +0000765def Test_list_of_objects()
766 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200767 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200769 class Foo
770 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000771 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200772 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000773
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200774 def ProcessList(fooList: list<Foo>)
775 for foo in fooList
776 foo.Add()
777 endfor
778 enddef
779
780 var l: list<Foo> = [Foo.new()]
781 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000782 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200783 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000784enddef
785
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000786def Test_expr_after_using_object()
787 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Something
791 this.label: string = ''
792 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def Foo(): Something
795 var v = Something.new()
796 echo 'in Foo(): ' .. typename(v)
797 return v
798 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000799
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000801 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200802 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000803enddef
804
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000805def Test_class_default_new()
806 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200807 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000808
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200809 class TextPosition
810 this.lnum: number = 1
811 this.col: number = 1
812 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000813
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200814 var pos = TextPosition.new()
815 assert_equal(1, pos.lnum)
816 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200818 pos = TextPosition.new(v:none, v:none)
819 assert_equal(1, pos.lnum)
820 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000821
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200822 pos = TextPosition.new(3, 22)
823 assert_equal(3, pos.lnum)
824 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200826 pos = TextPosition.new(v:none, 33)
827 assert_equal(1, pos.lnum)
828 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000829 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200830 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000831
832 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200833 vim9script
834 class Person
835 this.name: string
836 this.age: number = 42
837 this.education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 def new(this.name, this.age = v:none, this.education = v:none)
840 enddef
841 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000842
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200843 var piet = Person.new("Piet")
844 assert_equal("Piet", piet.name)
845 assert_equal(42, piet.age)
846 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000847
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200848 var chris = Person.new("Chris", 4, "none")
849 assert_equal("Chris", chris.name)
850 assert_equal(4, chris.age)
851 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000852 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200853 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000854
855 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200856 vim9script
857 class Person
858 this.name: string
859 this.age: number = 42
860 this.education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def new(this.name, this.age = v:none, this.education = v:none)
863 enddef
864 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200866 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200868 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200869
870 # Using a specific value to initialize an instance variable in the new()
871 # method.
872 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200873 vim9script
874 class A
875 this.val: string
876 def new(this.val = 'a')
877 enddef
878 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200879 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000881enddef
882
h-east2261c892023-08-16 21:49:54 +0900883def Test_class_new_with_object_member()
884 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200885 vim9script
h-east2261c892023-08-16 21:49:54 +0900886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200887 class C
888 this.str: string
889 this.num: number
890 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900891 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200892 def newVals(this.str, this.num)
893 enddef
894 endclass
h-east2261c892023-08-16 21:49:54 +0900895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200896 def Check()
897 try
898 var c = C.new('cats', 2)
899 assert_equal('cats', c.str)
900 assert_equal(2, c.num)
901
902 c = C.newVals('dogs', 4)
903 assert_equal('dogs', c.str)
904 assert_equal(4, c.num)
905 catch
906 assert_report($'Unexpected exception was caught: {v:exception}')
907 endtry
908 enddef
909
910 Check()
h-east2261c892023-08-16 21:49:54 +0900911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200912 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900913
914 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +0200915 vim9script
916
917 class C
918 this.str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200919 this.num: number
920 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +0200921 enddef
922 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200923
924 def Check()
925 try
926 var c = C.new(1, 2)
927 catch
928 assert_report($'Unexpected exception was caught: {v:exception}')
929 endtry
930 enddef
931
932 Check()
h-eastdb385522023-09-28 22:18:19 +0200933 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +0200935
936 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
h-eastb895b0f2023-09-24 15:46:31 +0200938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class C
940 this.str: string
941 this.num: number
942 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +0200943 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 endclass
h-eastb895b0f2023-09-24 15:46:31 +0200945
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 def Check()
947 try
948 var c = C.newVals('dogs', 'apes')
949 catch
950 assert_report($'Unexpected exception was caught: {v:exception}')
951 endtry
952 enddef
953
954 Check()
955 END
956 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
957
958 lines =<< trim END
959 vim9script
960
961 class C
962 this.str: string
963 def new(str: any)
964 enddef
965 endclass
966
967 def Check()
968 try
969 var c = C.new(1)
970 catch
971 assert_report($'Unexpected exception was caught: {v:exception}')
972 endtry
973 enddef
974
975 Check()
h-eastb895b0f2023-09-24 15:46:31 +0200976 END
977 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900978enddef
979
Bram Moolenaar74e12742022-12-13 21:14:28 +0000980def Test_class_object_member_inits()
981 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200982 vim9script
983 class TextPosition
984 this.lnum: number
985 this.col = 1
986 this.addcol: number = 2
987 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000988
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200989 var pos = TextPosition.new()
990 assert_equal(0, pos.lnum)
991 assert_equal(1, pos.col)
992 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000993 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200994 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000995
996 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 vim9script
998 class TextPosition
999 this.lnum
1000 this.col = 1
1001 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001004
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001005 # If the type is not specified for a member, then it should be set during
1006 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001007 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var init_count = 0
1011 def Init(): string
1012 init_count += 1
1013 return 'foo'
1014 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001015
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 class A
1017 this.str1 = Init()
1018 this.str2: string = Init()
1019 this.col = 1
1020 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 assert_equal(init_count, 0)
1023 var a = A.new()
1024 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001027
1028 # Test for initializing an object member with an unknown variable/type
1029 lines =<< trim END
1030 vim9script
1031 class A
1032 this.value = init_val
1033 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001034 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001036 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001037
1038 # Test for initializing an object member with an special type
1039 lines =<< trim END
1040 vim9script
1041 class A
1042 this.value: void
1043 endclass
1044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001046enddef
1047
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048" Test for instance variable access
1049def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001050 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 vim9script
1052 class Triple
1053 this._one = 1
1054 this.two = 2
1055 public this.three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001056
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001057 def GetOne(): number
1058 return this._one
1059 enddef
1060 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var trip = Triple.new()
1063 assert_equal(1, trip.GetOne())
1064 assert_equal(2, trip.two)
1065 assert_equal(3, trip.three)
Ernie Rael64885642023-10-04 20:16:22 +02001066 assert_fails('echo trip._one', 'E1333: Cannot access private variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001067
Ernie Rael64885642023-10-04 20:16:22 +02001068 assert_fails('trip._one = 11', 'E1333: Cannot access private variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001069 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1070 trip.three = 33
1071 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 assert_fails('trip.four = 4', 'E1326: Variable not found on object "Triple": four')
Bram Moolenaard505d172022-12-18 21:42:55 +00001074 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001075 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001076
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001077 # Test for a public member variable name beginning with an underscore
1078 lines =<< trim END
1079 vim9script
1080 class A
1081 public this._val = 10
1082 endclass
1083 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001084 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001085
Bram Moolenaar590162c2022-12-24 21:24:06 +00001086 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001087 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001088
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001089 class MyCar
1090 this.make: string
1091 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001092
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001093 def new(make_arg: string)
1094 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001095 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001096
1097 def GetMake(): string
1098 return $"make = {this.make}"
1099 enddef
1100 def GetAge(): number
1101 return this.age
1102 enddef
1103 endclass
1104
1105 var c = MyCar.new("abc")
1106 assert_equal('make = abc', c.GetMake())
1107
1108 c = MyCar.new("def")
1109 assert_equal('make = def', c.GetMake())
1110
1111 var c2 = MyCar.new("123")
1112 assert_equal('make = 123', c2.GetMake())
1113
1114 def CheckCar()
1115 assert_equal("make = def", c.GetMake())
1116 assert_equal(5, c.GetAge())
1117 enddef
1118 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001119 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001120 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001121
1122 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001123 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001124
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001125 class MyCar
1126 this.make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001127
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001128 def new(make_arg: string)
1129 this.make = make_arg
1130 enddef
1131 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001132
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 var c = MyCar.new("abc")
1134 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001136 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001137
1138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001139 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001141 class Foo
1142 this.x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001143
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001144 def Add(n: number): any
1145 this.x->add(n)
1146 return this
1147 enddef
1148 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001150 echo Foo.new().Add(1).Add(2).x
1151 echo Foo.new().Add(1).Add(2)
1152 .x
1153 echo Foo.new().Add(1)
1154 .Add(2).x
1155 echo Foo.new()
1156 .Add(1).Add(2).x
1157 echo Foo.new()
1158 .Add(1)
1159 .Add(2)
1160 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001161 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001162 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001163
1164 # Test for "public" cannot be abbreviated
1165 lines =<< trim END
1166 vim9script
1167 class Something
1168 pub this.val = 1
1169 endclass
1170 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001171 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001172
1173 # Test for "public" keyword must be followed by "this" or "static".
1174 lines =<< trim END
1175 vim9script
1176 class Something
1177 public val = 1
1178 endclass
1179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001180 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001181
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001182 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001183 lines =<< trim END
1184 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001185 class A
1186 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001187 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001188 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001191
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001192 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001193 lines =<< trim END
1194 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001195 class A
1196 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001197 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001198 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001201
1202 # Modify a instance variable using the class name in a def function
1203 lines =<< trim END
1204 vim9script
1205 class A
1206 public this.val = 1
1207 endclass
1208 def T()
1209 A.val = 1
1210 enddef
1211 T()
1212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001213 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214
1215 # Read a instance variable using the class name in a def function
1216 lines =<< trim END
1217 vim9script
1218 class A
1219 public this.val = 1
1220 endclass
1221 def T()
1222 var i = A.val
1223 enddef
1224 T()
1225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001227
1228 # Access from child class extending a class:
1229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001230 vim9script
1231 class A
1232 this.ro_obj_var = 10
1233 public this.rw_obj_var = 20
1234 this._priv_obj_var = 30
1235 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001237 class B extends A
1238 def Foo()
1239 var x: number
1240 x = this.ro_obj_var
1241 this.ro_obj_var = 0
1242 x = this.rw_obj_var
1243 this.rw_obj_var = 0
1244 x = this._priv_obj_var
1245 this._priv_obj_var = 0
1246 enddef
1247 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 var b = B.new()
1250 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001251 END
1252 v9.CheckSourceSuccess(lines)
1253enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001254
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001255" Test for class variable access
1256def Test_class_variable_access()
1257 # Test for "static" cannot be abbreviated
1258 var lines =<< trim END
1259 vim9script
1260 class Something
1261 stat this.val = 1
1262 endclass
1263 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001264 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001265
1266 # Test for "static" cannot be followed by "this".
1267 lines =<< trim END
1268 vim9script
1269 class Something
1270 static this.val = 1
1271 endclass
1272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001274
1275 # Test for "static" cannot be followed by "public".
1276 lines =<< trim END
1277 vim9script
1278 class Something
1279 static public val = 1
1280 endclass
1281 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001282 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001283
1284 # A readonly class variable cannot be modified from a child class
1285 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 vim9script
1287 class A
1288 static ro_class_var = 40
1289 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001290
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001291 class B extends A
1292 def Foo()
1293 A.ro_class_var = 50
1294 enddef
1295 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001297 var b = B.new()
1298 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001299 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001301
1302 # A private class variable cannot be accessed from a child class
1303 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001304 vim9script
1305 class A
1306 static _priv_class_var = 60
1307 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001309 class B extends A
1310 def Foo()
1311 var i = A._priv_class_var
1312 enddef
1313 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001314
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001315 var b = B.new()
1316 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001317 END
Ernie Rael64885642023-10-04 20:16:22 +02001318 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001319
1320 # A private class variable cannot be modified from a child class
1321 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001322 vim9script
1323 class A
1324 static _priv_class_var = 60
1325 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001327 class B extends A
1328 def Foo()
1329 A._priv_class_var = 0
1330 enddef
1331 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001332
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001333 var b = B.new()
1334 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001335 END
Ernie Rael64885642023-10-04 20:16:22 +02001336 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001337
1338 # Access from child class extending a class and from script context
1339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 vim9script
1341 class A
1342 static ro_class_var = 10
1343 public static rw_class_var = 20
1344 static _priv_class_var = 30
1345 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001347 class B extends A
1348 def Foo()
1349 var x: number
1350 x = A.ro_class_var
1351 assert_equal(10, x)
1352 x = A.rw_class_var
1353 assert_equal(25, x)
1354 A.rw_class_var = 20
1355 assert_equal(20, A.rw_class_var)
1356 enddef
1357 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 assert_equal(10, A.ro_class_var)
1360 assert_equal(20, A.rw_class_var)
1361 A.rw_class_var = 25
1362 assert_equal(25, A.rw_class_var)
1363 var b = B.new()
1364 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 END
1366 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001367enddef
1368
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001369def Test_class_object_compare()
1370 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001371 vim9script
1372 class Item
1373 this.nr = 0
1374 this.name = 'xx'
1375 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001376 END
1377
1378 # used at the script level and in a compiled function
1379 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001380 var i1 = Item.new()
1381 assert_equal(i1, i1)
1382 assert_true(i1 is i1)
1383 var i2 = Item.new()
1384 assert_equal(i1, i2)
1385 assert_false(i1 is i2)
1386 var i3 = Item.new(0, 'xx')
1387 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001388
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001389 var io1 = Item.new(1, 'xx')
1390 assert_notequal(i1, io1)
1391 var io2 = Item.new(0, 'yy')
1392 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001393 END
1394
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001395 v9.CheckSourceSuccess(class_lines + test_lines)
1396 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001397 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001398
1399 for op in ['>', '>=', '<', '<=', '=~', '!~']
1400 var op_lines = [
1401 'var i1 = Item.new()',
1402 'var i2 = Item.new()',
1403 'echo i1 ' .. op .. ' i2',
1404 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001407 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001408 endfor
1409enddef
1410
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001411def Test_object_type()
1412 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001413 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001414
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001415 class One
1416 this.one = 1
1417 endclass
1418 class Two
1419 this.two = 2
1420 endclass
1421 class TwoMore extends Two
1422 this.more = 9
1423 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001425 var o: One = One.new()
1426 var t: Two = Two.new()
1427 var m: TwoMore = TwoMore.new()
1428 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001429
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001430 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001431 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001433
1434 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001437 class One
1438 this.one = 1
1439 endclass
1440 class Two
1441 this.two = 2
1442 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001443
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001445 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001447
1448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001449 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001451 interface One
1452 def GetMember(): number
1453 endinterface
1454 class Two implements One
1455 this.one = 1
1456 def GetMember(): number
1457 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001458 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001460
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001461 var o: One = Two.new(5)
1462 assert_equal(5, o.GetMember())
1463 END
1464 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001466 lines =<< trim END
1467 vim9script
1468
1469 class Num
1470 this.n: number = 0
1471 endclass
1472
1473 def Ref(name: string): func(Num): Num
1474 return (arg: Num): Num => {
1475 return eval(name)(arg)
1476 }
1477 enddef
1478
1479 const Fn = Ref('Double')
1480 var Double = (m: Num): Num => Num.new(m.n * 2)
1481
1482 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001483 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001484 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001485enddef
1486
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001487def Test_class_member()
1488 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001489 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 vim9script
1491 class TextPos
1492 this.lnum = 1
1493 this.col = 1
1494 static counter = 0
1495 static _secret = 7
1496 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 static def AddToCounter(nr: number)
1499 counter += nr
1500 enddef
1501 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001502
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001503 assert_equal(0, TextPos.counter)
1504 TextPos.AddToCounter(3)
1505 assert_equal(3, TextPos.counter)
1506 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 def GetCounter(): number
1509 return TextPos.counter
1510 enddef
1511 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1514 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1515 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001516
Ernie Rael64885642023-10-04 20:16:22 +02001517 assert_fails('echo TextPos._secret', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
1518 assert_fails('TextPos._secret = 8', 'E1333: Cannot access private variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001519
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 assert_equal(42, TextPos.anybody)
1521 TextPos.anybody = 12
1522 assert_equal(12, TextPos.anybody)
1523 TextPos.anybody += 5
1524 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001525 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001527
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001528 # example in the help
1529 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 vim9script
1531 class OtherThing
1532 this.size: number
1533 static totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 def new(this.size)
1536 totalSize += this.size
1537 enddef
1538 endclass
1539 assert_equal(0, OtherThing.totalSize)
1540 var to3 = OtherThing.new(3)
1541 assert_equal(3, OtherThing.totalSize)
1542 var to7 = OtherThing.new(7)
1543 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001544 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001545 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001546
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001547 # using static class member twice
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001550
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 class HTML
1552 static author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 static def MacroSubstitute(s: string): string
1555 return substitute(s, '{{author}}', author, 'gi')
1556 enddef
1557 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001559 assert_equal('some text', HTML.MacroSubstitute('some text'))
1560 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001561 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001562 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001563
Bram Moolenaar62a69232023-01-24 15:07:04 +00001564 # access private member in lambda
1565 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001566 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 class Foo
1569 this._x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001570
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 def Add(n: number): number
1572 const F = (): number => this._x + n
1573 return F()
1574 enddef
1575 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001576
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001577 var foo = Foo.new()
1578 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001579 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001580 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001581
h-east2bd6a092023-05-19 19:01:17 +01001582 # access private member in lambda body
1583 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001585
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 class Foo
1587 this._x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001588
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 def Add(n: number): number
1590 var Lam = () => {
1591 this._x = this._x + n
1592 }
1593 Lam()
1594 return this._x
1595 enddef
1596 endclass
h-east2bd6a092023-05-19 19:01:17 +01001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var foo = Foo.new()
1599 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001600 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001601 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001602
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001603 # check shadowing
1604 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001605 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001606
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001607 class Some
1608 static count = 0
1609 def Method(count: number)
1610 echo count
1611 enddef
1612 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 var s = Some.new()
1615 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001617 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001618
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001619 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001620 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001622
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001623 class Some
1624 static count = 0
1625 def Method(arg: number)
1626 var count = 3
1627 echo arg count
1628 enddef
1629 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001630
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 var s = Some.new()
1632 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001635
1636 # Test for using an invalid type for a member variable
1637 lines =<< trim END
1638 vim9script
1639 class A
1640 this.val: xxx
1641 endclass
1642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001643 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001644
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001645 # Test for setting a member on a null object
1646 lines =<< trim END
1647 vim9script
1648 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001649 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001650 endclass
1651
1652 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var obj: A
1654 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001655 enddef
1656 F()
1657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001659
1660 # Test for accessing a member on a null object
1661 lines =<< trim END
1662 vim9script
1663 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001664 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001665 endclass
1666
1667 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 var obj: A
1669 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001670 enddef
1671 F()
1672 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001673 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001674
1675 # Test for setting a member on a null object, at script level
1676 lines =<< trim END
1677 vim9script
1678 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001680 endclass
1681
1682 var obj: A
1683 obj.val = ""
1684 END
1685 # FIXME(in source): this should give E1360 as well!
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001687
1688 # Test for accessing a member on a null object, at script level
1689 lines =<< trim END
1690 vim9script
1691 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001692 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001693 endclass
1694
1695 var obj: A
1696 echo obj.val
1697 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001698 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001699
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001700 # Test for no space before or after the '=' when initializing a member
1701 # variable
1702 lines =<< trim END
1703 vim9script
1704 class A
1705 this.val: number= 10
1706 endclass
1707 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001709 lines =<< trim END
1710 vim9script
1711 class A
1712 this.val: number =10
1713 endclass
1714 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001716
1717 # Access a non-existing member
1718 lines =<< trim END
1719 vim9script
1720 class A
1721 endclass
1722 var a = A.new()
1723 var v = a.bar
1724 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": bar', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001726enddef
1727
Ernie Raele6c9aa52023-10-06 19:55:52 +02001728" These messages should show the defining class of the variable (base class),
1729" not the class that did the reference (super class)
1730def Test_defining_class_message()
1731 var lines =<< trim END
1732 vim9script
1733
1734 class Base
1735 this._v1: list<list<number>>
1736 endclass
1737
1738 class Child extends Base
1739 endclass
1740
1741 var o = Child.new()
1742 var x = o._v1
1743 END
1744 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 11)
1745 lines =<< trim END
1746 vim9script
1747
1748 class Base
1749 this._v1: list<list<number>>
1750 endclass
1751
1752 class Child extends Base
1753 endclass
1754
1755 def F()
1756 var o = Child.new()
1757 var x = o._v1
1758 enddef
1759 F()
1760 END
1761 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 2)
1762 lines =<< trim END
1763 vim9script
1764
1765 class Base
1766 this.v1: list<list<number>>
1767 endclass
1768
1769 class Child extends Base
1770 endclass
1771
1772 var o = Child.new()
1773 o.v1 = []
1774 END
1775 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1776 lines =<< trim END
1777 vim9script
1778
1779 class Base
1780 this.v1: list<list<number>>
1781 endclass
1782
1783 class Child extends Base
1784 endclass
1785
1786 def F()
1787 var o = Child.new()
1788 o.v1 = []
1789 enddef
1790 F()
1791 END
1792
1793 # Attempt to read a private variable that is in the middle
1794 # of the class hierarchy.
1795 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1796 lines =<< trim END
1797 vim9script
1798
1799 class Base0
1800 endclass
1801
1802 class Base extends Base0
1803 this._v1: list<list<number>>
1804 endclass
1805
1806 class Child extends Base
1807 endclass
1808
1809 def F()
1810 var o = Child.new()
1811 var x = o._v1
1812 enddef
1813 F()
1814 END
1815 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Base"', 2)
1816
1817 # Attempt to read a private variable that is at the start
1818 # of the class hierarchy.
1819 lines =<< trim END
1820 vim9script
1821
1822 class Base0
1823 endclass
1824
1825 class Base extends Base0
1826 endclass
1827
1828 class Child extends Base
1829 this._v1: list<list<number>>
1830 endclass
1831
1832 def F()
1833 var o = Child.new()
1834 var x = o._v1
1835 enddef
1836 F()
1837 END
1838 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "Child"', 2)
1839enddef
1840
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001841func Test_class_garbagecollect()
1842 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001843 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001844
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001845 class Point
1846 this.p = [2, 3]
1847 static pl = ['a', 'b']
1848 static pd = {a: 'a', b: 'b'}
1849 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001850
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001851 echo Point.pl Point.pd
1852 call test_garbagecollect_now()
1853 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001854 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001855 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001856
1857 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001858 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001859
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001860 interface View
1861 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001862
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001863 class Widget
1864 this.view: View
1865 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001866
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001867 class MyView implements View
1868 this.widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001869
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001870 def new()
1871 # this will result in a circular reference to this object
1872 this.widget = Widget.new(this)
1873 enddef
1874 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001875
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001876 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001877
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001878 # overwrite "view", will be garbage-collected next
1879 view = MyView.new()
1880 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001881 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001882 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001883endfunc
1884
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001885" Test interface garbage collection
1886func Test_interface_garbagecollect()
1887 let lines =<< trim END
1888 vim9script
1889
1890 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001891 this.ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001892
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001893 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001894 endinterface
1895
1896 class A implements I
1897 static ro_class_var: number = 10
1898 public static rw_class_var: number = 20
1899 static _priv_class_var: number = 30
1900 this.ro_obj_var: number = 40
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001901 this._priv_obj_var: number = 60
1902
1903 static def _ClassBar(): number
1904 return _priv_class_var
1905 enddef
1906
1907 static def ClassFoo(): number
1908 return ro_class_var + rw_class_var + A._ClassBar()
1909 enddef
1910
1911 def _ObjBar(): number
1912 return this._priv_obj_var
1913 enddef
1914
1915 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001916 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001917 enddef
1918 endclass
1919
1920 assert_equal(60, A.ClassFoo())
1921 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001922 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001923 test_garbagecollect_now()
1924 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001925 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001926 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001927 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001928endfunc
1929
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001930def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001931 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001932 vim9script
1933 class Value
1934 this.value = 0
1935 static objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001936
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001937 def new(v: number)
1938 this.value = v
1939 ++objects
1940 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001941
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001942 static def GetCount(): number
1943 return objects
1944 enddef
1945 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001946
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001947 assert_equal(0, Value.GetCount())
1948 var v1 = Value.new(2)
1949 assert_equal(1, Value.GetCount())
1950 var v2 = Value.new(7)
1951 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001952 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001953 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001954
1955 # Test for cleaning up after a class definition failure when using class
1956 # functions.
1957 lines =<< trim END
1958 vim9script
1959 class A
1960 static def Foo()
1961 enddef
1962 aaa
1963 endclass
1964 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001965 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001966
1967 # Test for calling a class method from another class method without the class
1968 # name prefix.
1969 lines =<< trim END
1970 vim9script
1971 class A
1972 static myList: list<number> = [1]
1973 static def Foo(n: number)
1974 myList->add(n)
1975 enddef
1976 static def Bar()
1977 Foo(2)
1978 enddef
1979 def Baz()
1980 Foo(3)
1981 enddef
1982 endclass
1983 A.Bar()
1984 var a = A.new()
1985 a.Baz()
1986 assert_equal([1, 2, 3], A.myList)
1987 END
1988 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001989enddef
1990
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001991def Test_class_defcompile()
1992 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001993 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001994
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001995 class C
1996 def Fo(i: number): string
1997 return i
1998 enddef
1999 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002000
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002001 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002003 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002004
2005 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002006 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002007
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002008 class C
2009 static def Fc(): number
2010 return 'x'
2011 enddef
2012 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002013
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002014 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002015 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002017
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002018 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002019 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002021 class C
2022 static def new()
2023 enddef
2024 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002026 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002028 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002029
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002030 # Trying to compile a function using a non-existing class variable
2031 lines =<< trim END
2032 vim9script
2033 defcompile x.Foo()
2034 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002035 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002036
2037 # Trying to compile a function using a variable which is not a class
2038 lines =<< trim END
2039 vim9script
2040 var x: number
2041 defcompile x.Foo()
2042 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002043 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002044
2045 # Trying to compile a function without specifying the name
2046 lines =<< trim END
2047 vim9script
2048 class A
2049 endclass
2050 defcompile A.
2051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002052 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002053
2054 # Trying to compile a non-existing class object member function
2055 lines =<< trim END
2056 vim9script
2057 class A
2058 endclass
2059 var a = A.new()
2060 defcompile a.Foo()
2061 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002062 v9.CheckSourceFailureList(lines, ['E1326: Variable not found on object "A": Foo', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002063enddef
2064
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002065def Test_class_object_to_string()
2066 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002067 vim9script
2068 class TextPosition
2069 this.lnum = 1
2070 this.col = 22
2071 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002074
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002075 var pos = TextPosition.new()
2076 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002077 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002078 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002079enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002080
Bram Moolenaar554d0312023-01-05 19:59:18 +00002081def Test_interface_basics()
2082 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002083 vim9script
2084 interface Something
2085 this.ro_var: list<number>
2086 def GetCount(): number
2087 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002088 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002089 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002090
2091 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002092 interface SomethingWrong
2093 static count = 7
2094 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002095 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002096 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002097
2098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002099 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002100
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002101 interface Some
2102 this.value: number
2103 def Method(value: number)
2104 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002105 END
h-east61378a12023-04-18 19:07:29 +01002106 # The argument name and the object member name are the same, but this is not a
2107 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002108 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002109
2110 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002111 vim9script
2112 interface somethingWrong
2113 static count = 7
2114 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002115 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002116 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002117
2118 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 vim9script
2120 interface SomethingWrong
2121 this.value: string
2122 this.count = 7
2123 def GetCount(): number
2124 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002125 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002126 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002127
2128 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002129 vim9script
2130 interface SomethingWrong
2131 this.value: string
2132 this.count: number
2133 def GetCount(): number
2134 return 5
2135 enddef
2136 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002137 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002138 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002139
2140 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002141 vim9script
2142 export interface EnterExit
2143 def Enter(): void
2144 def Exit(): void
2145 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002146 END
2147 writefile(lines, 'XdefIntf.vim', 'D')
2148
2149 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 vim9script
2151 import './XdefIntf.vim' as defIntf
2152 export def With(ee: defIntf.EnterExit, F: func)
2153 ee.Enter()
2154 try
2155 F()
2156 finally
2157 ee.Exit()
2158 endtry
2159 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002160 END
2161 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002162
2163 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002164 vim9script
2165 export abstract class EnterExit
2166 def Enter(): void
2167 enddef
2168 def Exit(): void
2169 enddef
2170 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002171 END
2172 writefile(imported, 'XdefIntf2.vim', 'D')
2173
2174 lines[1] = " import './XdefIntf2.vim' as defIntf"
2175 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002176enddef
2177
Bram Moolenaar94674f22023-01-06 18:42:20 +00002178def Test_class_implements_interface()
2179 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002180 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002181
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002182 interface Some
2183 this.count: number
2184 def Method(nr: number)
2185 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002186
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002187 class SomeImpl implements Some
2188 this.count: number
2189 def Method(nr: number)
2190 echo nr
2191 enddef
2192 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002193
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002194 interface Another
2195 this.member: string
2196 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002197
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 class AnotherImpl implements Some, Another
2199 this.member = 'abc'
2200 this.count = 20
2201 def Method(nr: number)
2202 echo nr
2203 enddef
2204 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002205 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002206 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002207
2208 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002209 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002210
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002211 interface Some
2212 this.count: number
2213 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002215 class SomeImpl implements Some implements Some
2216 this.count: number
2217 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002218 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002220
2221 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002222 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002223
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002224 interface Some
2225 this.count: number
2226 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002227
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002228 class SomeImpl implements Some, Some
2229 this.count: number
2230 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002231 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002232 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002233
2234 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002235 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002237 interface Some
2238 this.counter: number
2239 def Method(nr: number)
2240 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002241
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002242 class SomeImpl implements Some
2243 this.count: number
2244 def Method(nr: number)
2245 echo nr
2246 enddef
2247 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002249 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002250
2251 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002252 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002253
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002254 interface Some
2255 this.count: number
2256 def Methods(nr: number)
2257 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002258
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002259 class SomeImpl implements Some
2260 this.count: number
2261 def Method(nr: number)
2262 echo nr
2263 enddef
2264 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002265 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002267
2268 # Check different order of members in class and interface works.
2269 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002270 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002271
2272 interface Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002273 this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002274 this.errpos: number
2275 endinterface
2276
2277 # order of members is opposite of interface
2278 class Failure implements Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002279 public this.lnum: number = 5
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002280 this.errpos: number = 42
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002281 this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002282 endclass
2283
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002284 def Test()
2285 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002286
2287 assert_equal('label', result.label)
2288 assert_equal(42, result.errpos)
2289 enddef
2290
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002291 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002293 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002294
2295 # Interface name after "extends" doesn't end in a space or NUL character
2296 lines =<< trim END
2297 vim9script
2298 interface A
2299 endinterface
2300 class B extends A"
2301 endclass
2302 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002303 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002304
2305 # Trailing characters after a class name
2306 lines =<< trim END
2307 vim9script
2308 class A bbb
2309 endclass
2310 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002311 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002312
2313 # using "implements" with a non-existing class
2314 lines =<< trim END
2315 vim9script
2316 class A implements B
2317 endclass
2318 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002319 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002320
2321 # using "implements" with a regular class
2322 lines =<< trim END
2323 vim9script
2324 class A
2325 endclass
2326 class B implements A
2327 endclass
2328 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002329 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002330
2331 # using "implements" with a variable
2332 lines =<< trim END
2333 vim9script
2334 var T: number = 10
2335 class A implements T
2336 endclass
2337 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002339
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002340 # implements should be followed by a white space
2341 lines =<< trim END
2342 vim9script
2343 interface A
2344 endinterface
2345 class B implements A;
2346 endclass
2347 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002348 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002349
LemonBoyc5d27442023-08-19 13:02:35 +02002350 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002351 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002352
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002353 interface One
2354 def IsEven(nr: number): bool
2355 endinterface
2356 class Two implements One
2357 def IsEven(nr: number): string
2358 enddef
2359 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002361 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002362
2363 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002364 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002365
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002366 interface One
2367 def IsEven(nr: number): bool
2368 endinterface
2369 class Two implements One
2370 def IsEven(nr: bool): bool
2371 enddef
2372 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002373 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002374 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002375
2376 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002377 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002378
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002379 interface One
2380 def IsEven(nr: number): bool
2381 endinterface
2382 class Two implements One
2383 def IsEven(nr: number, ...extra: list<number>): bool
2384 enddef
2385 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002386 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 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 +02002388
2389 # access superclass interface members from subclass, mix variable order
2390 lines =<< trim END
2391 vim9script
2392
2393 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002394 this.mvar1: number
2395 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002396 endinterface
2397
2398 # NOTE: the order is swapped
2399 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002400 this.mvar2: number
2401 this.mvar1: number
2402 public static svar2: number
2403 public static svar1: number
2404 def new()
2405 svar1 = 11
2406 svar2 = 12
2407 this.mvar1 = 111
2408 this.mvar2 = 112
2409 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002410 endclass
2411
2412 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002413 def new()
2414 this.mvar1 = 121
2415 this.mvar2 = 122
2416 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002417 endclass
2418
2419 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002420 def new()
2421 this.mvar1 = 131
2422 this.mvar2 = 132
2423 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002424 endclass
2425
Ernie Raelcf138d42023-09-06 20:45:03 +02002426 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002427 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002428 enddef
2429
2430 var oa = A.new()
2431 var ob = B.new()
2432 var oc = C.new()
2433
Ernie Raelcf138d42023-09-06 20:45:03 +02002434 assert_equal([111, 112], F2(oa))
2435 assert_equal([121, 122], F2(ob))
2436 assert_equal([131, 132], F2(oc))
2437 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002438 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002439
2440 # Access superclass interface members from subclass, mix variable order.
2441 # Two interfaces, one on A, one on B; each has both kinds of variables
2442 lines =<< trim END
2443 vim9script
2444
2445 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002446 this.mvar1: number
2447 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002448 endinterface
2449
2450 interface I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002451 this.mvar3: number
2452 this.mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002453 endinterface
2454
2455 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002456 public static svar1: number
2457 public static svar2: number
2458 this.mvar1: number
2459 this.mvar2: number
2460 def new()
2461 svar1 = 11
2462 svar2 = 12
2463 this.mvar1 = 111
2464 this.mvar2 = 112
2465 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002466 endclass
2467
2468 class B extends A implements I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002469 static svar3: number
2470 static svar4: number
2471 this.mvar3: number
2472 this.mvar4: number
2473 def new()
2474 svar3 = 23
2475 svar4 = 24
2476 this.mvar1 = 121
2477 this.mvar2 = 122
2478 this.mvar3 = 123
2479 this.mvar4 = 124
2480 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002481 endclass
2482
2483 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002484 public static svar5: number
2485 def new()
2486 svar5 = 1001
2487 this.mvar1 = 131
2488 this.mvar2 = 132
2489 this.mvar3 = 133
2490 this.mvar4 = 134
2491 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002492 endclass
2493
Ernie Raelcf138d42023-09-06 20:45:03 +02002494 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002495 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002496 enddef
2497
Ernie Raelcf138d42023-09-06 20:45:03 +02002498 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002499 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002500 enddef
2501
Ernie Raelcf138d42023-09-06 20:45:03 +02002502 var oa = A.new()
2503 var ob = B.new()
2504 var oc = C.new()
2505
Ernie Raelcf138d42023-09-06 20:45:03 +02002506 assert_equal([[111, 112]], [F2(oa)])
2507 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2508 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002509 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002510 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002511
2512 # Using two interface names without a space after the ","
2513 lines =<< trim END
2514 vim9script
2515 interface A
2516 endinterface
2517 interface B
2518 endinterface
2519 class C implements A,B
2520 endclass
2521 END
2522 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2523
2524 # No interface name after a comma
2525 lines =<< trim END
2526 vim9script
2527 interface A
2528 endinterface
2529 class B implements A,
2530 endclass
2531 END
2532 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2533
2534 # No interface name after implements
2535 lines =<< trim END
2536 vim9script
2537 class A implements
2538 endclass
2539 END
2540 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002541enddef
2542
Bram Moolenaard0200c82023-01-28 15:19:40 +00002543def Test_call_interface_method()
2544 var lines =<< trim END
2545 vim9script
2546 interface Base
2547 def Enter(): void
2548 endinterface
2549
2550 class Child implements Base
2551 def Enter(): void
2552 g:result ..= 'child'
2553 enddef
2554 endclass
2555
2556 def F(obj: Base)
2557 obj.Enter()
2558 enddef
2559
2560 g:result = ''
2561 F(Child.new())
2562 assert_equal('child', g:result)
2563 unlet g:result
2564 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002565 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002566
2567 lines =<< trim END
2568 vim9script
2569 class Base
2570 def Enter(): void
2571 g:result ..= 'base'
2572 enddef
2573 endclass
2574
2575 class Child extends Base
2576 def Enter(): void
2577 g:result ..= 'child'
2578 enddef
2579 endclass
2580
2581 def F(obj: Base)
2582 obj.Enter()
2583 enddef
2584
2585 g:result = ''
2586 F(Child.new())
2587 assert_equal('child', g:result)
2588 unlet g:result
2589 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002590 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002591
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002592 # method of interface returns a value
2593 lines =<< trim END
2594 vim9script
2595 interface Base
2596 def Enter(): string
2597 endinterface
2598
2599 class Child implements Base
2600 def Enter(): string
2601 g:result ..= 'child'
2602 return "/resource"
2603 enddef
2604 endclass
2605
2606 def F(obj: Base)
2607 var r = obj.Enter()
2608 g:result ..= r
2609 enddef
2610
2611 g:result = ''
2612 F(Child.new())
2613 assert_equal('child/resource', g:result)
2614 unlet g:result
2615 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002616 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002617
2618 lines =<< trim END
2619 vim9script
2620 class Base
2621 def Enter(): string
2622 return null_string
2623 enddef
2624 endclass
2625
2626 class Child extends Base
2627 def Enter(): string
2628 g:result ..= 'child'
2629 return "/resource"
2630 enddef
2631 endclass
2632
2633 def F(obj: Base)
2634 var r = obj.Enter()
2635 g:result ..= r
2636 enddef
2637
2638 g:result = ''
2639 F(Child.new())
2640 assert_equal('child/resource', g:result)
2641 unlet g:result
2642 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002643 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002644
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002645 # No class that implements the interface.
2646 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002647 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002648
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002649 interface IWithEE
2650 def Enter(): any
2651 def Exit(): void
2652 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002653
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002654 def With1(ee: IWithEE, F: func)
2655 var r = ee.Enter()
2656 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002657
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002658 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002659 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002660 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002661enddef
2662
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002663def Test_class_used_as_type()
2664 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002665 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002666
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002667 class Point
2668 this.x = 0
2669 this.y = 0
2670 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002671
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002672 var p: Point
2673 p = Point.new(2, 33)
2674 assert_equal(2, p.x)
2675 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002676 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002677 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002678
2679 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002680 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002681
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002682 interface HasX
2683 this.x: number
2684 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002685
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002686 class Point implements HasX
2687 this.x = 0
2688 this.y = 0
2689 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002690
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002691 var p: Point
2692 p = Point.new(2, 33)
2693 var hx = p
2694 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002695 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002696 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002697
2698 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002699 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002700
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002701 class Point
2702 this.x = 0
2703 this.y = 0
2704 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002705
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002706 var p: Point
2707 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002708 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002709 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002710enddef
2711
Bram Moolenaar83677162023-01-08 19:54:10 +00002712def Test_class_extends()
2713 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002714 vim9script
2715 class Base
2716 this.one = 1
2717 def GetOne(): number
2718 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002719 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002720 endclass
2721 class Child extends Base
2722 this.two = 2
2723 def GetTotal(): number
2724 return this.one + this.two
2725 enddef
2726 endclass
2727 var o = Child.new()
2728 assert_equal(1, o.one)
2729 assert_equal(2, o.two)
2730 assert_equal(1, o.GetOne())
2731 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002732 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002733 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002734
2735 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002736 vim9script
2737 class Base
2738 this.one = 1
2739 endclass
2740 class Child extends Base
2741 this.two = 2
2742 endclass
2743 var o = Child.new(3, 44)
2744 assert_equal(3, o.one)
2745 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002747 v9.CheckSourceSuccess(lines)
2748
2749 lines =<< trim END
2750 vim9script
2751 class Base
2752 this.one = 1
2753 endclass
2754 class Child extends Base extends Base
2755 this.two = 2
2756 endclass
2757 END
2758 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2759
2760 lines =<< trim END
2761 vim9script
2762 class Child extends BaseClass
2763 this.two = 2
2764 endclass
2765 END
2766 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2767
2768 lines =<< trim END
2769 vim9script
2770 var SomeVar = 99
2771 class Child extends SomeVar
2772 this.two = 2
2773 endclass
2774 END
2775 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2776
2777 lines =<< trim END
2778 vim9script
2779 class Base
2780 this.name: string
2781 def ToString(): string
2782 return this.name
2783 enddef
2784 endclass
2785
2786 class Child extends Base
2787 this.age: number
2788 def ToString(): string
2789 return super.ToString() .. ': ' .. this.age
2790 enddef
2791 endclass
2792
2793 var o = Child.new('John', 42)
2794 assert_equal('John: 42', o.ToString())
2795 END
2796 v9.CheckSourceSuccess(lines)
2797
2798 lines =<< trim END
2799 vim9script
2800 class Child
2801 this.age: number
2802 def ToString(): number
2803 return this.age
2804 enddef
2805 def ToString(): string
2806 return this.age
2807 enddef
2808 endclass
2809 END
2810 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2811
2812 lines =<< trim END
2813 vim9script
2814 class Child
2815 this.age: number
2816 def ToString(): string
2817 return super .ToString() .. ': ' .. this.age
2818 enddef
2819 endclass
2820 var o = Child.new(42)
2821 echo o.ToString()
2822 END
2823 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2824
2825 lines =<< trim END
2826 vim9script
2827 class Base
2828 this.name: string
2829 def ToString(): string
2830 return this.name
2831 enddef
2832 endclass
2833
2834 var age = 42
2835 def ToString(): string
2836 return super.ToString() .. ': ' .. age
2837 enddef
2838 echo ToString()
2839 END
2840 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2841
2842 lines =<< trim END
2843 vim9script
2844 class Child
2845 this.age: number
2846 def ToString(): string
2847 return super.ToString() .. ': ' .. this.age
2848 enddef
2849 endclass
2850 var o = Child.new(42)
2851 echo o.ToString()
2852 END
2853 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2854
2855 lines =<< trim END
2856 vim9script
2857 class Base
2858 this.name: string
2859 static def ToString(): string
2860 return 'Base class'
2861 enddef
2862 endclass
2863
2864 class Child extends Base
2865 this.age: number
2866 def ToString(): string
2867 return Base.ToString() .. ': ' .. this.age
2868 enddef
2869 endclass
2870
2871 var o = Child.new('John', 42)
2872 assert_equal('Base class: 42', o.ToString())
2873 END
2874 v9.CheckSourceSuccess(lines)
2875
2876 lines =<< trim END
2877 vim9script
2878 class Base
2879 this.value = 1
2880 def new(init: number)
2881 this.value = number + 1
2882 enddef
2883 endclass
2884 class Child extends Base
2885 def new()
2886 this.new(3)
2887 enddef
2888 endclass
2889 var c = Child.new()
2890 END
2891 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002892
2893 # base class with more than one object member
2894 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002895 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002896
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002897 class Result
2898 this.success: bool
2899 this.value: any = null
2900 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002901
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002902 class Success extends Result
2903 def new(this.value = v:none)
2904 this.success = true
2905 enddef
2906 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002907
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002908 var v = Success.new('asdf')
2909 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002910 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002911 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002912
2913 # class name after "extends" doesn't end in a space or NUL character
2914 lines =<< trim END
2915 vim9script
2916 class A
2917 endclass
2918 class B extends A"
2919 endclass
2920 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002921 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00002922enddef
2923
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002924def Test_using_base_class()
2925 var lines =<< trim END
2926 vim9script
2927
2928 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 def Enter(): any
2930 return null
2931 enddef
2932 def Exit(resource: any): void
2933 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002934 endclass
2935
2936 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002937 def Enter(): any
2938 return 42
2939 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002940
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 def Exit(resource: number): void
2942 g:result ..= '/exit'
2943 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002944 endclass
2945
2946 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002947 var r = ee.Enter()
2948 try
2949 g:result ..= r
2950 finally
2951 g:result ..= '/finally'
2952 ee.Exit(r)
2953 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002954 enddef
2955
2956 g:result = ''
2957 With(ChildEE.new())
2958 assert_equal('42/finally/exit', g:result)
2959 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002960 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002961 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002962
2963 # Using super, Child invokes Base method which has optional arg. #12471
2964 lines =<< trim END
2965 vim9script
2966
2967 class Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 this.success: bool = false
2969 def Method(arg = 0)
2970 this.success = true
2971 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002972 endclass
2973
2974 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002975 def new()
2976 super.Method()
2977 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002978 endclass
2979
2980 var obj = Child.new()
2981 assert_equal(true, obj.success)
2982 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002983 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002984enddef
2985
Bram Moolenaara86655a2023-01-12 17:06:27 +00002986def Test_class_import()
2987 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002988 vim9script
2989 export class Animal
2990 this.kind: string
2991 this.name: string
2992 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00002993 END
2994 writefile(lines, 'Xanimal.vim', 'D')
2995
2996 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002997 vim9script
2998 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00002999
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003000 var a: animal.Animal
3001 a = animal.Animal.new('fish', 'Eric')
3002 assert_equal('fish', a.kind)
3003 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003004
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003005 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3006 assert_equal('cat', b.kind)
3007 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003008 END
3009 v9.CheckScriptSuccess(lines)
3010enddef
3011
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003012def Test_abstract_class()
3013 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003014 vim9script
3015 abstract class Base
3016 this.name: string
3017 endclass
3018 class Person extends Base
3019 this.age: number
3020 endclass
3021 var p: Base = Person.new('Peter', 42)
3022 assert_equal('Peter', p.name)
3023 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003024 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003025 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003026
3027 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003028 vim9script
3029 abstract class Base
3030 this.name: string
3031 endclass
3032 class Person extends Base
3033 this.age: number
3034 endclass
3035 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003036 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003037 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003038
3039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003040 abstract class Base
3041 this.name: string
3042 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003044 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003045
3046 # Abstract class cannot have a "new" function
3047 lines =<< trim END
3048 vim9script
3049 abstract class Base
3050 def new()
3051 enddef
3052 endclass
3053 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003054 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003055enddef
3056
Bram Moolenaar486fc252023-01-18 14:51:07 +00003057def Test_closure_in_class()
3058 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003059 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003060
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003061 class Foo
3062 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003063
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003064 def new()
3065 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3066 enddef
3067 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003068
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003069 Foo.new()
3070 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003071 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003072 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003073enddef
3074
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003075def Test_call_constructor_from_legacy()
3076 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003077 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003078
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003079 var newCalled = 'false'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003080
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003081 class A
3082 def new()
3083 newCalled = 'true'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003084 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003086
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003087 export def F(options = {}): any
3088 return A
3089 enddef
3090
3091 g:p = F()
3092 legacy call p.new()
3093 assert_equal('true', newCalled)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003094 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003095 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003096enddef
3097
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003098def Test_defer_with_object()
3099 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003100 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003101
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003102 class CWithEE
3103 def Enter()
3104 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003105 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003106 def Exit()
3107 g:result ..= "exited"
3108 enddef
3109 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003111 def With(ee: CWithEE, F: func)
3112 ee.Enter()
3113 defer ee.Exit()
3114 F()
3115 enddef
3116
3117 g:result = ''
3118 var obj = CWithEE.new()
3119 obj->With(() => {
3120 g:result ..= "called/"
3121 })
3122 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003123 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003124 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003125 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003126
3127 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003128 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003129
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003130 class BaseWithEE
3131 def Enter()
3132 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003133 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003134 def Exit()
3135 g:result ..= "exited-base"
3136 enddef
3137 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003138
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003139 class CWithEE extends BaseWithEE
3140 def Enter()
3141 g:result ..= "entered-child/"
3142 enddef
3143 def Exit()
3144 g:result ..= "exited-child"
3145 enddef
3146 endclass
3147
3148 def With(ee: BaseWithEE, F: func)
3149 ee.Enter()
3150 defer ee.Exit()
3151 F()
3152 enddef
3153
3154 g:result = ''
3155 var obj = CWithEE.new()
3156 obj->With(() => {
3157 g:result ..= "called/"
3158 })
3159 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003161 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003162 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003163enddef
3164
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003165" The following test used to crash Vim (Github issue #12676)
3166def Test_extends_method_crashes_vim()
3167 var lines =<< trim END
3168 vim9script
3169
3170 class Observer
3171 endclass
3172
3173 class Property
3174 this.value: any
3175
3176 def Set(v: any)
3177 if v != this.value
3178 this.value = v
3179 endif
3180 enddef
3181
3182 def Register(observer: Observer)
3183 enddef
3184 endclass
3185
3186 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003187 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003188 endclass
3189
3190 def Observe(obj: Property, who: Observer)
3191 obj.Register(who)
3192 enddef
3193
3194 var p = Bool.new(false)
3195 var myObserver = Observer.new()
3196
3197 Observe(p, myObserver)
3198
3199 p.Set(true)
3200 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003201 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003202enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003203
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003204" Test for calling a method in a class that is extended
3205def Test_call_method_in_extended_class()
3206 var lines =<< trim END
3207 vim9script
3208
3209 var prop_init_called = false
3210 var prop_register_called = false
3211
3212 class Property
3213 def Init()
3214 prop_init_called = true
3215 enddef
3216
3217 def Register()
3218 prop_register_called = true
3219 enddef
3220 endclass
3221
3222 class Bool extends Property
3223 endclass
3224
3225 def Observe(obj: Property)
3226 obj.Register()
3227 enddef
3228
3229 var p = Property.new()
3230 Observe(p)
3231
3232 p.Init()
3233 assert_true(prop_init_called)
3234 assert_true(prop_register_called)
3235 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003236 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003237enddef
3238
LemonBoyafe04662023-08-23 21:08:11 +02003239def Test_instanceof()
3240 var lines =<< trim END
3241 vim9script
3242
3243 class Base1
3244 endclass
3245
3246 class Base2 extends Base1
3247 endclass
3248
3249 interface Intf1
3250 endinterface
3251
3252 class Mix1 implements Intf1
3253 endclass
3254
3255 class Base3 extends Mix1
3256 endclass
3257
3258 var b1 = Base1.new()
3259 var b2 = Base2.new()
3260 var b3 = Base3.new()
3261
3262 assert_true(instanceof(b1, Base1))
3263 assert_true(instanceof(b2, Base1))
3264 assert_false(instanceof(b1, Base2))
3265 assert_true(instanceof(b3, Mix1))
3266 assert_false(instanceof(b3, []))
3267 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003268
3269 def Foo()
3270 var a1 = Base1.new()
3271 var a2 = Base2.new()
3272 var a3 = Base3.new()
3273
3274 assert_true(instanceof(a1, Base1))
3275 assert_true(instanceof(a2, Base1))
3276 assert_false(instanceof(a1, Base2))
3277 assert_true(instanceof(a3, Mix1))
3278 assert_false(instanceof(a3, []))
3279 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3280 enddef
3281 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003282
3283 var o_null: Base1
3284 assert_false(instanceof(o_null, Base1))
3285
LemonBoyafe04662023-08-23 21:08:11 +02003286 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003287 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003288enddef
3289
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003290" Test for calling a method in the parent class that is extended partially.
3291" This used to fail with the 'E118: Too many arguments for function: Text' error
3292" message (Github issue #12524).
3293def Test_call_method_in_parent_class()
3294 var lines =<< trim END
3295 vim9script
3296
3297 class Widget
3298 this._lnum: number = 1
3299
3300 def SetY(lnum: number)
3301 this._lnum = lnum
3302 enddef
3303
3304 def Text(): string
3305 return ''
3306 enddef
3307 endclass
3308
3309 class Foo extends Widget
3310 def Text(): string
3311 return '<Foo>'
3312 enddef
3313 endclass
3314
3315 def Stack(w1: Widget, w2: Widget): list<Widget>
3316 w1.SetY(1)
3317 w2.SetY(2)
3318 return [w1, w2]
3319 enddef
3320
3321 var foo1 = Foo.new()
3322 var foo2 = Foo.new()
3323 var l = Stack(foo1, foo2)
3324 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003325 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003326enddef
3327
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003328" Test for calling methods from three levels of classes
3329def Test_multi_level_method_call()
3330 var lines =<< trim END
3331 vim9script
3332
3333 var A_func1: number = 0
3334 var A_func2: number = 0
3335 var A_func3: number = 0
3336 var B_func2: number = 0
3337 var B_func3: number = 0
3338 var C_func3: number = 0
3339
3340 class A
3341 def Func1()
3342 A_func1 += 1
3343 enddef
3344
3345 def Func2()
3346 A_func2 += 1
3347 enddef
3348
3349 def Func3()
3350 A_func3 += 1
3351 enddef
3352 endclass
3353
3354 class B extends A
3355 def Func2()
3356 B_func2 += 1
3357 enddef
3358
3359 def Func3()
3360 B_func3 += 1
3361 enddef
3362 endclass
3363
3364 class C extends B
3365 def Func3()
3366 C_func3 += 1
3367 enddef
3368 endclass
3369
3370 def A_CallFuncs(a: A)
3371 a.Func1()
3372 a.Func2()
3373 a.Func3()
3374 enddef
3375
3376 def B_CallFuncs(b: B)
3377 b.Func1()
3378 b.Func2()
3379 b.Func3()
3380 enddef
3381
3382 def C_CallFuncs(c: C)
3383 c.Func1()
3384 c.Func2()
3385 c.Func3()
3386 enddef
3387
3388 var cobj = C.new()
3389 A_CallFuncs(cobj)
3390 B_CallFuncs(cobj)
3391 C_CallFuncs(cobj)
3392 assert_equal(3, A_func1)
3393 assert_equal(0, A_func2)
3394 assert_equal(0, A_func3)
3395 assert_equal(3, B_func2)
3396 assert_equal(0, B_func3)
3397 assert_equal(3, C_func3)
3398 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003399 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003400enddef
3401
3402" Test for using members from three levels of classes
3403def Test_multi_level_member_access()
3404 var lines =<< trim END
3405 vim9script
3406
3407 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003408 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003409 endclass
3410
3411 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003412 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003413 endclass
3414
3415 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003416 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003417 endclass
3418
3419 def A_members(a: A)
3420 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003421 enddef
3422
3423 def B_members(b: B)
3424 b.val1 += 1
3425 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003426 enddef
3427
3428 def C_members(c: C)
3429 c.val1 += 1
3430 c.val2 += 1
3431 c.val3 += 1
3432 enddef
3433
3434 var cobj = C.new()
3435 A_members(cobj)
3436 B_members(cobj)
3437 C_members(cobj)
3438 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003439 assert_equal(2, cobj.val2)
3440 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003441 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003442 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003443enddef
3444
LemonBoy0ffc17a2023-08-20 18:09:11 +02003445" Test expansion of <stack> with class methods.
3446def Test_stack_expansion_with_methods()
3447 var lines =<< trim END
3448 vim9script
3449
3450 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003451 def M1()
3452 F0()
3453 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003454 endclass
3455
3456 def F0()
3457 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3458 enddef
3459
3460 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003461 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003462 enddef
3463
3464 F()
3465 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003466 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003467enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003468
3469" Test the return type of the new() constructor
3470def Test_new_return_type()
3471 # new() uses the default return type and there is no return statement
3472 var lines =<< trim END
3473 vim9script
3474
3475 class C
3476 this._bufnr: number
3477
3478 def new(this._bufnr)
3479 if !bufexists(this._bufnr)
3480 this._bufnr = -1
3481 endif
3482 enddef
3483 endclass
3484
3485 var c = C.new(12345)
3486 assert_equal('object<C>', typename(c))
3487
3488 var v1: C
3489 v1 = C.new(12345)
3490 assert_equal('object<C>', typename(v1))
3491
3492 def F()
3493 var v2: C
3494 v2 = C.new(12345)
3495 assert_equal('object<C>', typename(v2))
3496 enddef
3497 F()
3498 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003499 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003500
3501 # new() uses the default return type and an empty 'return' statement
3502 lines =<< trim END
3503 vim9script
3504
3505 class C
3506 this._bufnr: number
3507
3508 def new(this._bufnr)
3509 if !bufexists(this._bufnr)
3510 this._bufnr = -1
3511 return
3512 endif
3513 enddef
3514 endclass
3515
3516 var c = C.new(12345)
3517 assert_equal('object<C>', typename(c))
3518
3519 var v1: C
3520 v1 = C.new(12345)
3521 assert_equal('object<C>', typename(v1))
3522
3523 def F()
3524 var v2: C
3525 v2 = C.new(12345)
3526 assert_equal('object<C>', typename(v2))
3527 enddef
3528 F()
3529 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003530 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003531
3532 # new() uses "any" return type and returns "this"
3533 lines =<< trim END
3534 vim9script
3535
3536 class C
3537 this._bufnr: number
3538
3539 def new(this._bufnr): any
3540 if !bufexists(this._bufnr)
3541 this._bufnr = -1
3542 return this
3543 endif
3544 enddef
3545 endclass
3546 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003547 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003548
3549 # new() uses 'Dict' return type and returns a Dict
3550 lines =<< trim END
3551 vim9script
3552
3553 class C
3554 this._state: dict<any>
3555
3556 def new(): dict<any>
3557 this._state = {}
3558 return this._state
3559 enddef
3560 endclass
3561
3562 var c = C.new()
3563 assert_equal('object<C>', typename(c))
3564 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003565 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003566enddef
3567
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003568" Test for checking a member initialization type at run time.
3569def Test_runtime_type_check_for_member_init()
3570 var lines =<< trim END
3571 vim9script
3572
3573 var retnum: bool = false
3574
3575 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003576 retnum = !retnum
3577 if retnum
3578 return 1
3579 else
3580 return "hello"
3581 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003582 enddef
3583
3584 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003585 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003586 endclass
3587
3588 var c1 = C.new()
3589 var c2 = C.new()
3590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003591 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003592enddef
3593
3594" Test for locking a variable referring to an object and reassigning to another
3595" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003596def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003597 var lines =<< trim END
3598 vim9script
3599
3600 class C
3601 this.val: number
3602 def new(this.val)
3603 enddef
3604 endclass
3605
3606 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3607 lockvar 2 some_dict
3608
3609 var current: C
3610 current = some_dict['c']
3611 assert_equal(3, current.val)
3612 current = some_dict['b']
3613 assert_equal(2, current.val)
3614
3615 def F()
3616 current = some_dict['c']
3617 enddef
3618
3619 def G()
3620 current = some_dict['b']
3621 enddef
3622
3623 F()
3624 assert_equal(3, current.val)
3625 G()
3626 assert_equal(2, current.val)
3627 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003628 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003629enddef
3630
Ernie Raelee865f32023-09-29 19:53:55 +02003631" Test trying to lock an object variable from various places
3632def Test_lockvar_object_variable()
3633 # An object variable lockvar has several cases:
3634 # object method, scriptlevel, scriplevel from :def, :def arg
3635 # method arg, static method arg.
3636 # Also different depths
3637
Ernie Raelee865f32023-09-29 19:53:55 +02003638 #
3639 # lockvar of read-only object variable
3640 #
3641
3642 # read-only lockvar from object method
3643 var lines =<< trim END
3644 vim9script
3645
3646 class C
3647 this.val1: number
3648 def Lock()
3649 lockvar this.val1
3650 enddef
3651 endclass
3652 var o = C.new(3)
3653 o.Lock()
3654 END
Ernie Rael64885642023-10-04 20:16:22 +02003655 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003656
3657 # read-only lockvar from scriptlevel
3658 lines =<< trim END
3659 vim9script
3660
3661 class C
3662 this.val2: number
3663 endclass
3664 var o = C.new(3)
3665 lockvar o.val2
3666 END
3667 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3668
3669 # read-only lockvar of scriptlevel variable from def
3670 lines =<< trim END
3671 vim9script
3672
3673 class C
3674 this.val3: number
3675 endclass
3676 var o = C.new(3)
3677 def Lock()
3678 lockvar o.val3
3679 enddef
3680 Lock()
3681 END
3682 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3683
3684 # read-only lockvar of def argument variable
3685 lines =<< trim END
3686 vim9script
3687
3688 class C
3689 this.val4: number
3690 endclass
3691 def Lock(o: C)
3692 lockvar o.val4
3693 enddef
3694 Lock(C.new(3))
3695 END
3696 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3697
3698 # TODO: the following tests use type "any" for argument. Need a run time
3699 # check for access. Probably OK as is for now.
3700
3701 # read-only lockvar from object method arg
3702 lines =<< trim END
3703 vim9script
3704
3705 class C
3706 this.val5: number
3707 def Lock(o_any: any)
3708 lockvar o_any.val5
3709 enddef
3710 endclass
3711 var o = C.new(3)
3712 o.Lock(C.new(5))
3713 END
Ernie Rael64885642023-10-04 20:16:22 +02003714 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003715
3716 # read-only lockvar from class method arg
3717 lines =<< trim END
3718 vim9script
3719
3720 class C
3721 this.val6: number
3722 static def Lock(o_any: any)
3723 lockvar o_any.val6
3724 enddef
3725 endclass
3726 var o = C.new(3)
3727 C.Lock(o)
3728 END
Ernie Rael64885642023-10-04 20:16:22 +02003729 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003730
3731 #
3732 # lockvar of public object variable
3733 #
3734
3735 # lockvar from object method
3736 lines =<< trim END
3737 vim9script
3738
3739 class C
3740 public this.val1: number
3741 def Lock()
3742 lockvar this.val1
3743 enddef
3744 endclass
3745 var o = C.new(3)
3746 o.Lock()
3747 END
3748 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3749
3750 # lockvar from scriptlevel
3751 lines =<< trim END
3752 vim9script
3753
3754 class C
3755 public this.val2: number
3756 endclass
3757 var o = C.new(3)
3758 lockvar o.val2
3759 END
3760 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3761
3762 # lockvar of scriptlevel variable from def
3763 lines =<< trim END
3764 vim9script
3765
3766 class C
3767 public this.val3: number
3768 endclass
3769 var o = C.new(3)
3770 def Lock()
3771 lockvar o.val3
3772 enddef
3773 Lock()
3774 END
3775 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3776
3777 # lockvar of def argument variable
3778 lines =<< trim END
3779 vim9script
3780
3781 class C
3782 public this.val4: number
3783 endclass
3784 def Lock(o: C)
3785 lockvar o.val4
3786 enddef
3787 Lock(C.new(3))
3788 END
3789 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3790
3791 # lockvar from object method arg
3792 lines =<< trim END
3793 vim9script
3794
3795 class C
3796 public this.val5: number
3797 def Lock(o_any: any)
3798 lockvar o_any.val5
3799 enddef
3800 endclass
3801 var o = C.new(3)
3802 o.Lock(C.new(5))
3803 END
3804 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3805
3806 # lockvar from class method arg
3807 lines =<< trim END
3808 vim9script
3809
3810 class C
3811 public this.val6: number
3812 static def Lock(o_any: any)
3813 lockvar o_any.val6
3814 enddef
3815 endclass
3816 var o = C.new(3)
3817 C.Lock(o)
3818 END
3819 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3820enddef
3821
3822" Test trying to lock a class variable from various places
3823def Test_lockvar_class_variable()
3824
3825 # lockvar bare static from object method
3826 var lines =<< trim END
3827 vim9script
3828
3829 class C
3830 public static sval1: number
3831 def Lock()
3832 lockvar sval1
3833 enddef
3834 endclass
3835 var o = C.new()
3836 o.Lock()
3837 END
3838 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3839
3840 # lockvar C.static from object method
3841 lines =<< trim END
3842 vim9script
3843
3844 class C
3845 public static sval2: number
3846 def Lock()
3847 lockvar C.sval2
3848 enddef
3849 endclass
3850 var o = C.new()
3851 o.Lock()
3852 END
3853 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3854
3855 # lockvar bare static from class method
3856 lines =<< trim END
3857 vim9script
3858
3859 class C
3860 public static sval3: number
3861 static def Lock()
3862 lockvar sval3
3863 enddef
3864 endclass
3865 C.Lock()
3866 END
3867 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
3868
3869 # lockvar C.static from class method
3870 lines =<< trim END
3871 vim9script
3872
3873 class C
3874 public static sval4: number
3875 static def Lock()
3876 lockvar C.sval4
3877 enddef
3878 endclass
3879 C.Lock()
3880 END
3881 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
3882
3883 # lockvar C.static from script level
3884 lines =<< trim END
3885 vim9script
3886
3887 class C
3888 public static sval5: number
3889 endclass
3890 lockvar C.sval5
3891 END
3892 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
3893
3894 # lockvar o.static from script level
3895 lines =<< trim END
3896 vim9script
3897
3898 class C
3899 public static sval6: number
3900 endclass
3901 var o = C.new()
3902 lockvar o.sval6
3903 END
3904 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
3905enddef
3906
3907" Test locking an argument to :def
3908def Test_lockvar_argument()
3909 # Lockvar a function arg
3910 var lines =<< trim END
3911 vim9script
3912
3913 def Lock(val: any)
3914 lockvar val
3915 enddef
3916
3917 var d = {a: 1, b: 2}
3918 Lock(d)
3919
3920 d->extend({c: 3})
3921 END
3922 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
3923
3924 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
3925 # class member in "C". This tests lval_root_is_arg.
3926 lines =<< trim END
3927 vim9script
3928
3929 class C
3930 public static sval: list<number>
3931 endclass
3932
3933 def Lock2(sval: any)
3934 lockvar sval
3935 enddef
3936
3937 var o = C.new()
3938 Lock2(o)
3939 END
3940 v9.CheckSourceSuccess(lines)
3941
3942 # Lock a class.
3943 lines =<< trim END
3944 vim9script
3945
3946 class C
3947 public static sval: list<number>
3948 endclass
3949
3950 def Lock2(sval: any)
3951 lockvar sval
3952 enddef
3953
3954 Lock2(C)
3955 END
3956 v9.CheckSourceSuccess(lines)
3957
3958 # Lock an object.
3959 lines =<< trim END
3960 vim9script
3961
3962 class C
3963 public static sval: list<number>
3964 endclass
3965
3966 def Lock2(sval: any)
3967 lockvar sval
3968 enddef
3969
3970 Lock2(C.new())
3971 END
3972 v9.CheckSourceSuccess(lines)
3973
3974 # In this case (unlike previous) "lockvar sval" is a class member.
3975 lines =<< trim END
3976 vim9script
3977
3978 class C
3979 public static sval: list<number>
3980 def Lock2()
3981 lockvar sval
3982 enddef
3983 endclass
3984
3985
3986 var o = C.new()
3987 o.Lock2()
3988 END
3989 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
3990enddef
3991
3992" Test that this can be locked without error
3993def Test_lockvar_this()
3994 # lockvar this
3995 var lines =<< trim END
3996 vim9script
3997 class C
3998 def TLock()
3999 lockvar this
4000 enddef
4001 endclass
4002 var o = C.new()
4003 o.TLock()
4004 END
4005 v9.CheckSourceSuccess(lines)
4006
4007 # lockvar four (four letter word, but not this)
4008 lines =<< trim END
4009 vim9script
4010 class C
4011 def TLock4()
4012 var four: number
4013 lockvar four
4014 enddef
4015 endclass
4016 var o = C.new()
4017 o.TLock4()
4018 END
4019 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4020
4021 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4022 lines =<< trim END
4023 vim9script
4024 class C
4025 def TLock5()
4026 var this5: number
4027 lockvar this5
4028 enddef
4029 endclass
4030 var o = C.new()
4031 o.TLock5()
4032 END
4033 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4034enddef
4035
4036" Test some general lockvar cases
4037def Test_lockvar_general()
4038 # lockvar an object and a class. It does nothing
4039 var lines =<< trim END
4040 vim9script
4041 class C
4042 endclass
4043 var o = C.new()
4044 lockvar o
4045 lockvar C
4046 END
4047 v9.CheckSourceSuccess(lines)
4048
4049 # Lock a list element that's nested in an object variable from a :def
4050 lines =<< trim END
4051 vim9script
4052
4053 class C
4054 public this.val: list<list<number>> = [ [1], [2], [3] ]
4055 endclass
4056 def Lock2(obj: any)
4057 lockvar obj.val[1]
4058 enddef
4059
4060 var o = C.new()
4061 Lock2(o)
4062 o.val[0] = [9]
4063 assert_equal([ [9], [2], [3] ], o.val)
4064 try
4065 o.val[1] = [999]
4066 call assert_false(true, 'assign should have failed')
4067 catch
4068 assert_exception('E741:')
4069 endtry
4070 o.val[2] = [8]
4071 assert_equal([ [9], [2], [8] ], o.val)
4072 END
4073 v9.CheckSourceSuccess(lines)
4074
4075 # Lock a list element that's nested in an object variable from scriptlevel
4076 lines =<< trim END
4077 vim9script
4078
4079 class C
4080 public this.val: list<list<number>> = [ [1], [2], [3] ]
4081 endclass
4082
4083 var o = C.new()
4084 lockvar o.val[1]
4085 o.val[0] = [9]
4086 assert_equal([ [9], [2], [3] ], o.val)
4087 try
4088 o.val[1] = [999]
4089 call assert_false(true, 'assign should have failed')
4090 catch
4091 assert_exception('E741:')
4092 endtry
4093 o.val[2] = [8]
4094 assert_equal([ [9], [2], [8] ], o.val)
4095 END
4096 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004097
4098 # lock a script level variable from an object method
4099 lines =<< trim END
4100 vim9script
4101
4102 class C
4103 def Lock()
4104 lockvar l
4105 enddef
4106 endclass
4107
4108 var l = [1]
4109 C.new().Lock()
4110 l[0] = 11
4111 END
4112 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4113
4114 # lock a list element referenced by a private object variable
4115 # in an object fetched via a script level list
4116 lines =<< trim END
4117 vim9script
4118
4119 class C
4120 this._v1: list<list<number>>
4121 def Lock()
4122 lockvar lc[0]._v1[1]
4123 enddef
4124 endclass
4125
4126 var l = [[1], [2], [3]]
4127 var o = C.new(l)
4128 var lc: list<C> = [ o ]
4129
4130 o.Lock()
4131 l[0] = [22]
4132 l[1] = [33]
4133 END
4134 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4135
4136 # similar to the previous test, except the locking code is executing
4137 # in a class that does not own the private variable.
4138 # Note that the locking code is in a class has a private variable of
4139 # the same name.
4140 lines =<< trim END
4141 vim9script
4142
4143 class C2
4144 this._v1: list<list<number>>
4145 def Lock(obj: any)
4146 lockvar lc[0]._v1[1]
4147 enddef
4148 endclass
4149
4150 class C
4151 this._v1: list<list<number>>
4152 endclass
4153
4154 var l = [[1], [2], [3]]
4155 var o = C.new(l)
4156 var lc: list<C> = [ o ]
4157
4158 var o2 = C2.new()
4159 o2.Lock(o)
4160 END
4161 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004162enddef
4163
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004164" Test for a private object method
4165def Test_private_object_method()
4166 # Try calling a private method using an object (at the script level)
4167 var lines =<< trim END
4168 vim9script
4169
4170 class A
4171 def _Foo(): number
4172 return 1234
4173 enddef
4174 endclass
4175 var a = A.new()
4176 a._Foo()
4177 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004178 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004179
4180 # Try calling a private method using an object (from a def function)
4181 lines =<< trim END
4182 vim9script
4183
4184 class A
4185 def _Foo(): number
4186 return 1234
4187 enddef
4188 endclass
4189 def T()
4190 var a = A.new()
4191 a._Foo()
4192 enddef
4193 T()
4194 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004195 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004196
4197 # Use a private method from another object method (in script context)
4198 lines =<< trim END
4199 vim9script
4200
4201 class A
4202 def _Foo(): number
4203 return 1234
4204 enddef
4205 def Bar(): number
4206 return this._Foo()
4207 enddef
4208 endclass
4209 var a = A.new()
4210 assert_equal(1234, a.Bar())
4211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004212 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004213
4214 # Use a private method from another object method (def function context)
4215 lines =<< trim END
4216 vim9script
4217
4218 class A
4219 def _Foo(): number
4220 return 1234
4221 enddef
4222 def Bar(): number
4223 return this._Foo()
4224 enddef
4225 endclass
4226 def T()
4227 var a = A.new()
4228 assert_equal(1234, a.Bar())
4229 enddef
4230 T()
4231 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004232 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004233
4234 # Try calling a private method without the "this" prefix
4235 lines =<< trim END
4236 vim9script
4237
4238 class A
4239 def _Foo(): number
4240 return 1234
4241 enddef
4242 def Bar(): number
4243 return _Foo()
4244 enddef
4245 endclass
4246 var a = A.new()
4247 a.Bar()
4248 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004249 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004250
4251 # Try calling a private method using the class name
4252 lines =<< trim END
4253 vim9script
4254
4255 class A
4256 def _Foo(): number
4257 return 1234
4258 enddef
4259 endclass
4260 A._Foo()
4261 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004262 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004263
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004264 # Define two private methods with the same name
4265 lines =<< trim END
4266 vim9script
4267
4268 class A
4269 def _Foo()
4270 enddef
4271 def _Foo()
4272 enddef
4273 endclass
4274 var a = A.new()
4275 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004276 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004277
4278 # Define a private method and a object method with the same name
4279 lines =<< trim END
4280 vim9script
4281
4282 class A
4283 def _Foo()
4284 enddef
4285 def Foo()
4286 enddef
4287 endclass
4288 var a = A.new()
4289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004290 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004291
4292 # Define an object method and a private method with the same name
4293 lines =<< trim END
4294 vim9script
4295
4296 class A
4297 def Foo()
4298 enddef
4299 def _Foo()
4300 enddef
4301 endclass
4302 var a = A.new()
4303 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004304 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004305
4306 # Call a public method and a private method from a private method
4307 lines =<< trim END
4308 vim9script
4309
4310 class A
4311 def Foo(): number
4312 return 100
4313 enddef
4314 def _Bar(): number
4315 return 200
4316 enddef
4317 def _Baz()
4318 assert_equal(100, this.Foo())
4319 assert_equal(200, this._Bar())
4320 enddef
4321 def T()
4322 this._Baz()
4323 enddef
4324 endclass
4325 var a = A.new()
4326 a.T()
4327 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004328 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004329
4330 # Try calling a private method from another class
4331 lines =<< trim END
4332 vim9script
4333
4334 class A
4335 def _Foo(): number
4336 return 100
4337 enddef
4338 endclass
4339 class B
4340 def Foo(): number
4341 var a = A.new()
4342 a._Foo()
4343 enddef
4344 endclass
4345 var b = B.new()
4346 b.Foo()
4347 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004348 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004349
4350 # Call a private object method from a child class object method
4351 lines =<< trim END
4352 vim9script
4353 class A
4354 def _Foo(): number
4355 return 1234
4356 enddef
4357 endclass
4358 class B extends A
4359 def Bar()
4360 enddef
4361 endclass
4362 class C extends B
4363 def Baz(): number
4364 return this._Foo()
4365 enddef
4366 endclass
4367 var c = C.new()
4368 assert_equal(1234, c.Baz())
4369 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004370 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004371
4372 # Call a private object method from a child class object
4373 lines =<< trim END
4374 vim9script
4375 class A
4376 def _Foo(): number
4377 return 1234
4378 enddef
4379 endclass
4380 class B extends A
4381 def Bar()
4382 enddef
4383 endclass
4384 class C extends B
4385 def Baz(): number
4386 enddef
4387 endclass
4388 var c = C.new()
4389 assert_equal(1234, c._Foo())
4390 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004391 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004392
4393 # Using "_" prefix in a method name should fail outside of a class
4394 lines =<< trim END
4395 vim9script
4396 def _Foo(): number
4397 return 1234
4398 enddef
4399 var a = _Foo()
4400 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004401 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004402enddef
4403
4404" Test for an private class method
4405def Test_private_class_method()
4406 # Try calling a class private method (at the script level)
4407 var lines =<< trim END
4408 vim9script
4409
4410 class A
4411 static def _Foo(): number
4412 return 1234
4413 enddef
4414 endclass
4415 A._Foo()
4416 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004417 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004418
4419 # Try calling a class private method (from a def function)
4420 lines =<< trim END
4421 vim9script
4422
4423 class A
4424 static def _Foo(): number
4425 return 1234
4426 enddef
4427 endclass
4428 def T()
4429 A._Foo()
4430 enddef
4431 T()
4432 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004433 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004434
4435 # Try calling a class private method using an object (at the script level)
4436 lines =<< trim END
4437 vim9script
4438
4439 class A
4440 static def _Foo(): number
4441 return 1234
4442 enddef
4443 endclass
4444 var a = A.new()
4445 a._Foo()
4446 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004447 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004448
4449 # Try calling a class private method using an object (from a def function)
4450 lines =<< trim END
4451 vim9script
4452
4453 class A
4454 static def _Foo(): number
4455 return 1234
4456 enddef
4457 endclass
4458 def T()
4459 var a = A.new()
4460 a._Foo()
4461 enddef
4462 T()
4463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004464 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004465
4466 # Use a class private method from an object method
4467 lines =<< trim END
4468 vim9script
4469
4470 class A
4471 static def _Foo(): number
4472 return 1234
4473 enddef
4474 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004475 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004476 enddef
4477 endclass
4478 var a = A.new()
4479 a.Bar()
4480 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004481 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004482
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004483 # Use a class private method from another class private method without the
4484 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004485 lines =<< trim END
4486 vim9script
4487
4488 class A
4489 static def _Foo1(): number
4490 return 1234
4491 enddef
4492 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004493 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004494 enddef
4495 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004496 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004497 enddef
4498 endclass
4499 var a = A.new()
4500 a.Bar()
4501 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004502 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004503
4504 # Declare a class method and a class private method with the same name
4505 lines =<< trim END
4506 vim9script
4507
4508 class A
4509 static def _Foo()
4510 enddef
4511 static def Foo()
4512 enddef
4513 endclass
4514 var a = A.new()
4515 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004516 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004517
4518 # Try calling a class private method from another class
4519 lines =<< trim END
4520 vim9script
4521
4522 class A
4523 static def _Foo(): number
4524 return 1234
4525 enddef
4526 endclass
4527 class B
4528 def Foo(): number
4529 return A._Foo()
4530 enddef
4531 endclass
4532 var b = B.new()
4533 assert_equal(1234, b.Foo())
4534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004535 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004536
4537 # Call a private class method from a child class object method
4538 lines =<< trim END
4539 vim9script
4540 class A
4541 static def _Foo(): number
4542 return 1234
4543 enddef
4544 endclass
4545 class B extends A
4546 def Bar()
4547 enddef
4548 endclass
4549 class C extends B
4550 def Baz(): number
4551 return A._Foo()
4552 enddef
4553 endclass
4554 var c = C.new()
4555 assert_equal(1234, c.Baz())
4556 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004557 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004558
4559 # Call a private class method from a child class private class method
4560 lines =<< trim END
4561 vim9script
4562 class A
4563 static def _Foo(): number
4564 return 1234
4565 enddef
4566 endclass
4567 class B extends A
4568 def Bar()
4569 enddef
4570 endclass
4571 class C extends B
4572 static def Baz(): number
4573 return A._Foo()
4574 enddef
4575 endclass
4576 assert_equal(1234, C.Baz())
4577 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004578 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004579
4580 # Call a private class method from a child class object
4581 lines =<< trim END
4582 vim9script
4583 class A
4584 static def _Foo(): number
4585 return 1234
4586 enddef
4587 endclass
4588 class B extends A
4589 def Bar()
4590 enddef
4591 endclass
4592 class C extends B
4593 def Baz(): number
4594 enddef
4595 endclass
4596 var c = C.new()
4597 assert_equal(1234, C._Foo())
4598 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004599 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004600enddef
4601
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004602" Test for using the return value of a class/object method as a function
4603" argument.
4604def Test_objmethod_funcarg()
4605 var lines =<< trim END
4606 vim9script
4607
4608 class C
4609 def Foo(): string
4610 return 'foo'
4611 enddef
4612 endclass
4613
4614 def Bar(a: number, s: string): string
4615 return s
4616 enddef
4617
4618 def Baz(c: C)
4619 assert_equal('foo', Bar(10, c.Foo()))
4620 enddef
4621
4622 var t = C.new()
4623 Baz(t)
4624 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004625 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004626
4627 lines =<< trim END
4628 vim9script
4629
4630 class C
4631 static def Foo(): string
4632 return 'foo'
4633 enddef
4634 endclass
4635
4636 def Bar(a: number, s: string): string
4637 return s
4638 enddef
4639
4640 def Baz()
4641 assert_equal('foo', Bar(10, C.Foo()))
4642 enddef
4643
4644 Baz()
4645 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004646 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004647enddef
4648
Ernie Raelcf138d42023-09-06 20:45:03 +02004649def Test_static_inheritence()
4650 # subclasses get their own static copy
4651 var lines =<< trim END
4652 vim9script
4653
4654 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004655 static _svar: number
4656 this._mvar: number
4657 def new()
4658 _svar = 1
4659 this._mvar = 101
4660 enddef
4661 def AccessObject(): number
4662 return this._mvar
4663 enddef
4664 def AccessStaticThroughObject(): number
4665 return _svar
4666 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004667 endclass
4668
4669 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004670 def new()
4671 this._mvar = 102
4672 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004673 endclass
4674
4675 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004676 def new()
4677 this._mvar = 103
4678 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004679
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004680 def AccessPrivateStaticThroughClassName(): number
4681 assert_equal(1, A._svar)
4682 return 444
4683 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004684 endclass
4685
4686 var oa = A.new()
4687 var ob = B.new()
4688 var oc = C.new()
4689 assert_equal(101, oa.AccessObject())
4690 assert_equal(102, ob.AccessObject())
4691 assert_equal(103, oc.AccessObject())
4692
Ernie Rael64885642023-10-04 20:16:22 +02004693 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02004694
4695 # verify object properly resolves to correct static
4696 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004697 assert_equal(1, ob.AccessStaticThroughObject())
4698 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02004699 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004700 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02004701enddef
4702
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004703" Test for declaring duplicate object and class members
4704def Test_dup_member_variable()
4705 # Duplicate member variable
4706 var lines =<< trim END
4707 vim9script
4708 class C
4709 this.val = 10
4710 this.val = 20
4711 endclass
4712 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004713 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004714
4715 # Duplicate private member variable
4716 lines =<< trim END
4717 vim9script
4718 class C
4719 this._val = 10
4720 this._val = 20
4721 endclass
4722 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004723 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004724
4725 # Duplicate public member variable
4726 lines =<< trim END
4727 vim9script
4728 class C
4729 public this.val = 10
4730 public this.val = 20
4731 endclass
4732 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004733 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004734
4735 # Duplicate private member variable
4736 lines =<< trim END
4737 vim9script
4738 class C
4739 this.val = 10
4740 this._val = 20
4741 endclass
4742 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004743 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004744
4745 # Duplicate public and private member variable
4746 lines =<< trim END
4747 vim9script
4748 class C
4749 this._val = 20
4750 public this.val = 10
4751 endclass
4752 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004753 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004754
4755 # Duplicate class member variable
4756 lines =<< trim END
4757 vim9script
4758 class C
4759 static s: string = "abc"
4760 static _s: string = "def"
4761 endclass
4762 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004763 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004764
4765 # Duplicate public and private class member variable
4766 lines =<< trim END
4767 vim9script
4768 class C
4769 public static s: string = "abc"
4770 static _s: string = "def"
4771 endclass
4772 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004773 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004774
4775 # Duplicate class and object member variable
4776 lines =<< trim END
4777 vim9script
4778 class C
4779 static val = 10
4780 this.val = 20
4781 def new()
4782 enddef
4783 endclass
4784 var c = C.new()
4785 assert_equal(10, C.val)
4786 assert_equal(20, c.val)
4787 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02004788 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004789
4790 # Duplicate object member variable in a derived class
4791 lines =<< trim END
4792 vim9script
4793 class A
4794 this.val = 10
4795 endclass
4796 class B extends A
4797 endclass
4798 class C extends B
4799 this.val = 20
4800 endclass
4801 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004802 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004803
4804 # Duplicate object private member variable in a derived class
4805 lines =<< trim END
4806 vim9script
4807 class A
4808 this._val = 10
4809 endclass
4810 class B extends A
4811 endclass
4812 class C extends B
4813 this._val = 20
4814 endclass
4815 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004816 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004817
4818 # Duplicate object private member variable in a derived class
4819 lines =<< trim END
4820 vim9script
4821 class A
4822 this.val = 10
4823 endclass
4824 class B extends A
4825 endclass
4826 class C extends B
4827 this._val = 20
4828 endclass
4829 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004830 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004831
4832 # Duplicate object member variable in a derived class
4833 lines =<< trim END
4834 vim9script
4835 class A
4836 this._val = 10
4837 endclass
4838 class B extends A
4839 endclass
4840 class C extends B
4841 this.val = 20
4842 endclass
4843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004844 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004845
4846 # Two member variables with a common prefix
4847 lines =<< trim END
4848 vim9script
4849 class A
4850 public static svar2: number
4851 public static svar: number
4852 endclass
4853 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004854 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004855enddef
4856
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004857" Test for accessing a private member outside a class in a def function
4858def Test_private_member_access_outside_class()
4859 # private object member variable
4860 var lines =<< trim END
4861 vim9script
4862 class A
4863 this._val = 10
4864 def GetVal(): number
4865 return this._val
4866 enddef
4867 endclass
4868 def T()
4869 var a = A.new()
4870 a._val = 20
4871 enddef
4872 T()
4873 END
Ernie Rael64885642023-10-04 20:16:22 +02004874 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004875
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004876 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004877 lines =<< trim END
4878 vim9script
4879 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004880 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004881 endclass
4882 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004883 var a = A.new()
4884 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004885 enddef
4886 T()
4887 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004888 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004889
4890 # private static member variable
4891 lines =<< trim END
4892 vim9script
4893 class A
4894 static _val = 10
4895 endclass
4896 def T()
4897 var a = A.new()
4898 var x = a._val
4899 enddef
4900 T()
4901 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004902 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004903
4904 # private static member variable
4905 lines =<< trim END
4906 vim9script
4907 class A
4908 static _val = 10
4909 endclass
4910 def T()
4911 var a = A.new()
4912 a._val = 3
4913 enddef
4914 T()
4915 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004916 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004917
4918 # private static class variable
4919 lines =<< trim END
4920 vim9script
4921 class A
4922 static _val = 10
4923 endclass
4924 def T()
4925 var x = A._val
4926 enddef
4927 T()
4928 END
Ernie Rael64885642023-10-04 20:16:22 +02004929 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02004930
4931 # private static class variable
4932 lines =<< trim END
4933 vim9script
4934 class A
4935 static _val = 10
4936 endclass
4937 def T()
4938 A._val = 3
4939 enddef
4940 T()
4941 END
Ernie Rael64885642023-10-04 20:16:22 +02004942 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004943enddef
4944
4945" Test for changing the member access of an interface in a implementation class
4946def Test_change_interface_member_access()
4947 var lines =<< trim END
4948 vim9script
4949 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004950 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004951 endinterface
4952 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004953 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004954 endclass
4955 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004956 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004957
4958 lines =<< trim END
4959 vim9script
4960 interface A
4961 this.val: number
4962 endinterface
4963 class B implements A
4964 public this.val = 10
4965 endclass
4966 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004967 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004968enddef
4969
4970" Test for trying to change a readonly member from a def function
4971def Test_readonly_member_change_in_def_func()
4972 var lines =<< trim END
4973 vim9script
4974 class A
4975 this.val: number
4976 endclass
4977 def T()
4978 var a = A.new()
4979 a.val = 20
4980 enddef
4981 T()
4982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004983 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004984enddef
4985
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004986" Test for reading and writing a class member from a def function
4987def Test_modify_class_member_from_def_function()
4988 var lines =<< trim END
4989 vim9script
4990 class A
4991 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004992 public static var2: list<number> = [1, 2]
4993 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004994 static _priv_var4: number = 40
4995 endclass
4996 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004997 assert_equal([1, 2], A.var2)
4998 assert_equal({a: 1, b: 2}, A.var3)
4999 A.var2 = [3, 4]
5000 A.var3 = {c: 3, d: 4}
5001 assert_equal([3, 4], A.var2)
5002 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael64885642023-10-04 20:16:22 +02005003 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005004 enddef
5005 T()
5006 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005007 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005008enddef
5009
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005010" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005011def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005012 var lines =<< trim END
5013 vim9script
5014 class A
5015 public static svar1: list<number> = [1]
5016 public static svar2: list<number> = [2]
5017 endclass
5018
5019 A.svar1->add(3)
5020 A.svar2->add(4)
5021 assert_equal([1, 3], A.svar1)
5022 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005023
5024 def Foo()
5025 A.svar1->add(7)
5026 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005027 assert_equal([1, 3, 7], A.svar1)
5028 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005029 enddef
5030 Foo()
5031 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005032 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005033
5034 # Cannot read from a class variable using an object in script context
5035 lines =<< trim END
5036 vim9script
5037 class A
5038 public this.var1: number
5039 public static svar2: list<number> = [1]
5040 endclass
5041
5042 var a = A.new()
5043 echo a.svar2
5044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005045 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005046
5047 # Cannot write to a class variable using an object in script context
5048 lines =<< trim END
5049 vim9script
5050 class A
5051 public this.var1: number
5052 public static svar2: list<number> = [1]
5053 endclass
5054
5055 var a = A.new()
5056 a.svar2 = [2]
5057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005058 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005059
5060 # Cannot read from a class variable using an object in def method context
5061 lines =<< trim END
5062 vim9script
5063 class A
5064 public this.var1: number
5065 public static svar2: list<number> = [1]
5066 endclass
5067
5068 def T()
5069 var a = A.new()
5070 echo a.svar2
5071 enddef
5072 T()
5073 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005074 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005075
5076 # Cannot write to a class variable using an object in def method context
5077 lines =<< trim END
5078 vim9script
5079 class A
5080 public this.var1: number
5081 public static svar2: list<number> = [1]
5082 endclass
5083
5084 def T()
5085 var a = A.new()
5086 a.svar2 = [2]
5087 enddef
5088 T()
5089 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005090 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005091enddef
5092
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005093" Test for using a interface method using a child object
5094def Test_interface_method_from_child()
5095 var lines =<< trim END
5096 vim9script
5097
5098 interface A
5099 def Foo(): string
5100 endinterface
5101
5102 class B implements A
5103 def Foo(): string
5104 return 'foo'
5105 enddef
5106 endclass
5107
5108 class C extends B
5109 def Bar(): string
5110 return 'bar'
5111 enddef
5112 endclass
5113
5114 def T1(a: A)
5115 assert_equal('foo', a.Foo())
5116 enddef
5117
5118 def T2(b: B)
5119 assert_equal('foo', b.Foo())
5120 enddef
5121
5122 var c = C.new()
5123 T1(c)
5124 T2(c)
5125 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005126 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005127enddef
5128
5129" Test for using an interface method using a child object when it is overridden
5130" by the child class.
5131" FIXME: This test fails.
5132" def Test_interface_overridden_method_from_child()
5133" var lines =<< trim END
5134" vim9script
5135"
5136" interface A
5137" def Foo(): string
5138" endinterface
5139"
5140" class B implements A
5141" def Foo(): string
5142" return 'b-foo'
5143" enddef
5144" endclass
5145"
5146" class C extends B
5147" def Bar(): string
5148" return 'bar'
5149" enddef
5150" def Foo(): string
5151" return 'c-foo'
5152" enddef
5153" endclass
5154"
5155" def T1(a: A)
5156" assert_equal('c-foo', a.Foo())
5157" enddef
5158"
5159" def T2(b: B)
5160" assert_equal('c-foo', b.Foo())
5161" enddef
5162"
5163" var c = C.new()
5164" T1(c)
5165" T2(c)
5166" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005167" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005168" enddef
5169
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005170" Test for abstract methods
5171def Test_abstract_method()
5172 # Use two abstract methods
5173 var lines =<< trim END
5174 vim9script
5175 abstract class A
5176 def M1(): number
5177 return 10
5178 enddef
5179 abstract def M2(): number
5180 abstract def M3(): number
5181 endclass
5182 class B extends A
5183 def M2(): number
5184 return 20
5185 enddef
5186 def M3(): number
5187 return 30
5188 enddef
5189 endclass
5190 var b = B.new()
5191 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5192 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005193 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005194
5195 # Don't define an abstract method
5196 lines =<< trim END
5197 vim9script
5198 abstract class A
5199 abstract def Foo()
5200 endclass
5201 class B extends A
5202 endclass
5203 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005204 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005205
5206 # Use abstract method in a concrete class
5207 lines =<< trim END
5208 vim9script
5209 class A
5210 abstract def Foo()
5211 endclass
5212 class B extends A
5213 endclass
5214 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005215 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005216
5217 # Use abstract method in an interface
5218 lines =<< trim END
5219 vim9script
5220 interface A
5221 abstract def Foo()
5222 endinterface
5223 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005224 def Foo()
5225 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005226 endclass
5227 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005228 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005229
5230 # Abbreviate the "abstract" keyword
5231 lines =<< trim END
5232 vim9script
5233 class A
5234 abs def Foo()
5235 endclass
5236 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005237 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005238
5239 # Use "abstract" with a member variable
5240 lines =<< trim END
5241 vim9script
5242 abstract class A
5243 abstract this.val = 10
5244 endclass
5245 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005246 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005247
5248 # Use a static abstract method
5249 lines =<< trim END
5250 vim9script
5251 abstract class A
5252 abstract static def Foo(): number
5253 endclass
5254 class B extends A
5255 static def Foo(): number
5256 return 4
5257 enddef
5258 endclass
5259 assert_equal(4, B.Foo())
5260 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005261 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005262
5263 # Type mismatch between abstract method and concrete method
5264 lines =<< trim END
5265 vim9script
5266 abstract class A
5267 abstract def Foo(a: string, b: number): list<number>
5268 endclass
5269 class B extends A
5270 def Foo(a: number, b: string): list<string>
5271 return []
5272 enddef
5273 endclass
5274 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005275 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 +02005276
5277 # Use an abstract class to invoke an abstract method
5278 # FIXME: This should fail
5279 lines =<< trim END
5280 vim9script
5281 abstract class A
5282 abstract static def Foo()
5283 endclass
5284 A.Foo()
5285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005286 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005287
5288 # Invoke an abstract method from a def function
5289 lines =<< trim END
5290 vim9script
5291 abstract class A
5292 abstract def Foo(): list<number>
5293 endclass
5294 class B extends A
5295 def Foo(): list<number>
5296 return [3, 5]
5297 enddef
5298 endclass
5299 def Bar(c: B)
5300 assert_equal([3, 5], c.Foo())
5301 enddef
5302 var b = B.new()
5303 Bar(b)
5304 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005305 v9.CheckSourceSuccess(lines)
5306enddef
5307
5308" Test for calling a class method from a subclass
5309def Test_class_method_call_from_subclass()
5310 # class method call from a subclass
5311 var lines =<< trim END
5312 vim9script
5313
5314 class A
5315 static def Foo()
5316 echo "foo"
5317 enddef
5318 endclass
5319
5320 class B extends A
5321 def Bar()
5322 Foo()
5323 enddef
5324 endclass
5325
5326 var b = B.new()
5327 b.Bar()
5328 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005329 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005330enddef
5331
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005332" Test for calling a class method using an object in a def function context and
5333" script context.
5334def Test_class_method_call_using_object()
5335 # script context
5336 var lines =<< trim END
5337 vim9script
5338 class A
5339 static def Foo(): list<string>
5340 return ['a', 'b']
5341 enddef
5342 def Bar()
5343 assert_equal(['a', 'b'], A.Foo())
5344 assert_equal(['a', 'b'], Foo())
5345 enddef
5346 endclass
5347
5348 def T()
5349 assert_equal(['a', 'b'], A.Foo())
5350 var t_a = A.new()
5351 t_a.Bar()
5352 enddef
5353
5354 assert_equal(['a', 'b'], A.Foo())
5355 var a = A.new()
5356 a.Bar()
5357 T()
5358 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005359 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005360
5361 # script context
5362 lines =<< trim END
5363 vim9script
5364 class A
5365 static def Foo(): string
5366 return 'foo'
5367 enddef
5368 endclass
5369
5370 var a = A.new()
5371 assert_equal('foo', a.Foo())
5372 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005373 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005374
5375 # def function context
5376 lines =<< trim END
5377 vim9script
5378 class A
5379 static def Foo(): string
5380 return 'foo'
5381 enddef
5382 endclass
5383
5384 def T()
5385 var a = A.new()
5386 assert_equal('foo', a.Foo())
5387 enddef
5388 T()
5389 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005390 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005391enddef
5392
5393def Test_class_variable()
5394 var lines =<< trim END
5395 vim9script
5396
5397 class A
5398 public static val: number = 10
5399 static def ClassFunc()
5400 assert_equal(10, val)
5401 enddef
5402 def ObjFunc()
5403 assert_equal(10, val)
5404 enddef
5405 endclass
5406
5407 class B extends A
5408 endclass
5409
5410 assert_equal(10, A.val)
5411 A.ClassFunc()
5412 var a = A.new()
5413 a.ObjFunc()
5414 var b = B.new()
5415 b.ObjFunc()
5416
5417 def T1(a1: A)
5418 a1.ObjFunc()
5419 A.ClassFunc()
5420 enddef
5421 T1(b)
5422
5423 A.val = 20
5424 assert_equal(20, A.val)
5425 END
5426 v9.CheckSourceSuccess(lines)
5427
5428 # Modifying a parent class variable from a child class method
5429 lines =<< trim END
5430 vim9script
5431
5432 class A
5433 static val: number = 10
5434 endclass
5435
5436 class B extends A
5437 static def ClassFunc()
5438 val = 20
5439 enddef
5440 endclass
5441 B.ClassFunc()
5442 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005443 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005444
5445 # Reading a parent class variable from a child class method
5446 lines =<< trim END
5447 vim9script
5448
5449 class A
5450 static val: number = 10
5451 endclass
5452
5453 class B extends A
5454 static def ClassFunc()
5455 var i = val
5456 enddef
5457 endclass
5458 B.ClassFunc()
5459 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005460 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005461
5462 # Modifying a parent class variable from a child object method
5463 lines =<< trim END
5464 vim9script
5465
5466 class A
5467 static val: number = 10
5468 endclass
5469
5470 class B extends A
5471 def ObjFunc()
5472 val = 20
5473 enddef
5474 endclass
5475 var b = B.new()
5476 b.ObjFunc()
5477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005478 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005479
5480 # Reading a parent class variable from a child object method
5481 lines =<< trim END
5482 vim9script
5483
5484 class A
5485 static val: number = 10
5486 endclass
5487
5488 class B extends A
5489 def ObjFunc()
5490 var i = val
5491 enddef
5492 endclass
5493 var b = B.new()
5494 b.ObjFunc()
5495 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005496 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005497
5498 # Modifying a class variable using an object at script level
5499 lines =<< trim END
5500 vim9script
5501
5502 class A
5503 static val: number = 10
5504 endclass
5505 var a = A.new()
5506 a.val = 20
5507 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005508 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005509
5510 # Reading a class variable using an object at script level
5511 lines =<< trim END
5512 vim9script
5513
5514 class A
5515 static val: number = 10
5516 endclass
5517 var a = A.new()
5518 var i = a.val
5519 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005520 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005521
5522 # Modifying a class variable using an object at function level
5523 lines =<< trim END
5524 vim9script
5525
5526 class A
5527 static val: number = 10
5528 endclass
5529
5530 def T()
5531 var a = A.new()
5532 a.val = 20
5533 enddef
5534 T()
5535 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005536 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005537
5538 # Reading a class variable using an object at function level
5539 lines =<< trim END
5540 vim9script
5541
5542 class A
5543 static val: number = 10
5544 endclass
5545 def T()
5546 var a = A.new()
5547 var i = a.val
5548 enddef
5549 T()
5550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005551 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005552enddef
5553
5554" Test for using a duplicate class method and class variable in a child class
5555def Test_dup_class_member()
5556 # duplicate class variable, class method and overridden object method
5557 var lines =<< trim END
5558 vim9script
5559 class A
5560 static sval = 100
5561 static def Check()
5562 assert_equal(100, sval)
5563 enddef
5564 def GetVal(): number
5565 return sval
5566 enddef
5567 endclass
5568
5569 class B extends A
5570 static sval = 200
5571 static def Check()
5572 assert_equal(200, sval)
5573 enddef
5574 def GetVal(): number
5575 return sval
5576 enddef
5577 endclass
5578
5579 def T1(aa: A): number
5580 return aa.GetVal()
5581 enddef
5582
5583 def T2(bb: B): number
5584 return bb.GetVal()
5585 enddef
5586
5587 assert_equal(100, A.sval)
5588 assert_equal(200, B.sval)
5589 var a = A.new()
5590 assert_equal(100, a.GetVal())
5591 var b = B.new()
5592 assert_equal(200, b.GetVal())
5593 assert_equal(200, T1(b))
5594 assert_equal(200, T2(b))
5595 END
5596 v9.CheckSourceSuccess(lines)
5597
5598 # duplicate class variable and class method
5599 lines =<< trim END
5600 vim9script
5601 class A
5602 static sval = 100
5603 static def Check()
5604 assert_equal(100, sval)
5605 enddef
5606 def GetVal(): number
5607 return sval
5608 enddef
5609 endclass
5610
5611 class B extends A
5612 static sval = 200
5613 static def Check()
5614 assert_equal(200, sval)
5615 enddef
5616 endclass
5617
5618 def T1(aa: A): number
5619 return aa.GetVal()
5620 enddef
5621
5622 def T2(bb: B): number
5623 return bb.GetVal()
5624 enddef
5625
5626 assert_equal(100, A.sval)
5627 assert_equal(200, B.sval)
5628 var a = A.new()
5629 assert_equal(100, a.GetVal())
5630 var b = B.new()
5631 assert_equal(100, b.GetVal())
5632 assert_equal(100, T1(b))
5633 assert_equal(100, T2(b))
5634 END
5635 v9.CheckSourceSuccess(lines)
5636enddef
5637
5638" Test for calling an instance method using the class
5639def Test_instance_method_call_using_class()
5640 # Invoke an object method using a class in script context
5641 var lines =<< trim END
5642 vim9script
5643 class A
5644 def Foo()
5645 echo "foo"
5646 enddef
5647 endclass
5648 A.Foo()
5649 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005650 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005651
5652 # Invoke an object method using a class in def function context
5653 lines =<< trim END
5654 vim9script
5655 class A
5656 def Foo()
5657 echo "foo"
5658 enddef
5659 endclass
5660 def T()
5661 A.Foo()
5662 enddef
5663 T()
5664 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005665 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005666enddef
5667
5668" Test for duplicate class method and instance method
5669def Test_dup_classmethod_objmethod()
5670 # Duplicate instance method
5671 var lines =<< trim END
5672 vim9script
5673 class A
5674 static def Foo()
5675 enddef
5676 def Foo()
5677 enddef
5678 endclass
5679 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005680 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005681
5682 # Duplicate private instance method
5683 lines =<< trim END
5684 vim9script
5685 class A
5686 static def Foo()
5687 enddef
5688 def _Foo()
5689 enddef
5690 endclass
5691 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005692 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005693
5694 # Duplicate class method
5695 lines =<< trim END
5696 vim9script
5697 class A
5698 def Foo()
5699 enddef
5700 static def Foo()
5701 enddef
5702 endclass
5703 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005704 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005705
5706 # Duplicate private class method
5707 lines =<< trim END
5708 vim9script
5709 class A
5710 def Foo()
5711 enddef
5712 static def _Foo()
5713 enddef
5714 endclass
5715 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005716 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005717
5718 # Duplicate private class and object method
5719 lines =<< trim END
5720 vim9script
5721 class A
5722 def _Foo()
5723 enddef
5724 static def _Foo()
5725 enddef
5726 endclass
5727 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005728 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005729enddef
5730
5731" Test for an instance method access level comparison with parent instance
5732" methods.
5733def Test_instance_method_access_level()
5734 # Private method in subclass
5735 var lines =<< trim END
5736 vim9script
5737 class A
5738 def Foo()
5739 enddef
5740 endclass
5741 class B extends A
5742 endclass
5743 class C extends B
5744 def _Foo()
5745 enddef
5746 endclass
5747 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005748 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005749
5750 # Public method in subclass
5751 lines =<< trim END
5752 vim9script
5753 class A
5754 def _Foo()
5755 enddef
5756 endclass
5757 class B extends A
5758 endclass
5759 class C extends B
5760 def Foo()
5761 enddef
5762 endclass
5763 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005764 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005765enddef
5766
5767def Test_extend_empty_class()
5768 var lines =<< trim END
5769 vim9script
5770 class A
5771 endclass
5772 class B extends A
5773 endclass
5774 class C extends B
5775 public static rw_class_var = 1
5776 public this.rw_obj_var = 2
5777 static def ClassMethod(): number
5778 return 3
5779 enddef
5780 def ObjMethod(): number
5781 return 4
5782 enddef
5783 endclass
5784 assert_equal(1, C.rw_class_var)
5785 assert_equal(3, C.ClassMethod())
5786 var c = C.new()
5787 assert_equal(2, c.rw_obj_var)
5788 assert_equal(4, c.ObjMethod())
5789 END
5790 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005791enddef
5792
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005793" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005794" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005795def Test_interface_with_unsupported_members()
5796 var lines =<< trim END
5797 vim9script
5798 interface A
5799 static num: number
5800 endinterface
5801 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005802 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005803
5804 lines =<< trim END
5805 vim9script
5806 interface A
5807 static _num: number
5808 endinterface
5809 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005810 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005811
5812 lines =<< trim END
5813 vim9script
5814 interface A
5815 public static num: number
5816 endinterface
5817 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005818 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005819
5820 lines =<< trim END
5821 vim9script
5822 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005823 public static num: number
5824 endinterface
5825 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005826 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005827
5828 lines =<< trim END
5829 vim9script
5830 interface A
5831 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005832 endinterface
5833 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005834 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005835
5836 lines =<< trim END
5837 vim9script
5838 interface A
5839 static def Foo(d: dict<any>): list<string>
5840 endinterface
5841 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005842 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005843
5844 lines =<< trim END
5845 vim9script
5846 interface A
5847 static def _Foo(d: dict<any>): list<string>
5848 endinterface
5849 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005850 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005851
5852 lines =<< trim END
5853 vim9script
5854 interface A
5855 this._Foo: list<string>
5856 endinterface
5857 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005858 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005859
5860 lines =<< trim END
5861 vim9script
5862 interface A
5863 def _Foo(d: dict<any>): list<string>
5864 endinterface
5865 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005866 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005867enddef
5868
5869" Test for extending an interface
5870def Test_extend_interface()
5871 var lines =<< trim END
5872 vim9script
5873 interface A
5874 this.var1: list<string>
5875 def Foo()
5876 endinterface
5877 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005878 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005879 def Bar()
5880 endinterface
5881 class C implements A, B
5882 this.var1 = [1, 2]
5883 def Foo()
5884 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005885 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005886 def Bar()
5887 enddef
5888 endclass
5889 END
5890 v9.CheckSourceSuccess(lines)
5891
5892 lines =<< trim END
5893 vim9script
5894 interface A
5895 def Foo()
5896 endinterface
5897 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005898 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005899 endinterface
5900 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005901 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005902 endclass
5903 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005904 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005905
5906 lines =<< trim END
5907 vim9script
5908 interface A
5909 def Foo()
5910 endinterface
5911 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005912 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005913 endinterface
5914 class C implements A, B
5915 def Foo()
5916 enddef
5917 endclass
5918 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005919 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005920
5921 # interface cannot extend a class
5922 lines =<< trim END
5923 vim9script
5924 class A
5925 endclass
5926 interface B extends A
5927 endinterface
5928 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005929 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005930
5931 # class cannot extend an interface
5932 lines =<< trim END
5933 vim9script
5934 interface A
5935 endinterface
5936 class B extends A
5937 endclass
5938 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005939 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005940
5941 # interface cannot implement another interface
5942 lines =<< trim END
5943 vim9script
5944 interface A
5945 endinterface
5946 interface B implements A
5947 endinterface
5948 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005949 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005950
5951 # interface cannot extend multiple interfaces
5952 lines =<< trim END
5953 vim9script
5954 interface A
5955 endinterface
5956 interface B
5957 endinterface
5958 interface C extends A, B
5959 endinterface
5960 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005961 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005962
5963 # Variable type in an extended interface is of different type
5964 lines =<< trim END
5965 vim9script
5966 interface A
5967 this.val1: number
5968 endinterface
5969 interface B extends A
5970 this.val2: string
5971 endinterface
5972 interface C extends B
5973 this.val1: string
5974 this.val2: number
5975 endinterface
5976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005977 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005978enddef
5979
5980" Test for a child class implementing an interface when some of the methods are
5981" defined in the parent class.
5982def Test_child_class_implements_interface()
5983 var lines =<< trim END
5984 vim9script
5985
5986 interface Intf
5987 def F1(): list<list<number>>
5988 def F2(): list<list<number>>
5989 def F3(): list<list<number>>
5990 this.var1: list<dict<number>>
5991 this.var2: list<dict<number>>
5992 this.var3: list<dict<number>>
5993 endinterface
5994
5995 class A
5996 def A1()
5997 enddef
5998 def F3(): list<list<number>>
5999 return [[3]]
6000 enddef
6001 this.v1: list<list<number>> = [[0]]
6002 this.var3 = [{c: 30}]
6003 endclass
6004
6005 class B extends A
6006 def B1()
6007 enddef
6008 def F2(): list<list<number>>
6009 return [[2]]
6010 enddef
6011 this.v2: list<list<number>> = [[0]]
6012 this.var2 = [{b: 20}]
6013 endclass
6014
6015 class C extends B implements Intf
6016 def C1()
6017 enddef
6018 def F1(): list<list<number>>
6019 return [[1]]
6020 enddef
6021 this.v3: list<list<number>> = [[0]]
6022 this.var1 = [{a: 10}]
6023 endclass
6024
6025 def T(if: Intf)
6026 assert_equal([[1]], if.F1())
6027 assert_equal([[2]], if.F2())
6028 assert_equal([[3]], if.F3())
6029 assert_equal([{a: 10}], if.var1)
6030 assert_equal([{b: 20}], if.var2)
6031 assert_equal([{c: 30}], if.var3)
6032 enddef
6033
6034 var c = C.new()
6035 T(c)
6036 assert_equal([[1]], c.F1())
6037 assert_equal([[2]], c.F2())
6038 assert_equal([[3]], c.F3())
6039 assert_equal([{a: 10}], c.var1)
6040 assert_equal([{b: 20}], c.var2)
6041 assert_equal([{c: 30}], c.var3)
6042 END
6043 v9.CheckSourceSuccess(lines)
6044
6045 # One of the interface methods is not found
6046 lines =<< trim END
6047 vim9script
6048
6049 interface Intf
6050 def F1()
6051 def F2()
6052 def F3()
6053 endinterface
6054
6055 class A
6056 def A1()
6057 enddef
6058 endclass
6059
6060 class B extends A
6061 def B1()
6062 enddef
6063 def F2()
6064 enddef
6065 endclass
6066
6067 class C extends B implements Intf
6068 def C1()
6069 enddef
6070 def F1()
6071 enddef
6072 endclass
6073 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006074 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006075
6076 # One of the interface methods is of different type
6077 lines =<< trim END
6078 vim9script
6079
6080 interface Intf
6081 def F1()
6082 def F2()
6083 def F3()
6084 endinterface
6085
6086 class A
6087 def F3(): number
6088 return 0
6089 enddef
6090 def A1()
6091 enddef
6092 endclass
6093
6094 class B extends A
6095 def B1()
6096 enddef
6097 def F2()
6098 enddef
6099 endclass
6100
6101 class C extends B implements Intf
6102 def C1()
6103 enddef
6104 def F1()
6105 enddef
6106 endclass
6107 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006108 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006109
6110 # One of the interface variables is not present
6111 lines =<< trim END
6112 vim9script
6113
6114 interface Intf
6115 this.var1: list<dict<number>>
6116 this.var2: list<dict<number>>
6117 this.var3: list<dict<number>>
6118 endinterface
6119
6120 class A
6121 this.v1: list<list<number>> = [[0]]
6122 endclass
6123
6124 class B extends A
6125 this.v2: list<list<number>> = [[0]]
6126 this.var2 = [{b: 20}]
6127 endclass
6128
6129 class C extends B implements Intf
6130 this.v3: list<list<number>> = [[0]]
6131 this.var1 = [{a: 10}]
6132 endclass
6133 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006134 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006135
6136 # One of the interface variables is of different type
6137 lines =<< trim END
6138 vim9script
6139
6140 interface Intf
6141 this.var1: list<dict<number>>
6142 this.var2: list<dict<number>>
6143 this.var3: list<dict<number>>
6144 endinterface
6145
6146 class A
6147 this.v1: list<list<number>> = [[0]]
6148 this.var3: list<dict<string>>
6149 endclass
6150
6151 class B extends A
6152 this.v2: list<list<number>> = [[0]]
6153 this.var2 = [{b: 20}]
6154 endclass
6155
6156 class C extends B implements Intf
6157 this.v3: list<list<number>> = [[0]]
6158 this.var1 = [{a: 10}]
6159 endclass
6160 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006161 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 +02006162enddef
6163
6164" Test for extending an interface with duplicate variables and methods
6165def Test_interface_extends_with_dup_members()
6166 var lines =<< trim END
6167 vim9script
6168 interface A
6169 this.n1: number
6170 def Foo1(): number
6171 endinterface
6172 interface B extends A
6173 this.n2: number
6174 this.n1: number
6175 def Foo2(): number
6176 def Foo1(): number
6177 endinterface
6178 class C implements B
6179 this.n1 = 10
6180 this.n2 = 20
6181 def Foo1(): number
6182 return 30
6183 enddef
6184 def Foo2(): number
6185 return 40
6186 enddef
6187 endclass
6188 def T1(a: A)
6189 assert_equal(10, a.n1)
6190 assert_equal(30, a.Foo1())
6191 enddef
6192 def T2(b: B)
6193 assert_equal(10, b.n1)
6194 assert_equal(20, b.n2)
6195 assert_equal(30, b.Foo1())
6196 assert_equal(40, b.Foo2())
6197 enddef
6198 var c = C.new()
6199 T1(c)
6200 T2(c)
6201 END
6202 v9.CheckSourceSuccess(lines)
6203enddef
6204
6205" Test for using "any" type for a variable in a sub-class while it has a
6206" concrete type in the interface
6207def Test_implements_using_var_type_any()
6208 var lines =<< trim END
6209 vim9script
6210 interface A
6211 this.val: list<dict<string>>
6212 endinterface
6213 class B implements A
6214 this.val = [{a: '1'}, {b: '2'}]
6215 endclass
6216 var b = B.new()
6217 assert_equal([{a: '1'}, {b: '2'}], b.val)
6218 END
6219 v9.CheckSourceSuccess(lines)
6220
6221 # initialize instance variable using a different type
6222 lines =<< trim END
6223 vim9script
6224 interface A
6225 this.val: list<dict<string>>
6226 endinterface
6227 class B implements A
6228 this.val = {a: 1, b: 2}
6229 endclass
6230 var b = B.new()
6231 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006232 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006233enddef
6234
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006235" Test for assigning to a member variable in a nested class
6236def Test_nested_object_assignment()
6237 var lines =<< trim END
6238 vim9script
6239
6240 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006241 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006242 endclass
6243
6244 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006245 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006246 endclass
6247
6248 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006249 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006250 endclass
6251
6252 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006253 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006254 endclass
6255
6256 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006257 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006258 enddef
6259
6260 var d = D.new()
6261 T(d)
6262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006263 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006264enddef
6265
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006266" Test for calling methods using a null object
6267def Test_null_object_method_call()
6268 # Calling a object method using a null object in script context
6269 var lines =<< trim END
6270 vim9script
6271
6272 class C
6273 def Foo()
6274 assert_report('This method should not be executed')
6275 enddef
6276 endclass
6277
6278 var o: C
6279 o.Foo()
6280 END
6281 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6282
6283 # Calling a object method using a null object in def function context
6284 lines =<< trim END
6285 vim9script
6286
6287 class C
6288 def Foo()
6289 assert_report('This method should not be executed')
6290 enddef
6291 endclass
6292
6293 def T()
6294 var o: C
6295 o.Foo()
6296 enddef
6297 T()
6298 END
6299 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6300
6301 # Calling a object method through another class method using a null object in
6302 # script context
6303 lines =<< trim END
6304 vim9script
6305
6306 class C
6307 def Foo()
6308 assert_report('This method should not be executed')
6309 enddef
6310
6311 static def Bar(o_any: any)
6312 var o_typed: C = o_any
6313 o_typed.Foo()
6314 enddef
6315 endclass
6316
6317 var o: C
6318 C.Bar(o)
6319 END
6320 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6321
6322 # Calling a object method through another class method using a null object in
6323 # def function context
6324 lines =<< trim END
6325 vim9script
6326
6327 class C
6328 def Foo()
6329 assert_report('This method should not be executed')
6330 enddef
6331
6332 static def Bar(o_any: any)
6333 var o_typed: C = o_any
6334 o_typed.Foo()
6335 enddef
6336 endclass
6337
6338 def T()
6339 var o: C
6340 C.Bar(o)
6341 enddef
6342 T()
6343 END
6344 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6345enddef
6346
6347" Test for using a dict as an object member
6348def Test_dict_object_member()
6349 var lines =<< trim END
6350 vim9script
6351
6352 class Context
6353 public this.state: dict<number> = {}
6354 def GetState(): dict<number>
6355 return this.state
6356 enddef
6357 endclass
6358
6359 var ctx = Context.new()
6360 ctx.state->extend({a: 1})
6361 ctx.state['b'] = 2
6362 assert_equal({a: 1, b: 2}, ctx.GetState())
6363
6364 def F()
6365 ctx.state['c'] = 3
6366 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6367 enddef
6368 F()
6369 assert_equal(3, ctx.state.c)
6370 ctx.state.c = 4
6371 assert_equal(4, ctx.state.c)
6372 END
6373 v9.CheckSourceSuccess(lines)
6374enddef
6375
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006376" The following test was failing after 9.0.1914. This was caused by using a
6377" freed object from a previous method call.
6378def Test_freed_object_from_previous_method_call()
6379 var lines =<< trim END
6380 vim9script
6381
6382 class Context
6383 endclass
6384
6385 class Result
6386 endclass
6387
6388 def Failure(): Result
6389 return Result.new()
6390 enddef
6391
6392 def GetResult(ctx: Context): Result
6393 return Failure()
6394 enddef
6395
6396 def Test_GetResult()
6397 var ctx = Context.new()
6398 var result = GetResult(ctx)
6399 enddef
6400
6401 Test_GetResult()
6402 END
6403 v9.CheckSourceSuccess(lines)
6404enddef
6405
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006406" Test for duplicate object and class variable
6407def Test_duplicate_variable()
6408 # Object variable name is same as the class variable name
6409 var lines =<< trim END
6410 vim9script
6411 class A
6412 public static sval: number
6413 public this.sval: number
6414 endclass
6415 var a = A.new()
6416 END
6417 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6418
6419 # Duplicate variable name and calling a class method
6420 lines =<< trim END
6421 vim9script
6422 class A
6423 public static sval: number
6424 public this.sval: number
6425 def F1()
6426 echo this.sval
6427 enddef
6428 static def F2()
6429 echo sval
6430 enddef
6431 endclass
6432 A.F2()
6433 END
6434 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6435
6436 # Duplicate variable with an empty constructor
6437 lines =<< trim END
6438 vim9script
6439 class A
6440 public static sval: number
6441 public this.sval: number
6442 def new()
6443 enddef
6444 endclass
6445 var a = A.new()
6446 END
6447 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6448enddef
6449
6450" Test for using a reserved keyword as a variable name
6451def Test_reserved_varname()
6452 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6453 'null_function', 'null_list', 'null_partial', 'null_string',
6454 'null_channel', 'null_job', 'super', 'this']
6455
6456 var lines =<< trim eval END
6457 vim9script
6458 class C
6459 public this.{kword}: list<number> = [1, 2, 3]
6460 endclass
6461 var o = C.new()
6462 END
6463 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6464
6465 lines =<< trim eval END
6466 vim9script
6467 class C
6468 public this.{kword}: list<number> = [1, 2, 3]
6469 def new()
6470 enddef
6471 endclass
6472 var o = C.new()
6473 END
6474 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6475
6476 lines =<< trim eval END
6477 vim9script
6478 class C
6479 public this.{kword}: list<number> = [1, 2, 3]
6480 def new()
6481 enddef
6482 def F()
6483 echo this.{kword}
6484 enddef
6485 endclass
6486 var o = C.new()
6487 o.F()
6488 END
6489 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6490 endfor
6491enddef
6492
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006493" Test for checking the type of the arguments and the return value of a object
6494" method in an extended class.
6495def Test_extended_obj_method_type_check()
6496 var lines =<< trim END
6497 vim9script
6498
6499 class A
6500 endclass
6501 class B extends A
6502 endclass
6503 class C extends B
6504 endclass
6505
6506 class Foo
6507 def Doit(p: B): B
6508 return B.new()
6509 enddef
6510 endclass
6511
6512 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006513 def Doit(p: C): B
6514 return B.new()
6515 enddef
6516 endclass
6517 END
6518 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6519
6520 lines =<< trim END
6521 vim9script
6522
6523 class A
6524 endclass
6525 class B extends A
6526 endclass
6527 class C extends B
6528 endclass
6529
6530 class Foo
6531 def Doit(p: B): B
6532 return B.new()
6533 enddef
6534 endclass
6535
6536 class Bar extends Foo
6537 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006538 return C.new()
6539 enddef
6540 endclass
6541 END
6542 v9.CheckSourceSuccess(lines)
6543
6544 lines =<< trim END
6545 vim9script
6546
6547 class A
6548 endclass
6549 class B extends A
6550 endclass
6551 class C extends B
6552 endclass
6553
6554 class Foo
6555 def Doit(p: B): B
6556 return B.new()
6557 enddef
6558 endclass
6559
6560 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006561 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006562 return B.new()
6563 enddef
6564 endclass
6565 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006566 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 +02006567
6568 lines =<< trim END
6569 vim9script
6570
6571 class A
6572 endclass
6573 class B extends A
6574 endclass
6575 class C extends B
6576 endclass
6577
6578 class Foo
6579 def Doit(p: B): B
6580 return B.new()
6581 enddef
6582 endclass
6583
6584 class Bar extends Foo
6585 def Doit(p: B): A
6586 return A.new()
6587 enddef
6588 endclass
6589 END
6590 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
6591enddef
6592
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006593" Test type checking for class variable in assignments
6594func Test_class_variable_complex_type_check()
6595 " class variable with a specific type. Try assigning a different type at
6596 " script level.
6597 let lines =<< trim END
6598 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006599 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006600 return {}
6601 enddef
6602 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006603 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006604 endclass
6605 test_garbagecollect_now()
6606 A.Fn = "abc"
6607 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006608 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 +02006609
6610 " class variable with a specific type. Try assigning a different type at
6611 " class def method level.
6612 let lines =<< trim END
6613 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006614 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006615 return {}
6616 enddef
6617 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006618 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006619 def Bar()
6620 Fn = "abc"
6621 enddef
6622 endclass
6623 var a = A.new()
6624 test_garbagecollect_now()
6625 a.Bar()
6626 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006627 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 +02006628
6629 " class variable with a specific type. Try assigning a different type at
6630 " script def method level.
6631 let lines =<< trim END
6632 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006633 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006634 return {}
6635 enddef
6636 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006637 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006638 endclass
6639 def Bar()
6640 A.Fn = "abc"
6641 enddef
6642 test_garbagecollect_now()
6643 Bar()
6644 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006645 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 +02006646
6647 " class variable without any type. Should be set to the initialization
6648 " expression type. Try assigning a different type from script level.
6649 let lines =<< trim END
6650 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006651 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006652 return {}
6653 enddef
6654 class A
6655 public static Fn = Foo
6656 endclass
6657 test_garbagecollect_now()
6658 A.Fn = "abc"
6659 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006660 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 +02006661
6662 " class variable without any type. Should be set to the initialization
6663 " expression type. Try assigning a different type at class def level.
6664 let lines =<< trim END
6665 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006666 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006667 return {}
6668 enddef
6669 class A
6670 public static Fn = Foo
6671 def Bar()
6672 Fn = "abc"
6673 enddef
6674 endclass
6675 var a = A.new()
6676 test_garbagecollect_now()
6677 a.Bar()
6678 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006679 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 +02006680
6681 " class variable without any type. Should be set to the initialization
6682 " expression type. Try assigning a different type at script def level.
6683 let lines =<< trim END
6684 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006685 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006686 return {}
6687 enddef
6688 class A
6689 public static Fn = Foo
6690 endclass
6691 def Bar()
6692 A.Fn = "abc"
6693 enddef
6694 test_garbagecollect_now()
6695 Bar()
6696 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006697 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 +02006698
6699 " class variable with 'any" type. Can be assigned different types.
6700 let lines =<< trim END
6701 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006702 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006703 return {}
6704 enddef
6705 class A
6706 public static Fn: any = Foo
6707 public static Fn2: any
6708 endclass
6709 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006710 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006711 A.Fn = "abc"
6712 test_garbagecollect_now()
6713 assert_equal('string', typename(A.Fn))
6714 A.Fn2 = Foo
6715 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006716 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006717 A.Fn2 = "xyz"
6718 test_garbagecollect_now()
6719 assert_equal('string', typename(A.Fn2))
6720 END
6721 call v9.CheckSourceSuccess(lines)
6722
6723 " class variable with 'any" type. Can be assigned different types.
6724 let lines =<< trim END
6725 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006726 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006727 return {}
6728 enddef
6729 class A
6730 public static Fn: any = Foo
6731 public static Fn2: any
6732
6733 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006734 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006735 Fn = "abc"
6736 assert_equal('string', typename(Fn))
6737 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006738 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006739 Fn2 = "xyz"
6740 assert_equal('string', typename(Fn2))
6741 enddef
6742 endclass
6743 var a = A.new()
6744 test_garbagecollect_now()
6745 a.Bar()
6746 test_garbagecollect_now()
6747 A.Fn = Foo
6748 a.Bar()
6749 END
6750 call v9.CheckSourceSuccess(lines)
6751
6752 " class variable with 'any" type. Can be assigned different types.
6753 let lines =<< trim END
6754 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006755 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006756 return {}
6757 enddef
6758 class A
6759 public static Fn: any = Foo
6760 public static Fn2: any
6761 endclass
6762
6763 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006764 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006765 A.Fn = "abc"
6766 assert_equal('string', typename(A.Fn))
6767 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006768 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006769 A.Fn2 = "xyz"
6770 assert_equal('string', typename(A.Fn2))
6771 enddef
6772 Bar()
6773 test_garbagecollect_now()
6774 A.Fn = Foo
6775 Bar()
6776 END
6777 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006778
6779 let lines =<< trim END
6780 vim9script
6781 class A
6782 public static foo = [0z10, 0z20]
6783 endclass
6784 assert_equal([0z10, 0z20], A.foo)
6785 A.foo = [0z30]
6786 assert_equal([0z30], A.foo)
6787 var a = A.foo
6788 assert_equal([0z30], a)
6789 END
6790 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006791endfunc
6792
6793" Test type checking for object variable in assignments
6794func Test_object_variable_complex_type_check()
6795 " object variable with a specific type. Try assigning a different type at
6796 " script level.
6797 let lines =<< trim END
6798 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006799 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006800 return {}
6801 enddef
6802 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006803 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006804 endclass
6805 var a = A.new()
6806 test_garbagecollect_now()
6807 a.Fn = "abc"
6808 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006809 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 +02006810
6811 " object variable with a specific type. Try assigning a different type at
6812 " object def method level.
6813 let lines =<< trim END
6814 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006815 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006816 return {}
6817 enddef
6818 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006819 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006820 def Bar()
6821 this.Fn = "abc"
6822 this.Fn = Foo
6823 enddef
6824 endclass
6825 var a = A.new()
6826 test_garbagecollect_now()
6827 a.Bar()
6828 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006829 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 +02006830
6831 " object variable with a specific type. Try assigning a different type at
6832 " script def method level.
6833 let lines =<< trim END
6834 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006835 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006836 return {}
6837 enddef
6838 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006839 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006840 endclass
6841 def Bar()
6842 var a = A.new()
6843 a.Fn = "abc"
6844 a.Fn = Foo
6845 enddef
6846 test_garbagecollect_now()
6847 Bar()
6848 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006849 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 +02006850
6851 " object variable without any type. Should be set to the initialization
6852 " expression type. Try assigning a different type from script level.
6853 let lines =<< trim END
6854 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006855 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006856 return {}
6857 enddef
6858 class A
6859 public this.Fn = Foo
6860 endclass
6861 var a = A.new()
6862 test_garbagecollect_now()
6863 a.Fn = "abc"
6864 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006865 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 +02006866
6867 " object variable without any type. Should be set to the initialization
6868 " expression type. Try assigning a different type at object def level.
6869 let lines =<< trim END
6870 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006871 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006872 return {}
6873 enddef
6874 class A
6875 public this.Fn = Foo
6876 def Bar()
6877 this.Fn = "abc"
6878 this.Fn = Foo
6879 enddef
6880 endclass
6881 var a = A.new()
6882 test_garbagecollect_now()
6883 a.Bar()
6884 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006885 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 +02006886
6887 " object variable without any type. Should be set to the initialization
6888 " expression type. Try assigning a different type at script def level.
6889 let lines =<< trim END
6890 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006891 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006892 return {}
6893 enddef
6894 class A
6895 public this.Fn = Foo
6896 endclass
6897 def Bar()
6898 var a = A.new()
6899 a.Fn = "abc"
6900 a.Fn = Foo
6901 enddef
6902 test_garbagecollect_now()
6903 Bar()
6904 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006905 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 +02006906
6907 " object variable with 'any" type. Can be assigned different types.
6908 let lines =<< trim END
6909 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006910 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006911 return {}
6912 enddef
6913 class A
6914 public this.Fn: any = Foo
6915 public this.Fn2: any
6916 endclass
6917
6918 var a = A.new()
6919 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006920 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006921 a.Fn = "abc"
6922 test_garbagecollect_now()
6923 assert_equal('string', typename(a.Fn))
6924 a.Fn2 = Foo
6925 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006926 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006927 a.Fn2 = "xyz"
6928 test_garbagecollect_now()
6929 assert_equal('string', typename(a.Fn2))
6930 END
6931 call v9.CheckSourceSuccess(lines)
6932
6933 " object variable with 'any" type. Can be assigned different types.
6934 let lines =<< trim END
6935 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006936 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006937 return {}
6938 enddef
6939 class A
6940 public this.Fn: any = Foo
6941 public this.Fn2: any
6942
6943 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006944 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006945 this.Fn = "abc"
6946 assert_equal('string', typename(this.Fn))
6947 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006948 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006949 this.Fn2 = "xyz"
6950 assert_equal('string', typename(this.Fn2))
6951 enddef
6952 endclass
6953
6954 var a = A.new()
6955 test_garbagecollect_now()
6956 a.Bar()
6957 test_garbagecollect_now()
6958 a.Fn = Foo
6959 a.Bar()
6960 END
6961 call v9.CheckSourceSuccess(lines)
6962
6963 " object variable with 'any" type. Can be assigned different types.
6964 let lines =<< trim END
6965 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006966 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006967 return {}
6968 enddef
6969 class A
6970 public this.Fn: any = Foo
6971 public this.Fn2: any
6972 endclass
6973
6974 def Bar()
6975 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006976 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006977 a.Fn = "abc"
6978 assert_equal('string', typename(a.Fn))
6979 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006980 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006981 a.Fn2 = "xyz"
6982 assert_equal('string', typename(a.Fn2))
6983 enddef
6984 test_garbagecollect_now()
6985 Bar()
6986 test_garbagecollect_now()
6987 Bar()
6988 END
6989 call v9.CheckSourceSuccess(lines)
6990endfunc
6991
Bram Moolenaar00b28d62022-12-08 15:32:33 +00006992" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker