blob: 555c46cc8e867f0d7a16a442a1ae2543714b971f [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
Ernie Rael9771b2a2023-10-07 22:05:40 +02004164" Test builtin islocked()
4165def Test_lockvar_islocked()
4166 # Can't lock class/object variable
4167 # Lock class/object variable's value
4168 # Lock item of variabl's value (a list item)
4169 # varible is at index 1 within class/object
4170 var lines =<< trim END
4171 vim9script
4172
4173 class C
4174 this.o0: list<list<number>> = [ [0], [1], [2]]
4175 this.o1: list<list<number>> = [[10], [11], [12]]
4176 static c0: list<list<number>> = [[20], [21], [22]]
4177 static c1: list<list<number>> = [[30], [31], [32]]
4178 endclass
4179
4180 def LockIt(arg: any)
4181 lockvar arg
4182 enddef
4183
4184 def UnlockIt(arg: any)
4185 unlockvar arg
4186 enddef
4187
4188 var obj = C.new()
4189 #lockvar obj.o1 # can't lock something you can't write to
4190
4191 try
4192 lockvar obj.o1 # can't lock something you can't write to
4193 call assert_false(1, '"lockvar obj.o1" should have failed')
4194 catch
4195 call assert_exception('E1335:')
4196 endtry
4197
4198 LockIt(obj.o1) # but can lock it's value
4199 assert_equal(1, islocked("obj.o1"))
4200 assert_equal(1, islocked("obj.o1[0]"))
4201 assert_equal(1, islocked("obj.o1[1]"))
4202 UnlockIt(obj.o1)
4203 assert_equal(0, islocked("obj.o1"))
4204 assert_equal(0, islocked("obj.o1[0]"))
4205
4206 lockvar obj.o1[0]
4207 assert_equal(0, islocked("obj.o1"))
4208 assert_equal(1, islocked("obj.o1[0]"))
4209 assert_equal(0, islocked("obj.o1[1]"))
4210 unlockvar obj.o1[0]
4211 assert_equal(0, islocked("obj.o1"))
4212 assert_equal(0, islocked("obj.o1[0]"))
4213
4214 # Same thing, but with a static
4215
4216 try
4217 lockvar C.c1 # can't lock something you can't write to
4218 call assert_false(1, '"lockvar C.c1" should have failed')
4219 catch
4220 call assert_exception('E1335:')
4221 endtry
4222
4223 LockIt(C.c1) # but can lock it's value
4224 assert_equal(1, islocked("C.c1"))
4225 assert_equal(1, islocked("C.c1[0]"))
4226 assert_equal(1, islocked("C.c1[1]"))
4227 UnlockIt(C.c1)
4228 assert_equal(0, islocked("C.c1"))
4229 assert_equal(0, islocked("C.c1[0]"))
4230
4231 lockvar C.c1[0]
4232 assert_equal(0, islocked("C.c1"))
4233 assert_equal(1, islocked("C.c1[0]"))
4234 assert_equal(0, islocked("C.c1[1]"))
4235 unlockvar C.c1[0]
4236 assert_equal(0, islocked("C.c1"))
4237 assert_equal(0, islocked("C.c1[0]"))
4238 END
4239 v9.CheckSourceSuccess(lines)
4240 lines =<< trim END
4241 END
4242enddef
4243
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004244" Test for a private object method
4245def Test_private_object_method()
4246 # Try calling a private method using an object (at the script level)
4247 var lines =<< trim END
4248 vim9script
4249
4250 class A
4251 def _Foo(): number
4252 return 1234
4253 enddef
4254 endclass
4255 var a = A.new()
4256 a._Foo()
4257 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004258 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004259
4260 # Try calling a private method using an object (from a def function)
4261 lines =<< trim END
4262 vim9script
4263
4264 class A
4265 def _Foo(): number
4266 return 1234
4267 enddef
4268 endclass
4269 def T()
4270 var a = A.new()
4271 a._Foo()
4272 enddef
4273 T()
4274 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004275 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004276
4277 # Use a private method from another object method (in script context)
4278 lines =<< trim END
4279 vim9script
4280
4281 class A
4282 def _Foo(): number
4283 return 1234
4284 enddef
4285 def Bar(): number
4286 return this._Foo()
4287 enddef
4288 endclass
4289 var a = A.new()
4290 assert_equal(1234, a.Bar())
4291 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004292 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004293
4294 # Use a private method from another object method (def function context)
4295 lines =<< trim END
4296 vim9script
4297
4298 class A
4299 def _Foo(): number
4300 return 1234
4301 enddef
4302 def Bar(): number
4303 return this._Foo()
4304 enddef
4305 endclass
4306 def T()
4307 var a = A.new()
4308 assert_equal(1234, a.Bar())
4309 enddef
4310 T()
4311 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004312 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004313
4314 # Try calling a private method without the "this" prefix
4315 lines =<< trim END
4316 vim9script
4317
4318 class A
4319 def _Foo(): number
4320 return 1234
4321 enddef
4322 def Bar(): number
4323 return _Foo()
4324 enddef
4325 endclass
4326 var a = A.new()
4327 a.Bar()
4328 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004329 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004330
4331 # Try calling a private method using the class name
4332 lines =<< trim END
4333 vim9script
4334
4335 class A
4336 def _Foo(): number
4337 return 1234
4338 enddef
4339 endclass
4340 A._Foo()
4341 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004342 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004343
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004344 # Define two private methods with the same name
4345 lines =<< trim END
4346 vim9script
4347
4348 class A
4349 def _Foo()
4350 enddef
4351 def _Foo()
4352 enddef
4353 endclass
4354 var a = A.new()
4355 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004356 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004357
4358 # Define a private method and a object method with the same name
4359 lines =<< trim END
4360 vim9script
4361
4362 class A
4363 def _Foo()
4364 enddef
4365 def Foo()
4366 enddef
4367 endclass
4368 var a = A.new()
4369 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004370 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004371
4372 # Define an object method and a private method with the same name
4373 lines =<< trim END
4374 vim9script
4375
4376 class A
4377 def Foo()
4378 enddef
4379 def _Foo()
4380 enddef
4381 endclass
4382 var a = A.new()
4383 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004384 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004385
4386 # Call a public method and a private method from a private method
4387 lines =<< trim END
4388 vim9script
4389
4390 class A
4391 def Foo(): number
4392 return 100
4393 enddef
4394 def _Bar(): number
4395 return 200
4396 enddef
4397 def _Baz()
4398 assert_equal(100, this.Foo())
4399 assert_equal(200, this._Bar())
4400 enddef
4401 def T()
4402 this._Baz()
4403 enddef
4404 endclass
4405 var a = A.new()
4406 a.T()
4407 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004408 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004409
4410 # Try calling a private method from another class
4411 lines =<< trim END
4412 vim9script
4413
4414 class A
4415 def _Foo(): number
4416 return 100
4417 enddef
4418 endclass
4419 class B
4420 def Foo(): number
4421 var a = A.new()
4422 a._Foo()
4423 enddef
4424 endclass
4425 var b = B.new()
4426 b.Foo()
4427 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004428 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004429
4430 # Call a private object method from a child class object method
4431 lines =<< trim END
4432 vim9script
4433 class A
4434 def _Foo(): number
4435 return 1234
4436 enddef
4437 endclass
4438 class B extends A
4439 def Bar()
4440 enddef
4441 endclass
4442 class C extends B
4443 def Baz(): number
4444 return this._Foo()
4445 enddef
4446 endclass
4447 var c = C.new()
4448 assert_equal(1234, c.Baz())
4449 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004450 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004451
4452 # Call a private object method from a child class object
4453 lines =<< trim END
4454 vim9script
4455 class A
4456 def _Foo(): number
4457 return 1234
4458 enddef
4459 endclass
4460 class B extends A
4461 def Bar()
4462 enddef
4463 endclass
4464 class C extends B
4465 def Baz(): number
4466 enddef
4467 endclass
4468 var c = C.new()
4469 assert_equal(1234, c._Foo())
4470 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004471 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004472
4473 # Using "_" prefix in a method name should fail outside of a class
4474 lines =<< trim END
4475 vim9script
4476 def _Foo(): number
4477 return 1234
4478 enddef
4479 var a = _Foo()
4480 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004481 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004482enddef
4483
4484" Test for an private class method
4485def Test_private_class_method()
4486 # Try calling a class private method (at the script level)
4487 var lines =<< trim END
4488 vim9script
4489
4490 class A
4491 static def _Foo(): number
4492 return 1234
4493 enddef
4494 endclass
4495 A._Foo()
4496 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004497 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004498
4499 # Try calling a class private method (from a def function)
4500 lines =<< trim END
4501 vim9script
4502
4503 class A
4504 static def _Foo(): number
4505 return 1234
4506 enddef
4507 endclass
4508 def T()
4509 A._Foo()
4510 enddef
4511 T()
4512 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004513 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004514
4515 # Try calling a class private method using an object (at the script level)
4516 lines =<< trim END
4517 vim9script
4518
4519 class A
4520 static def _Foo(): number
4521 return 1234
4522 enddef
4523 endclass
4524 var a = A.new()
4525 a._Foo()
4526 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004527 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004528
4529 # Try calling a class private method using an object (from a def function)
4530 lines =<< trim END
4531 vim9script
4532
4533 class A
4534 static def _Foo(): number
4535 return 1234
4536 enddef
4537 endclass
4538 def T()
4539 var a = A.new()
4540 a._Foo()
4541 enddef
4542 T()
4543 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004544 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004545
4546 # Use a class private method from an object method
4547 lines =<< trim END
4548 vim9script
4549
4550 class A
4551 static def _Foo(): number
4552 return 1234
4553 enddef
4554 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004555 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004556 enddef
4557 endclass
4558 var a = A.new()
4559 a.Bar()
4560 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004561 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004562
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004563 # Use a class private method from another class private method without the
4564 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004565 lines =<< trim END
4566 vim9script
4567
4568 class A
4569 static def _Foo1(): number
4570 return 1234
4571 enddef
4572 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004573 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004574 enddef
4575 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004576 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004577 enddef
4578 endclass
4579 var a = A.new()
4580 a.Bar()
4581 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004582 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004583
4584 # Declare a class method and a class private method with the same name
4585 lines =<< trim END
4586 vim9script
4587
4588 class A
4589 static def _Foo()
4590 enddef
4591 static def Foo()
4592 enddef
4593 endclass
4594 var a = A.new()
4595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004596 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004597
4598 # Try calling a class private method from another class
4599 lines =<< trim END
4600 vim9script
4601
4602 class A
4603 static def _Foo(): number
4604 return 1234
4605 enddef
4606 endclass
4607 class B
4608 def Foo(): number
4609 return A._Foo()
4610 enddef
4611 endclass
4612 var b = B.new()
4613 assert_equal(1234, b.Foo())
4614 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004615 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004616
4617 # Call a private class method from a child class object method
4618 lines =<< trim END
4619 vim9script
4620 class A
4621 static def _Foo(): number
4622 return 1234
4623 enddef
4624 endclass
4625 class B extends A
4626 def Bar()
4627 enddef
4628 endclass
4629 class C extends B
4630 def Baz(): number
4631 return A._Foo()
4632 enddef
4633 endclass
4634 var c = C.new()
4635 assert_equal(1234, c.Baz())
4636 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004637 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004638
4639 # Call a private class method from a child class private class method
4640 lines =<< trim END
4641 vim9script
4642 class A
4643 static def _Foo(): number
4644 return 1234
4645 enddef
4646 endclass
4647 class B extends A
4648 def Bar()
4649 enddef
4650 endclass
4651 class C extends B
4652 static def Baz(): number
4653 return A._Foo()
4654 enddef
4655 endclass
4656 assert_equal(1234, C.Baz())
4657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004658 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004659
4660 # Call a private class method from a child class object
4661 lines =<< trim END
4662 vim9script
4663 class A
4664 static def _Foo(): number
4665 return 1234
4666 enddef
4667 endclass
4668 class B extends A
4669 def Bar()
4670 enddef
4671 endclass
4672 class C extends B
4673 def Baz(): number
4674 enddef
4675 endclass
4676 var c = C.new()
4677 assert_equal(1234, C._Foo())
4678 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004679 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004680enddef
4681
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004682" Test for using the return value of a class/object method as a function
4683" argument.
4684def Test_objmethod_funcarg()
4685 var lines =<< trim END
4686 vim9script
4687
4688 class C
4689 def Foo(): string
4690 return 'foo'
4691 enddef
4692 endclass
4693
4694 def Bar(a: number, s: string): string
4695 return s
4696 enddef
4697
4698 def Baz(c: C)
4699 assert_equal('foo', Bar(10, c.Foo()))
4700 enddef
4701
4702 var t = C.new()
4703 Baz(t)
4704 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004705 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004706
4707 lines =<< trim END
4708 vim9script
4709
4710 class C
4711 static def Foo(): string
4712 return 'foo'
4713 enddef
4714 endclass
4715
4716 def Bar(a: number, s: string): string
4717 return s
4718 enddef
4719
4720 def Baz()
4721 assert_equal('foo', Bar(10, C.Foo()))
4722 enddef
4723
4724 Baz()
4725 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004726 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004727enddef
4728
Ernie Raelcf138d42023-09-06 20:45:03 +02004729def Test_static_inheritence()
4730 # subclasses get their own static copy
4731 var lines =<< trim END
4732 vim9script
4733
4734 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004735 static _svar: number
4736 this._mvar: number
4737 def new()
4738 _svar = 1
4739 this._mvar = 101
4740 enddef
4741 def AccessObject(): number
4742 return this._mvar
4743 enddef
4744 def AccessStaticThroughObject(): number
4745 return _svar
4746 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004747 endclass
4748
4749 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004750 def new()
4751 this._mvar = 102
4752 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004753 endclass
4754
4755 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004756 def new()
4757 this._mvar = 103
4758 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004759
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004760 def AccessPrivateStaticThroughClassName(): number
4761 assert_equal(1, A._svar)
4762 return 444
4763 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004764 endclass
4765
4766 var oa = A.new()
4767 var ob = B.new()
4768 var oc = C.new()
4769 assert_equal(101, oa.AccessObject())
4770 assert_equal(102, ob.AccessObject())
4771 assert_equal(103, oc.AccessObject())
4772
Ernie Rael64885642023-10-04 20:16:22 +02004773 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02004774
4775 # verify object properly resolves to correct static
4776 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004777 assert_equal(1, ob.AccessStaticThroughObject())
4778 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02004779 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004780 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02004781enddef
4782
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004783" Test for declaring duplicate object and class members
4784def Test_dup_member_variable()
4785 # Duplicate member variable
4786 var lines =<< trim END
4787 vim9script
4788 class C
4789 this.val = 10
4790 this.val = 20
4791 endclass
4792 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004793 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004794
4795 # Duplicate private member variable
4796 lines =<< trim END
4797 vim9script
4798 class C
4799 this._val = 10
4800 this._val = 20
4801 endclass
4802 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004803 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004804
4805 # Duplicate public member variable
4806 lines =<< trim END
4807 vim9script
4808 class C
4809 public this.val = 10
4810 public this.val = 20
4811 endclass
4812 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004813 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004814
4815 # Duplicate private member variable
4816 lines =<< trim END
4817 vim9script
4818 class C
4819 this.val = 10
4820 this._val = 20
4821 endclass
4822 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004823 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004824
4825 # Duplicate public and private member variable
4826 lines =<< trim END
4827 vim9script
4828 class C
4829 this._val = 20
4830 public this.val = 10
4831 endclass
4832 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004833 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004834
4835 # Duplicate class member variable
4836 lines =<< trim END
4837 vim9script
4838 class C
4839 static s: string = "abc"
4840 static _s: string = "def"
4841 endclass
4842 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004843 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004844
4845 # Duplicate public and private class member variable
4846 lines =<< trim END
4847 vim9script
4848 class C
4849 public static s: string = "abc"
4850 static _s: string = "def"
4851 endclass
4852 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004853 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004854
4855 # Duplicate class and object member variable
4856 lines =<< trim END
4857 vim9script
4858 class C
4859 static val = 10
4860 this.val = 20
4861 def new()
4862 enddef
4863 endclass
4864 var c = C.new()
4865 assert_equal(10, C.val)
4866 assert_equal(20, c.val)
4867 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02004868 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004869
4870 # Duplicate object member variable in a derived class
4871 lines =<< trim END
4872 vim9script
4873 class A
4874 this.val = 10
4875 endclass
4876 class B extends A
4877 endclass
4878 class C extends B
4879 this.val = 20
4880 endclass
4881 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004882 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004883
4884 # Duplicate object private member variable in a derived class
4885 lines =<< trim END
4886 vim9script
4887 class A
4888 this._val = 10
4889 endclass
4890 class B extends A
4891 endclass
4892 class C extends B
4893 this._val = 20
4894 endclass
4895 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004896 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004897
4898 # Duplicate object private member variable in a derived class
4899 lines =<< trim END
4900 vim9script
4901 class A
4902 this.val = 10
4903 endclass
4904 class B extends A
4905 endclass
4906 class C extends B
4907 this._val = 20
4908 endclass
4909 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004910 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004911
4912 # Duplicate object member variable in a derived class
4913 lines =<< trim END
4914 vim9script
4915 class A
4916 this._val = 10
4917 endclass
4918 class B extends A
4919 endclass
4920 class C extends B
4921 this.val = 20
4922 endclass
4923 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004924 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004925
4926 # Two member variables with a common prefix
4927 lines =<< trim END
4928 vim9script
4929 class A
4930 public static svar2: number
4931 public static svar: number
4932 endclass
4933 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004934 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004935enddef
4936
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004937" Test for accessing a private member outside a class in a def function
4938def Test_private_member_access_outside_class()
4939 # private object member variable
4940 var lines =<< trim END
4941 vim9script
4942 class A
4943 this._val = 10
4944 def GetVal(): number
4945 return this._val
4946 enddef
4947 endclass
4948 def T()
4949 var a = A.new()
4950 a._val = 20
4951 enddef
4952 T()
4953 END
Ernie Rael64885642023-10-04 20:16:22 +02004954 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004955
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004956 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004957 lines =<< trim END
4958 vim9script
4959 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004960 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004961 endclass
4962 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004963 var a = A.new()
4964 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004965 enddef
4966 T()
4967 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004968 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004969
4970 # private static member variable
4971 lines =<< trim END
4972 vim9script
4973 class A
4974 static _val = 10
4975 endclass
4976 def T()
4977 var a = A.new()
4978 var x = a._val
4979 enddef
4980 T()
4981 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004982 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004983
4984 # private static member variable
4985 lines =<< trim END
4986 vim9script
4987 class A
4988 static _val = 10
4989 endclass
4990 def T()
4991 var a = A.new()
4992 a._val = 3
4993 enddef
4994 T()
4995 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004996 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004997
4998 # private static class variable
4999 lines =<< trim END
5000 vim9script
5001 class A
5002 static _val = 10
5003 endclass
5004 def T()
5005 var x = A._val
5006 enddef
5007 T()
5008 END
Ernie Rael64885642023-10-04 20:16:22 +02005009 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005010
5011 # private static class variable
5012 lines =<< trim END
5013 vim9script
5014 class A
5015 static _val = 10
5016 endclass
5017 def T()
5018 A._val = 3
5019 enddef
5020 T()
5021 END
Ernie Rael64885642023-10-04 20:16:22 +02005022 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005023enddef
5024
5025" Test for changing the member access of an interface in a implementation class
5026def Test_change_interface_member_access()
5027 var lines =<< trim END
5028 vim9script
5029 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005030 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005031 endinterface
5032 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005033 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005034 endclass
5035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005036 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005037
5038 lines =<< trim END
5039 vim9script
5040 interface A
5041 this.val: number
5042 endinterface
5043 class B implements A
5044 public this.val = 10
5045 endclass
5046 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005047 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005048enddef
5049
5050" Test for trying to change a readonly member from a def function
5051def Test_readonly_member_change_in_def_func()
5052 var lines =<< trim END
5053 vim9script
5054 class A
5055 this.val: number
5056 endclass
5057 def T()
5058 var a = A.new()
5059 a.val = 20
5060 enddef
5061 T()
5062 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005063 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005064enddef
5065
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005066" Test for reading and writing a class member from a def function
5067def Test_modify_class_member_from_def_function()
5068 var lines =<< trim END
5069 vim9script
5070 class A
5071 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005072 public static var2: list<number> = [1, 2]
5073 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005074 static _priv_var4: number = 40
5075 endclass
5076 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005077 assert_equal([1, 2], A.var2)
5078 assert_equal({a: 1, b: 2}, A.var3)
5079 A.var2 = [3, 4]
5080 A.var3 = {c: 3, d: 4}
5081 assert_equal([3, 4], A.var2)
5082 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael64885642023-10-04 20:16:22 +02005083 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005084 enddef
5085 T()
5086 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005087 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005088enddef
5089
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005090" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005091def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005092 var lines =<< trim END
5093 vim9script
5094 class A
5095 public static svar1: list<number> = [1]
5096 public static svar2: list<number> = [2]
5097 endclass
5098
5099 A.svar1->add(3)
5100 A.svar2->add(4)
5101 assert_equal([1, 3], A.svar1)
5102 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005103
5104 def Foo()
5105 A.svar1->add(7)
5106 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005107 assert_equal([1, 3, 7], A.svar1)
5108 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005109 enddef
5110 Foo()
5111 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005112 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005113
5114 # Cannot read from a class variable using an object in script context
5115 lines =<< trim END
5116 vim9script
5117 class A
5118 public this.var1: number
5119 public static svar2: list<number> = [1]
5120 endclass
5121
5122 var a = A.new()
5123 echo a.svar2
5124 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005125 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005126
5127 # Cannot write to a class variable using an object in script context
5128 lines =<< trim END
5129 vim9script
5130 class A
5131 public this.var1: number
5132 public static svar2: list<number> = [1]
5133 endclass
5134
5135 var a = A.new()
5136 a.svar2 = [2]
5137 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005138 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005139
5140 # Cannot read from a class variable using an object in def method context
5141 lines =<< trim END
5142 vim9script
5143 class A
5144 public this.var1: number
5145 public static svar2: list<number> = [1]
5146 endclass
5147
5148 def T()
5149 var a = A.new()
5150 echo a.svar2
5151 enddef
5152 T()
5153 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005154 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005155
5156 # Cannot write to a class variable using an object in def method context
5157 lines =<< trim END
5158 vim9script
5159 class A
5160 public this.var1: number
5161 public static svar2: list<number> = [1]
5162 endclass
5163
5164 def T()
5165 var a = A.new()
5166 a.svar2 = [2]
5167 enddef
5168 T()
5169 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005170 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005171enddef
5172
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005173" Test for using a interface method using a child object
5174def Test_interface_method_from_child()
5175 var lines =<< trim END
5176 vim9script
5177
5178 interface A
5179 def Foo(): string
5180 endinterface
5181
5182 class B implements A
5183 def Foo(): string
5184 return 'foo'
5185 enddef
5186 endclass
5187
5188 class C extends B
5189 def Bar(): string
5190 return 'bar'
5191 enddef
5192 endclass
5193
5194 def T1(a: A)
5195 assert_equal('foo', a.Foo())
5196 enddef
5197
5198 def T2(b: B)
5199 assert_equal('foo', b.Foo())
5200 enddef
5201
5202 var c = C.new()
5203 T1(c)
5204 T2(c)
5205 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005206 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005207enddef
5208
5209" Test for using an interface method using a child object when it is overridden
5210" by the child class.
5211" FIXME: This test fails.
5212" def Test_interface_overridden_method_from_child()
5213" var lines =<< trim END
5214" vim9script
5215"
5216" interface A
5217" def Foo(): string
5218" endinterface
5219"
5220" class B implements A
5221" def Foo(): string
5222" return 'b-foo'
5223" enddef
5224" endclass
5225"
5226" class C extends B
5227" def Bar(): string
5228" return 'bar'
5229" enddef
5230" def Foo(): string
5231" return 'c-foo'
5232" enddef
5233" endclass
5234"
5235" def T1(a: A)
5236" assert_equal('c-foo', a.Foo())
5237" enddef
5238"
5239" def T2(b: B)
5240" assert_equal('c-foo', b.Foo())
5241" enddef
5242"
5243" var c = C.new()
5244" T1(c)
5245" T2(c)
5246" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005247" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005248" enddef
5249
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005250" Test for abstract methods
5251def Test_abstract_method()
5252 # Use two abstract methods
5253 var lines =<< trim END
5254 vim9script
5255 abstract class A
5256 def M1(): number
5257 return 10
5258 enddef
5259 abstract def M2(): number
5260 abstract def M3(): number
5261 endclass
5262 class B extends A
5263 def M2(): number
5264 return 20
5265 enddef
5266 def M3(): number
5267 return 30
5268 enddef
5269 endclass
5270 var b = B.new()
5271 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5272 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005273 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005274
5275 # Don't define an abstract method
5276 lines =<< trim END
5277 vim9script
5278 abstract class A
5279 abstract def Foo()
5280 endclass
5281 class B extends A
5282 endclass
5283 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005284 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005285
5286 # Use abstract method in a concrete class
5287 lines =<< trim END
5288 vim9script
5289 class A
5290 abstract def Foo()
5291 endclass
5292 class B extends A
5293 endclass
5294 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005295 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005296
5297 # Use abstract method in an interface
5298 lines =<< trim END
5299 vim9script
5300 interface A
5301 abstract def Foo()
5302 endinterface
5303 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005304 def Foo()
5305 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005306 endclass
5307 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005308 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005309
5310 # Abbreviate the "abstract" keyword
5311 lines =<< trim END
5312 vim9script
5313 class A
5314 abs def Foo()
5315 endclass
5316 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005317 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005318
5319 # Use "abstract" with a member variable
5320 lines =<< trim END
5321 vim9script
5322 abstract class A
5323 abstract this.val = 10
5324 endclass
5325 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005326 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005327
5328 # Use a static abstract method
5329 lines =<< trim END
5330 vim9script
5331 abstract class A
5332 abstract static def Foo(): number
5333 endclass
5334 class B extends A
5335 static def Foo(): number
5336 return 4
5337 enddef
5338 endclass
5339 assert_equal(4, B.Foo())
5340 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005341 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005342
5343 # Type mismatch between abstract method and concrete method
5344 lines =<< trim END
5345 vim9script
5346 abstract class A
5347 abstract def Foo(a: string, b: number): list<number>
5348 endclass
5349 class B extends A
5350 def Foo(a: number, b: string): list<string>
5351 return []
5352 enddef
5353 endclass
5354 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005355 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 +02005356
5357 # Use an abstract class to invoke an abstract method
5358 # FIXME: This should fail
5359 lines =<< trim END
5360 vim9script
5361 abstract class A
5362 abstract static def Foo()
5363 endclass
5364 A.Foo()
5365 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005366 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005367
5368 # Invoke an abstract method from a def function
5369 lines =<< trim END
5370 vim9script
5371 abstract class A
5372 abstract def Foo(): list<number>
5373 endclass
5374 class B extends A
5375 def Foo(): list<number>
5376 return [3, 5]
5377 enddef
5378 endclass
5379 def Bar(c: B)
5380 assert_equal([3, 5], c.Foo())
5381 enddef
5382 var b = B.new()
5383 Bar(b)
5384 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005385 v9.CheckSourceSuccess(lines)
5386enddef
5387
5388" Test for calling a class method from a subclass
5389def Test_class_method_call_from_subclass()
5390 # class method call from a subclass
5391 var lines =<< trim END
5392 vim9script
5393
5394 class A
5395 static def Foo()
5396 echo "foo"
5397 enddef
5398 endclass
5399
5400 class B extends A
5401 def Bar()
5402 Foo()
5403 enddef
5404 endclass
5405
5406 var b = B.new()
5407 b.Bar()
5408 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005409 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005410enddef
5411
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005412" Test for calling a class method using an object in a def function context and
5413" script context.
5414def Test_class_method_call_using_object()
5415 # script context
5416 var lines =<< trim END
5417 vim9script
5418 class A
5419 static def Foo(): list<string>
5420 return ['a', 'b']
5421 enddef
5422 def Bar()
5423 assert_equal(['a', 'b'], A.Foo())
5424 assert_equal(['a', 'b'], Foo())
5425 enddef
5426 endclass
5427
5428 def T()
5429 assert_equal(['a', 'b'], A.Foo())
5430 var t_a = A.new()
5431 t_a.Bar()
5432 enddef
5433
5434 assert_equal(['a', 'b'], A.Foo())
5435 var a = A.new()
5436 a.Bar()
5437 T()
5438 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005439 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005440
5441 # script context
5442 lines =<< trim END
5443 vim9script
5444 class A
5445 static def Foo(): string
5446 return 'foo'
5447 enddef
5448 endclass
5449
5450 var a = A.new()
5451 assert_equal('foo', a.Foo())
5452 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005453 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005454
5455 # def function context
5456 lines =<< trim END
5457 vim9script
5458 class A
5459 static def Foo(): string
5460 return 'foo'
5461 enddef
5462 endclass
5463
5464 def T()
5465 var a = A.new()
5466 assert_equal('foo', a.Foo())
5467 enddef
5468 T()
5469 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005470 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005471enddef
5472
5473def Test_class_variable()
5474 var lines =<< trim END
5475 vim9script
5476
5477 class A
5478 public static val: number = 10
5479 static def ClassFunc()
5480 assert_equal(10, val)
5481 enddef
5482 def ObjFunc()
5483 assert_equal(10, val)
5484 enddef
5485 endclass
5486
5487 class B extends A
5488 endclass
5489
5490 assert_equal(10, A.val)
5491 A.ClassFunc()
5492 var a = A.new()
5493 a.ObjFunc()
5494 var b = B.new()
5495 b.ObjFunc()
5496
5497 def T1(a1: A)
5498 a1.ObjFunc()
5499 A.ClassFunc()
5500 enddef
5501 T1(b)
5502
5503 A.val = 20
5504 assert_equal(20, A.val)
5505 END
5506 v9.CheckSourceSuccess(lines)
5507
5508 # Modifying a parent class variable from a child class method
5509 lines =<< trim END
5510 vim9script
5511
5512 class A
5513 static val: number = 10
5514 endclass
5515
5516 class B extends A
5517 static def ClassFunc()
5518 val = 20
5519 enddef
5520 endclass
5521 B.ClassFunc()
5522 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005523 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005524
5525 # Reading a parent class variable from a child class method
5526 lines =<< trim END
5527 vim9script
5528
5529 class A
5530 static val: number = 10
5531 endclass
5532
5533 class B extends A
5534 static def ClassFunc()
5535 var i = val
5536 enddef
5537 endclass
5538 B.ClassFunc()
5539 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005540 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005541
5542 # Modifying a parent class variable from a child object method
5543 lines =<< trim END
5544 vim9script
5545
5546 class A
5547 static val: number = 10
5548 endclass
5549
5550 class B extends A
5551 def ObjFunc()
5552 val = 20
5553 enddef
5554 endclass
5555 var b = B.new()
5556 b.ObjFunc()
5557 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005558 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005559
5560 # Reading a parent class variable from a child object method
5561 lines =<< trim END
5562 vim9script
5563
5564 class A
5565 static val: number = 10
5566 endclass
5567
5568 class B extends A
5569 def ObjFunc()
5570 var i = val
5571 enddef
5572 endclass
5573 var b = B.new()
5574 b.ObjFunc()
5575 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005576 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005577
5578 # Modifying a class variable using an object at script level
5579 lines =<< trim END
5580 vim9script
5581
5582 class A
5583 static val: number = 10
5584 endclass
5585 var a = A.new()
5586 a.val = 20
5587 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005588 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005589
5590 # Reading a class variable using an object at script level
5591 lines =<< trim END
5592 vim9script
5593
5594 class A
5595 static val: number = 10
5596 endclass
5597 var a = A.new()
5598 var i = a.val
5599 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005600 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005601
5602 # Modifying a class variable using an object at function level
5603 lines =<< trim END
5604 vim9script
5605
5606 class A
5607 static val: number = 10
5608 endclass
5609
5610 def T()
5611 var a = A.new()
5612 a.val = 20
5613 enddef
5614 T()
5615 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005616 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005617
5618 # Reading a class variable using an object at function level
5619 lines =<< trim END
5620 vim9script
5621
5622 class A
5623 static val: number = 10
5624 endclass
5625 def T()
5626 var a = A.new()
5627 var i = a.val
5628 enddef
5629 T()
5630 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005631 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005632enddef
5633
5634" Test for using a duplicate class method and class variable in a child class
5635def Test_dup_class_member()
5636 # duplicate class variable, class method and overridden object method
5637 var lines =<< trim END
5638 vim9script
5639 class A
5640 static sval = 100
5641 static def Check()
5642 assert_equal(100, sval)
5643 enddef
5644 def GetVal(): number
5645 return sval
5646 enddef
5647 endclass
5648
5649 class B extends A
5650 static sval = 200
5651 static def Check()
5652 assert_equal(200, sval)
5653 enddef
5654 def GetVal(): number
5655 return sval
5656 enddef
5657 endclass
5658
5659 def T1(aa: A): number
5660 return aa.GetVal()
5661 enddef
5662
5663 def T2(bb: B): number
5664 return bb.GetVal()
5665 enddef
5666
5667 assert_equal(100, A.sval)
5668 assert_equal(200, B.sval)
5669 var a = A.new()
5670 assert_equal(100, a.GetVal())
5671 var b = B.new()
5672 assert_equal(200, b.GetVal())
5673 assert_equal(200, T1(b))
5674 assert_equal(200, T2(b))
5675 END
5676 v9.CheckSourceSuccess(lines)
5677
5678 # duplicate class variable and class method
5679 lines =<< trim END
5680 vim9script
5681 class A
5682 static sval = 100
5683 static def Check()
5684 assert_equal(100, sval)
5685 enddef
5686 def GetVal(): number
5687 return sval
5688 enddef
5689 endclass
5690
5691 class B extends A
5692 static sval = 200
5693 static def Check()
5694 assert_equal(200, sval)
5695 enddef
5696 endclass
5697
5698 def T1(aa: A): number
5699 return aa.GetVal()
5700 enddef
5701
5702 def T2(bb: B): number
5703 return bb.GetVal()
5704 enddef
5705
5706 assert_equal(100, A.sval)
5707 assert_equal(200, B.sval)
5708 var a = A.new()
5709 assert_equal(100, a.GetVal())
5710 var b = B.new()
5711 assert_equal(100, b.GetVal())
5712 assert_equal(100, T1(b))
5713 assert_equal(100, T2(b))
5714 END
5715 v9.CheckSourceSuccess(lines)
5716enddef
5717
5718" Test for calling an instance method using the class
5719def Test_instance_method_call_using_class()
5720 # Invoke an object method using a class in script context
5721 var lines =<< trim END
5722 vim9script
5723 class A
5724 def Foo()
5725 echo "foo"
5726 enddef
5727 endclass
5728 A.Foo()
5729 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005730 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005731
5732 # Invoke an object method using a class in def function context
5733 lines =<< trim END
5734 vim9script
5735 class A
5736 def Foo()
5737 echo "foo"
5738 enddef
5739 endclass
5740 def T()
5741 A.Foo()
5742 enddef
5743 T()
5744 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005745 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005746enddef
5747
5748" Test for duplicate class method and instance method
5749def Test_dup_classmethod_objmethod()
5750 # Duplicate instance method
5751 var lines =<< trim END
5752 vim9script
5753 class A
5754 static def Foo()
5755 enddef
5756 def Foo()
5757 enddef
5758 endclass
5759 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005760 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005761
5762 # Duplicate private instance method
5763 lines =<< trim END
5764 vim9script
5765 class A
5766 static def Foo()
5767 enddef
5768 def _Foo()
5769 enddef
5770 endclass
5771 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005772 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005773
5774 # Duplicate class method
5775 lines =<< trim END
5776 vim9script
5777 class A
5778 def Foo()
5779 enddef
5780 static def Foo()
5781 enddef
5782 endclass
5783 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005784 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005785
5786 # Duplicate private class method
5787 lines =<< trim END
5788 vim9script
5789 class A
5790 def Foo()
5791 enddef
5792 static def _Foo()
5793 enddef
5794 endclass
5795 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005796 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005797
5798 # Duplicate private class and object method
5799 lines =<< trim END
5800 vim9script
5801 class A
5802 def _Foo()
5803 enddef
5804 static def _Foo()
5805 enddef
5806 endclass
5807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005808 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005809enddef
5810
5811" Test for an instance method access level comparison with parent instance
5812" methods.
5813def Test_instance_method_access_level()
5814 # Private method in subclass
5815 var lines =<< trim END
5816 vim9script
5817 class A
5818 def Foo()
5819 enddef
5820 endclass
5821 class B extends A
5822 endclass
5823 class C extends B
5824 def _Foo()
5825 enddef
5826 endclass
5827 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005828 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005829
5830 # Public method in subclass
5831 lines =<< trim END
5832 vim9script
5833 class A
5834 def _Foo()
5835 enddef
5836 endclass
5837 class B extends A
5838 endclass
5839 class C extends B
5840 def Foo()
5841 enddef
5842 endclass
5843 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005844 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005845enddef
5846
5847def Test_extend_empty_class()
5848 var lines =<< trim END
5849 vim9script
5850 class A
5851 endclass
5852 class B extends A
5853 endclass
5854 class C extends B
5855 public static rw_class_var = 1
5856 public this.rw_obj_var = 2
5857 static def ClassMethod(): number
5858 return 3
5859 enddef
5860 def ObjMethod(): number
5861 return 4
5862 enddef
5863 endclass
5864 assert_equal(1, C.rw_class_var)
5865 assert_equal(3, C.ClassMethod())
5866 var c = C.new()
5867 assert_equal(2, c.rw_obj_var)
5868 assert_equal(4, c.ObjMethod())
5869 END
5870 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005871enddef
5872
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005873" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005874" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005875def Test_interface_with_unsupported_members()
5876 var lines =<< trim END
5877 vim9script
5878 interface A
5879 static num: number
5880 endinterface
5881 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005882 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005883
5884 lines =<< trim END
5885 vim9script
5886 interface A
5887 static _num: number
5888 endinterface
5889 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005890 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005891
5892 lines =<< trim END
5893 vim9script
5894 interface A
5895 public static num: number
5896 endinterface
5897 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005898 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005899
5900 lines =<< trim END
5901 vim9script
5902 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005903 public static num: number
5904 endinterface
5905 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005906 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005907
5908 lines =<< trim END
5909 vim9script
5910 interface A
5911 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005912 endinterface
5913 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005914 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005915
5916 lines =<< trim END
5917 vim9script
5918 interface A
5919 static def Foo(d: dict<any>): list<string>
5920 endinterface
5921 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005922 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005923
5924 lines =<< trim END
5925 vim9script
5926 interface A
5927 static def _Foo(d: dict<any>): list<string>
5928 endinterface
5929 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005930 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005931
5932 lines =<< trim END
5933 vim9script
5934 interface A
5935 this._Foo: list<string>
5936 endinterface
5937 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005938 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005939
5940 lines =<< trim END
5941 vim9script
5942 interface A
5943 def _Foo(d: dict<any>): list<string>
5944 endinterface
5945 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005946 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005947enddef
5948
5949" Test for extending an interface
5950def Test_extend_interface()
5951 var lines =<< trim END
5952 vim9script
5953 interface A
5954 this.var1: list<string>
5955 def Foo()
5956 endinterface
5957 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005958 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005959 def Bar()
5960 endinterface
5961 class C implements A, B
5962 this.var1 = [1, 2]
5963 def Foo()
5964 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005965 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005966 def Bar()
5967 enddef
5968 endclass
5969 END
5970 v9.CheckSourceSuccess(lines)
5971
5972 lines =<< trim END
5973 vim9script
5974 interface A
5975 def Foo()
5976 endinterface
5977 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005978 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005979 endinterface
5980 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005981 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005982 endclass
5983 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005984 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005985
5986 lines =<< trim END
5987 vim9script
5988 interface A
5989 def Foo()
5990 endinterface
5991 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005992 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005993 endinterface
5994 class C implements A, B
5995 def Foo()
5996 enddef
5997 endclass
5998 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005999 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006000
6001 # interface cannot extend a class
6002 lines =<< trim END
6003 vim9script
6004 class A
6005 endclass
6006 interface B extends A
6007 endinterface
6008 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006009 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006010
6011 # class cannot extend an interface
6012 lines =<< trim END
6013 vim9script
6014 interface A
6015 endinterface
6016 class B extends A
6017 endclass
6018 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006019 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006020
6021 # interface cannot implement another interface
6022 lines =<< trim END
6023 vim9script
6024 interface A
6025 endinterface
6026 interface B implements A
6027 endinterface
6028 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006029 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006030
6031 # interface cannot extend multiple interfaces
6032 lines =<< trim END
6033 vim9script
6034 interface A
6035 endinterface
6036 interface B
6037 endinterface
6038 interface C extends A, B
6039 endinterface
6040 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006041 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006042
6043 # Variable type in an extended interface is of different type
6044 lines =<< trim END
6045 vim9script
6046 interface A
6047 this.val1: number
6048 endinterface
6049 interface B extends A
6050 this.val2: string
6051 endinterface
6052 interface C extends B
6053 this.val1: string
6054 this.val2: number
6055 endinterface
6056 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006057 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006058enddef
6059
6060" Test for a child class implementing an interface when some of the methods are
6061" defined in the parent class.
6062def Test_child_class_implements_interface()
6063 var lines =<< trim END
6064 vim9script
6065
6066 interface Intf
6067 def F1(): list<list<number>>
6068 def F2(): list<list<number>>
6069 def F3(): list<list<number>>
6070 this.var1: list<dict<number>>
6071 this.var2: list<dict<number>>
6072 this.var3: list<dict<number>>
6073 endinterface
6074
6075 class A
6076 def A1()
6077 enddef
6078 def F3(): list<list<number>>
6079 return [[3]]
6080 enddef
6081 this.v1: list<list<number>> = [[0]]
6082 this.var3 = [{c: 30}]
6083 endclass
6084
6085 class B extends A
6086 def B1()
6087 enddef
6088 def F2(): list<list<number>>
6089 return [[2]]
6090 enddef
6091 this.v2: list<list<number>> = [[0]]
6092 this.var2 = [{b: 20}]
6093 endclass
6094
6095 class C extends B implements Intf
6096 def C1()
6097 enddef
6098 def F1(): list<list<number>>
6099 return [[1]]
6100 enddef
6101 this.v3: list<list<number>> = [[0]]
6102 this.var1 = [{a: 10}]
6103 endclass
6104
6105 def T(if: Intf)
6106 assert_equal([[1]], if.F1())
6107 assert_equal([[2]], if.F2())
6108 assert_equal([[3]], if.F3())
6109 assert_equal([{a: 10}], if.var1)
6110 assert_equal([{b: 20}], if.var2)
6111 assert_equal([{c: 30}], if.var3)
6112 enddef
6113
6114 var c = C.new()
6115 T(c)
6116 assert_equal([[1]], c.F1())
6117 assert_equal([[2]], c.F2())
6118 assert_equal([[3]], c.F3())
6119 assert_equal([{a: 10}], c.var1)
6120 assert_equal([{b: 20}], c.var2)
6121 assert_equal([{c: 30}], c.var3)
6122 END
6123 v9.CheckSourceSuccess(lines)
6124
6125 # One of the interface methods is not found
6126 lines =<< trim END
6127 vim9script
6128
6129 interface Intf
6130 def F1()
6131 def F2()
6132 def F3()
6133 endinterface
6134
6135 class A
6136 def A1()
6137 enddef
6138 endclass
6139
6140 class B extends A
6141 def B1()
6142 enddef
6143 def F2()
6144 enddef
6145 endclass
6146
6147 class C extends B implements Intf
6148 def C1()
6149 enddef
6150 def F1()
6151 enddef
6152 endclass
6153 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006154 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006155
6156 # One of the interface methods is of different type
6157 lines =<< trim END
6158 vim9script
6159
6160 interface Intf
6161 def F1()
6162 def F2()
6163 def F3()
6164 endinterface
6165
6166 class A
6167 def F3(): number
6168 return 0
6169 enddef
6170 def A1()
6171 enddef
6172 endclass
6173
6174 class B extends A
6175 def B1()
6176 enddef
6177 def F2()
6178 enddef
6179 endclass
6180
6181 class C extends B implements Intf
6182 def C1()
6183 enddef
6184 def F1()
6185 enddef
6186 endclass
6187 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006188 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006189
6190 # One of the interface variables is not present
6191 lines =<< trim END
6192 vim9script
6193
6194 interface Intf
6195 this.var1: list<dict<number>>
6196 this.var2: list<dict<number>>
6197 this.var3: list<dict<number>>
6198 endinterface
6199
6200 class A
6201 this.v1: list<list<number>> = [[0]]
6202 endclass
6203
6204 class B extends A
6205 this.v2: list<list<number>> = [[0]]
6206 this.var2 = [{b: 20}]
6207 endclass
6208
6209 class C extends B implements Intf
6210 this.v3: list<list<number>> = [[0]]
6211 this.var1 = [{a: 10}]
6212 endclass
6213 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006214 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006215
6216 # One of the interface variables is of different type
6217 lines =<< trim END
6218 vim9script
6219
6220 interface Intf
6221 this.var1: list<dict<number>>
6222 this.var2: list<dict<number>>
6223 this.var3: list<dict<number>>
6224 endinterface
6225
6226 class A
6227 this.v1: list<list<number>> = [[0]]
6228 this.var3: list<dict<string>>
6229 endclass
6230
6231 class B extends A
6232 this.v2: list<list<number>> = [[0]]
6233 this.var2 = [{b: 20}]
6234 endclass
6235
6236 class C extends B implements Intf
6237 this.v3: list<list<number>> = [[0]]
6238 this.var1 = [{a: 10}]
6239 endclass
6240 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006241 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 +02006242enddef
6243
6244" Test for extending an interface with duplicate variables and methods
6245def Test_interface_extends_with_dup_members()
6246 var lines =<< trim END
6247 vim9script
6248 interface A
6249 this.n1: number
6250 def Foo1(): number
6251 endinterface
6252 interface B extends A
6253 this.n2: number
6254 this.n1: number
6255 def Foo2(): number
6256 def Foo1(): number
6257 endinterface
6258 class C implements B
6259 this.n1 = 10
6260 this.n2 = 20
6261 def Foo1(): number
6262 return 30
6263 enddef
6264 def Foo2(): number
6265 return 40
6266 enddef
6267 endclass
6268 def T1(a: A)
6269 assert_equal(10, a.n1)
6270 assert_equal(30, a.Foo1())
6271 enddef
6272 def T2(b: B)
6273 assert_equal(10, b.n1)
6274 assert_equal(20, b.n2)
6275 assert_equal(30, b.Foo1())
6276 assert_equal(40, b.Foo2())
6277 enddef
6278 var c = C.new()
6279 T1(c)
6280 T2(c)
6281 END
6282 v9.CheckSourceSuccess(lines)
6283enddef
6284
6285" Test for using "any" type for a variable in a sub-class while it has a
6286" concrete type in the interface
6287def Test_implements_using_var_type_any()
6288 var lines =<< trim END
6289 vim9script
6290 interface A
6291 this.val: list<dict<string>>
6292 endinterface
6293 class B implements A
6294 this.val = [{a: '1'}, {b: '2'}]
6295 endclass
6296 var b = B.new()
6297 assert_equal([{a: '1'}, {b: '2'}], b.val)
6298 END
6299 v9.CheckSourceSuccess(lines)
6300
6301 # initialize instance variable using a different type
6302 lines =<< trim END
6303 vim9script
6304 interface A
6305 this.val: list<dict<string>>
6306 endinterface
6307 class B implements A
6308 this.val = {a: 1, b: 2}
6309 endclass
6310 var b = B.new()
6311 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006312 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006313enddef
6314
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006315" Test for assigning to a member variable in a nested class
6316def Test_nested_object_assignment()
6317 var lines =<< trim END
6318 vim9script
6319
6320 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006321 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006322 endclass
6323
6324 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006325 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006326 endclass
6327
6328 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006329 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006330 endclass
6331
6332 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006333 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006334 endclass
6335
6336 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006337 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006338 enddef
6339
6340 var d = D.new()
6341 T(d)
6342 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006343 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006344enddef
6345
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006346" Test for calling methods using a null object
6347def Test_null_object_method_call()
6348 # Calling a object method using a null object in script context
6349 var lines =<< trim END
6350 vim9script
6351
6352 class C
6353 def Foo()
6354 assert_report('This method should not be executed')
6355 enddef
6356 endclass
6357
6358 var o: C
6359 o.Foo()
6360 END
6361 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6362
6363 # Calling a object method using a null object in def function context
6364 lines =<< trim END
6365 vim9script
6366
6367 class C
6368 def Foo()
6369 assert_report('This method should not be executed')
6370 enddef
6371 endclass
6372
6373 def T()
6374 var o: C
6375 o.Foo()
6376 enddef
6377 T()
6378 END
6379 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6380
6381 # Calling a object method through another class method using a null object in
6382 # script context
6383 lines =<< trim END
6384 vim9script
6385
6386 class C
6387 def Foo()
6388 assert_report('This method should not be executed')
6389 enddef
6390
6391 static def Bar(o_any: any)
6392 var o_typed: C = o_any
6393 o_typed.Foo()
6394 enddef
6395 endclass
6396
6397 var o: C
6398 C.Bar(o)
6399 END
6400 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6401
6402 # Calling a object method through another class method using a null object in
6403 # def function context
6404 lines =<< trim END
6405 vim9script
6406
6407 class C
6408 def Foo()
6409 assert_report('This method should not be executed')
6410 enddef
6411
6412 static def Bar(o_any: any)
6413 var o_typed: C = o_any
6414 o_typed.Foo()
6415 enddef
6416 endclass
6417
6418 def T()
6419 var o: C
6420 C.Bar(o)
6421 enddef
6422 T()
6423 END
6424 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6425enddef
6426
6427" Test for using a dict as an object member
6428def Test_dict_object_member()
6429 var lines =<< trim END
6430 vim9script
6431
6432 class Context
6433 public this.state: dict<number> = {}
6434 def GetState(): dict<number>
6435 return this.state
6436 enddef
6437 endclass
6438
6439 var ctx = Context.new()
6440 ctx.state->extend({a: 1})
6441 ctx.state['b'] = 2
6442 assert_equal({a: 1, b: 2}, ctx.GetState())
6443
6444 def F()
6445 ctx.state['c'] = 3
6446 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6447 enddef
6448 F()
6449 assert_equal(3, ctx.state.c)
6450 ctx.state.c = 4
6451 assert_equal(4, ctx.state.c)
6452 END
6453 v9.CheckSourceSuccess(lines)
6454enddef
6455
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006456" The following test was failing after 9.0.1914. This was caused by using a
6457" freed object from a previous method call.
6458def Test_freed_object_from_previous_method_call()
6459 var lines =<< trim END
6460 vim9script
6461
6462 class Context
6463 endclass
6464
6465 class Result
6466 endclass
6467
6468 def Failure(): Result
6469 return Result.new()
6470 enddef
6471
6472 def GetResult(ctx: Context): Result
6473 return Failure()
6474 enddef
6475
6476 def Test_GetResult()
6477 var ctx = Context.new()
6478 var result = GetResult(ctx)
6479 enddef
6480
6481 Test_GetResult()
6482 END
6483 v9.CheckSourceSuccess(lines)
6484enddef
6485
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006486" Test for duplicate object and class variable
6487def Test_duplicate_variable()
6488 # Object variable name is same as the class variable name
6489 var lines =<< trim END
6490 vim9script
6491 class A
6492 public static sval: number
6493 public this.sval: number
6494 endclass
6495 var a = A.new()
6496 END
6497 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6498
6499 # Duplicate variable name and calling a class method
6500 lines =<< trim END
6501 vim9script
6502 class A
6503 public static sval: number
6504 public this.sval: number
6505 def F1()
6506 echo this.sval
6507 enddef
6508 static def F2()
6509 echo sval
6510 enddef
6511 endclass
6512 A.F2()
6513 END
6514 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6515
6516 # Duplicate variable with an empty constructor
6517 lines =<< trim END
6518 vim9script
6519 class A
6520 public static sval: number
6521 public this.sval: number
6522 def new()
6523 enddef
6524 endclass
6525 var a = A.new()
6526 END
6527 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6528enddef
6529
6530" Test for using a reserved keyword as a variable name
6531def Test_reserved_varname()
6532 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6533 'null_function', 'null_list', 'null_partial', 'null_string',
6534 'null_channel', 'null_job', 'super', 'this']
6535
6536 var lines =<< trim eval END
6537 vim9script
6538 class C
6539 public this.{kword}: list<number> = [1, 2, 3]
6540 endclass
6541 var o = C.new()
6542 END
6543 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6544
6545 lines =<< trim eval END
6546 vim9script
6547 class C
6548 public this.{kword}: list<number> = [1, 2, 3]
6549 def new()
6550 enddef
6551 endclass
6552 var o = C.new()
6553 END
6554 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6555
6556 lines =<< trim eval END
6557 vim9script
6558 class C
6559 public this.{kword}: list<number> = [1, 2, 3]
6560 def new()
6561 enddef
6562 def F()
6563 echo this.{kword}
6564 enddef
6565 endclass
6566 var o = C.new()
6567 o.F()
6568 END
6569 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6570 endfor
6571enddef
6572
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006573" Test for checking the type of the arguments and the return value of a object
6574" method in an extended class.
6575def Test_extended_obj_method_type_check()
6576 var lines =<< trim END
6577 vim9script
6578
6579 class A
6580 endclass
6581 class B extends A
6582 endclass
6583 class C extends B
6584 endclass
6585
6586 class Foo
6587 def Doit(p: B): B
6588 return B.new()
6589 enddef
6590 endclass
6591
6592 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006593 def Doit(p: C): B
6594 return B.new()
6595 enddef
6596 endclass
6597 END
6598 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6599
6600 lines =<< trim END
6601 vim9script
6602
6603 class A
6604 endclass
6605 class B extends A
6606 endclass
6607 class C extends B
6608 endclass
6609
6610 class Foo
6611 def Doit(p: B): B
6612 return B.new()
6613 enddef
6614 endclass
6615
6616 class Bar extends Foo
6617 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006618 return C.new()
6619 enddef
6620 endclass
6621 END
6622 v9.CheckSourceSuccess(lines)
6623
6624 lines =<< trim END
6625 vim9script
6626
6627 class A
6628 endclass
6629 class B extends A
6630 endclass
6631 class C extends B
6632 endclass
6633
6634 class Foo
6635 def Doit(p: B): B
6636 return B.new()
6637 enddef
6638 endclass
6639
6640 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006641 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006642 return B.new()
6643 enddef
6644 endclass
6645 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006646 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 +02006647
6648 lines =<< trim END
6649 vim9script
6650
6651 class A
6652 endclass
6653 class B extends A
6654 endclass
6655 class C extends B
6656 endclass
6657
6658 class Foo
6659 def Doit(p: B): B
6660 return B.new()
6661 enddef
6662 endclass
6663
6664 class Bar extends Foo
6665 def Doit(p: B): A
6666 return A.new()
6667 enddef
6668 endclass
6669 END
6670 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
6671enddef
6672
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006673" Test type checking for class variable in assignments
6674func Test_class_variable_complex_type_check()
6675 " class variable with a specific type. Try assigning a different type at
6676 " script level.
6677 let lines =<< trim END
6678 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006679 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006680 return {}
6681 enddef
6682 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006683 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006684 endclass
6685 test_garbagecollect_now()
6686 A.Fn = "abc"
6687 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006688 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 +02006689
6690 " class variable with a specific type. Try assigning a different type at
6691 " class def method level.
6692 let lines =<< trim END
6693 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006694 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006695 return {}
6696 enddef
6697 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006698 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006699 def Bar()
6700 Fn = "abc"
6701 enddef
6702 endclass
6703 var a = A.new()
6704 test_garbagecollect_now()
6705 a.Bar()
6706 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006707 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 +02006708
6709 " class variable with a specific type. Try assigning a different type at
6710 " script def method level.
6711 let lines =<< trim END
6712 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006713 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006714 return {}
6715 enddef
6716 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006717 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006718 endclass
6719 def Bar()
6720 A.Fn = "abc"
6721 enddef
6722 test_garbagecollect_now()
6723 Bar()
6724 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006725 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 +02006726
6727 " class variable without any type. Should be set to the initialization
6728 " expression type. Try assigning a different type from script level.
6729 let lines =<< trim END
6730 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006731 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006732 return {}
6733 enddef
6734 class A
6735 public static Fn = Foo
6736 endclass
6737 test_garbagecollect_now()
6738 A.Fn = "abc"
6739 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006740 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 +02006741
6742 " class variable without any type. Should be set to the initialization
6743 " expression type. Try assigning a different type at class def level.
6744 let lines =<< trim END
6745 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006746 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006747 return {}
6748 enddef
6749 class A
6750 public static Fn = Foo
6751 def Bar()
6752 Fn = "abc"
6753 enddef
6754 endclass
6755 var a = A.new()
6756 test_garbagecollect_now()
6757 a.Bar()
6758 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006759 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 +02006760
6761 " class variable without any type. Should be set to the initialization
6762 " expression type. Try assigning a different type at script def level.
6763 let lines =<< trim END
6764 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006765 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006766 return {}
6767 enddef
6768 class A
6769 public static Fn = Foo
6770 endclass
6771 def Bar()
6772 A.Fn = "abc"
6773 enddef
6774 test_garbagecollect_now()
6775 Bar()
6776 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006777 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 +02006778
6779 " class variable with 'any" type. Can be assigned different types.
6780 let lines =<< trim END
6781 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006782 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006783 return {}
6784 enddef
6785 class A
6786 public static Fn: any = Foo
6787 public static Fn2: any
6788 endclass
6789 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006790 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006791 A.Fn = "abc"
6792 test_garbagecollect_now()
6793 assert_equal('string', typename(A.Fn))
6794 A.Fn2 = Foo
6795 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006796 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006797 A.Fn2 = "xyz"
6798 test_garbagecollect_now()
6799 assert_equal('string', typename(A.Fn2))
6800 END
6801 call v9.CheckSourceSuccess(lines)
6802
6803 " class variable with 'any" type. Can be assigned different types.
6804 let lines =<< trim END
6805 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006806 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006807 return {}
6808 enddef
6809 class A
6810 public static Fn: any = Foo
6811 public static Fn2: any
6812
6813 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006814 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006815 Fn = "abc"
6816 assert_equal('string', typename(Fn))
6817 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006818 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006819 Fn2 = "xyz"
6820 assert_equal('string', typename(Fn2))
6821 enddef
6822 endclass
6823 var a = A.new()
6824 test_garbagecollect_now()
6825 a.Bar()
6826 test_garbagecollect_now()
6827 A.Fn = Foo
6828 a.Bar()
6829 END
6830 call v9.CheckSourceSuccess(lines)
6831
6832 " class variable with 'any" type. Can be assigned different types.
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
6839 public static Fn: any = Foo
6840 public static Fn2: any
6841 endclass
6842
6843 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006844 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006845 A.Fn = "abc"
6846 assert_equal('string', typename(A.Fn))
6847 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006848 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006849 A.Fn2 = "xyz"
6850 assert_equal('string', typename(A.Fn2))
6851 enddef
6852 Bar()
6853 test_garbagecollect_now()
6854 A.Fn = Foo
6855 Bar()
6856 END
6857 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006858
6859 let lines =<< trim END
6860 vim9script
6861 class A
6862 public static foo = [0z10, 0z20]
6863 endclass
6864 assert_equal([0z10, 0z20], A.foo)
6865 A.foo = [0z30]
6866 assert_equal([0z30], A.foo)
6867 var a = A.foo
6868 assert_equal([0z30], a)
6869 END
6870 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006871endfunc
6872
6873" Test type checking for object variable in assignments
6874func Test_object_variable_complex_type_check()
6875 " object variable with a specific type. Try assigning a different type at
6876 " script level.
6877 let lines =<< trim END
6878 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006879 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006880 return {}
6881 enddef
6882 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006883 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006884 endclass
6885 var a = A.new()
6886 test_garbagecollect_now()
6887 a.Fn = "abc"
6888 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006889 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 +02006890
6891 " object variable with a specific type. Try assigning a different type at
6892 " object def method level.
6893 let lines =<< trim END
6894 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006895 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006896 return {}
6897 enddef
6898 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006899 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006900 def Bar()
6901 this.Fn = "abc"
6902 this.Fn = Foo
6903 enddef
6904 endclass
6905 var a = A.new()
6906 test_garbagecollect_now()
6907 a.Bar()
6908 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006909 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 +02006910
6911 " object variable with a specific type. Try assigning a different type at
6912 " script def method level.
6913 let lines =<< trim END
6914 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006915 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006916 return {}
6917 enddef
6918 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006919 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006920 endclass
6921 def Bar()
6922 var a = A.new()
6923 a.Fn = "abc"
6924 a.Fn = Foo
6925 enddef
6926 test_garbagecollect_now()
6927 Bar()
6928 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006929 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 +02006930
6931 " object variable without any type. Should be set to the initialization
6932 " expression type. Try assigning a different type from script level.
6933 let lines =<< trim END
6934 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006935 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006936 return {}
6937 enddef
6938 class A
6939 public this.Fn = Foo
6940 endclass
6941 var a = A.new()
6942 test_garbagecollect_now()
6943 a.Fn = "abc"
6944 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006945 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 +02006946
6947 " object variable without any type. Should be set to the initialization
6948 " expression type. Try assigning a different type at object def level.
6949 let lines =<< trim END
6950 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006951 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006952 return {}
6953 enddef
6954 class A
6955 public this.Fn = Foo
6956 def Bar()
6957 this.Fn = "abc"
6958 this.Fn = Foo
6959 enddef
6960 endclass
6961 var a = A.new()
6962 test_garbagecollect_now()
6963 a.Bar()
6964 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006965 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 +02006966
6967 " object variable without any type. Should be set to the initialization
6968 " expression type. Try assigning a different type at script def level.
6969 let lines =<< trim END
6970 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006971 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006972 return {}
6973 enddef
6974 class A
6975 public this.Fn = Foo
6976 endclass
6977 def Bar()
6978 var a = A.new()
6979 a.Fn = "abc"
6980 a.Fn = Foo
6981 enddef
6982 test_garbagecollect_now()
6983 Bar()
6984 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006985 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 +02006986
6987 " object variable with 'any" type. Can be assigned different types.
6988 let lines =<< trim END
6989 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02006990 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02006991 return {}
6992 enddef
6993 class A
6994 public this.Fn: any = Foo
6995 public this.Fn2: any
6996 endclass
6997
6998 var a = A.new()
6999 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007000 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007001 a.Fn = "abc"
7002 test_garbagecollect_now()
7003 assert_equal('string', typename(a.Fn))
7004 a.Fn2 = Foo
7005 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007006 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007007 a.Fn2 = "xyz"
7008 test_garbagecollect_now()
7009 assert_equal('string', typename(a.Fn2))
7010 END
7011 call v9.CheckSourceSuccess(lines)
7012
7013 " object variable with 'any" type. Can be assigned different types.
7014 let lines =<< trim END
7015 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007016 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007017 return {}
7018 enddef
7019 class A
7020 public this.Fn: any = Foo
7021 public this.Fn2: any
7022
7023 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007024 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007025 this.Fn = "abc"
7026 assert_equal('string', typename(this.Fn))
7027 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007028 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007029 this.Fn2 = "xyz"
7030 assert_equal('string', typename(this.Fn2))
7031 enddef
7032 endclass
7033
7034 var a = A.new()
7035 test_garbagecollect_now()
7036 a.Bar()
7037 test_garbagecollect_now()
7038 a.Fn = Foo
7039 a.Bar()
7040 END
7041 call v9.CheckSourceSuccess(lines)
7042
7043 " object variable with 'any" type. Can be assigned different types.
7044 let lines =<< trim END
7045 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007046 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007047 return {}
7048 enddef
7049 class A
7050 public this.Fn: any = Foo
7051 public this.Fn2: any
7052 endclass
7053
7054 def Bar()
7055 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007056 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007057 a.Fn = "abc"
7058 assert_equal('string', typename(a.Fn))
7059 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007060 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007061 a.Fn2 = "xyz"
7062 assert_equal('string', typename(a.Fn2))
7063 enddef
7064 test_garbagecollect_now()
7065 Bar()
7066 test_garbagecollect_now()
7067 Bar()
7068 END
7069 call v9.CheckSourceSuccess(lines)
7070endfunc
7071
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007072" Test for recursively calling an object method. This used to cause an
7073" use-after-free error.
7074def Test_recursive_object_method_call()
7075 var lines =<< trim END
7076 vim9script
7077 class A
7078 this.val: number = 0
7079 def Foo(): number
7080 if this.val >= 90
7081 return this.val
7082 endif
7083 this.val += 1
7084 return this.Foo()
7085 enddef
7086 endclass
7087 var a = A.new()
7088 assert_equal(90, a.Foo())
7089 END
7090 v9.CheckSourceSuccess(lines)
7091enddef
7092
7093" Test for recursively calling a class method.
7094def Test_recursive_class_method_call()
7095 var lines =<< trim END
7096 vim9script
7097 class A
7098 static val: number = 0
7099 static def Foo(): number
7100 if val >= 90
7101 return val
7102 endif
7103 val += 1
7104 return Foo()
7105 enddef
7106 endclass
7107 assert_equal(90, A.Foo())
7108 END
7109 v9.CheckSourceSuccess(lines)
7110enddef
7111
Bram Moolenaar00b28d62022-12-08 15:32:33 +00007112" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker