blob: 84ea1cb3571ea8389c2b127c8afa822c86532678 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +010038 # Only the complete word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020070 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000071 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020072 vim9script
73 class Something
74 this
75 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020077 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020079 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000080 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020081 vim9script
82 class Something
83 this.
84 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000085 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020086 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000087
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020088 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000089 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020090 vim9script
91 class Something
92 this .count
93 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000094 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020095 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000096
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020099 vim9script
100 class Something
101 this. count
102 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200104 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200108 vim9script
109 class Something
110 this.count: number
111 that.count
112 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000113 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200114 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000115
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200116 # Member variable without a type or initialization
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200118 vim9script
119 class Something
120 this.count
121 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000122 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200123 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200125 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000126 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200127 vim9script
128 class Something
129 def new()
130 this.state = 0
131 enddef
132 endclass
133 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000134 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200135 v9.CheckSourceFailure(lines, 'E1326: Variable "state" not found in object "Something"', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000136
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200137 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200139 vim9script
140 class Something
141 this.count : number
142 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200144 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000145
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200146 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000147 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200148 vim9script
149 class Something
150 this.count:number
151 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200153 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000154
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200155 # Test for unsupported comment specifier
156 lines =<< trim END
157 vim9script
158 class Something
159 # comment
160 #{
161 endclass
162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200164
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200165 # Test for using class as a bool
166 lines =<< trim END
167 vim9script
168 class A
169 endclass
170 if A
171 endif
172 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200173 v9.CheckSourceFailure(lines, 'E1319: Using a Class as a Number', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200174
175 # Test for using object as a bool
176 lines =<< trim END
177 vim9script
178 class A
179 endclass
180 var a = A.new()
181 if a
182 endif
183 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200184 v9.CheckSourceFailure(lines, 'E1320: Using an Object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200185
186 # Test for using class as a float
187 lines =<< trim END
188 vim9script
189 class A
190 endclass
191 sort([1.1, A], 'f')
192 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200193 v9.CheckSourceFailure(lines, 'E1321: Using a Class as a Float', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200194
195 # Test for using object as a float
196 lines =<< trim END
197 vim9script
198 class A
199 endclass
200 var a = A.new()
201 sort([1.1, a], 'f')
202 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200203 v9.CheckSourceFailure(lines, 'E1322: Using an Object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200204
205 # Test for using class as a string
206 lines =<< trim END
207 vim9script
208 class A
209 endclass
210 :exe 'call ' .. A
211 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200212 v9.CheckSourceFailure(lines, 'E1323: Using a Class as a String', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200213
214 # Test for using object as a string
215 lines =<< trim END
216 vim9script
217 class A
218 endclass
219 var a = A.new()
220 :exe 'call ' .. a
221 END
Yegappan Lakshmananec3cebb2023-10-27 19:35:26 +0200222 v9.CheckSourceFailure(lines, 'E1324: Using an Object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200223
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200224 # Test creating a class with member variables and methods, calling a object
225 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200227 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200229 class TextPosition
230 this.lnum: number
231 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000232
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200233 # make a nicely formatted string
234 def ToString(): string
235 return $'({this.lnum}, {this.col})'
236 enddef
237 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000238
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200239 # use the automatically generated new() method
240 var pos = TextPosition.new(2, 12)
241 assert_equal(2, pos.lnum)
242 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000243
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200244 # call an object method
245 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000246
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200247 assert_equal(v:t_class, type(TextPosition))
248 assert_equal(v:t_object, type(pos))
249 assert_equal('class<TextPosition>', typename(TextPosition))
250 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200253
254 # When referencing object methods, space cannot be used after a "."
255 lines =<< trim END
256 vim9script
257 class A
258 def Foo(): number
259 return 10
260 enddef
261 endclass
262 var a = A.new()
263 var v = a. Foo()
264 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200265 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200266
267 # Using an object without specifying a method or a member variable
268 lines =<< trim END
269 vim9script
270 class A
271 def Foo(): number
272 return 10
273 enddef
274 endclass
275 var a = A.new()
276 var v = a.
277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200278 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279
280 # Error when parsing the arguments of an object method.
281 lines =<< trim END
282 vim9script
283 class A
284 def Foo()
285 enddef
286 endclass
287 var a = A.new()
288 var v = a.Foo(,)
289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200290 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200291
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200292 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200293 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200294 vim9script
295 class A
296 this.y = {
297 X: 1
298 }
299 endclass
300 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200301 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200302 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000303enddef
304
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200305" Tests for object/class methods in a class
306def Test_class_def_method()
307 # Using the "public" keyword when defining an object method
308 var lines =<< trim END
309 vim9script
310 class A
311 public def Foo()
312 enddef
313 endclass
314 END
315 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
316
317 # Using the "public" keyword when defining a class method
318 lines =<< trim END
319 vim9script
320 class A
321 public static def Foo()
322 enddef
323 endclass
324 END
325 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
326
Ernie Rael03042a22023-11-11 08:53:32 +0100327 # Using the "public" keyword when defining an object protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200328 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
Ernie Rael03042a22023-11-11 08:53:32 +0100337 # Using the "public" keyword when defining a class protected method
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200338 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
Ernie Rael03042a22023-11-11 08:53:32 +0100609 # Try modifying a protected variable using an "any" object
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200610 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 Rael03042a22023-11-11 08:53:32 +0100629 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_value" in class "Inner"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200630
631 # Try modifying a non-existing variable using an "any" object
632 lines =<< trim END
633 vim9script
634
635 class Inner
636 this.value: string = ''
637 endclass
638
639 class Outer
640 this.inner: any
641 endclass
642
643 def F(outer: Outer)
644 outer.inner.someval = 'b'
645 enddef
646
647 var inner_obj = Inner.new('a')
648 var outer_obj = Outer.new(inner_obj)
649 F(outer_obj)
650 END
Ernie Raeld4802ec2023-10-20 11:59:00 +0200651 v9.CheckSourceFailure(lines, 'E1326: Variable "someval" not found in object "Inner"', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000652enddef
653
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200654" Nested assignment to a object variable which is of another class type
655def Test_assignment_nested_type()
656 var lines =<< trim END
657 vim9script
658
659 class Inner
660 public this.value: number = 0
661 endclass
662
663 class Outer
664 this.inner: Inner
665 endclass
666
667 def F(outer: Outer)
668 outer.inner.value = 1
669 enddef
670
671 def Test_assign_to_nested_typed_member()
672 var inner = Inner.new(0)
673 var outer = Outer.new(inner)
674 F(outer)
675 assert_equal(1, inner.value)
676 enddef
677
678 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200679
680 var script_inner = Inner.new(0)
681 var script_outer = Outer.new(script_inner)
682 script_outer.inner.value = 1
683 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200684 END
685 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200686
687 # Assignment where target item is read only in :def
688 lines =<< trim END
689 vim9script
690
691 class Inner
692 this.value: number = 0
693 endclass
694
695 class Outer
696 this.inner: Inner
697 endclass
698
699 def F(outer: Outer)
700 outer.inner.value = 1
701 enddef
702
703 def Test_assign_to_nested_typed_member()
704 var inner = Inner.new(0)
705 var outer = Outer.new(inner)
706 F(outer)
707 assert_equal(1, inner.value)
708 enddef
709
710 Test_assign_to_nested_typed_member()
711 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200713
714 # Assignment where target item is read only script level
715 lines =<< trim END
716 vim9script
717
718 class Inner
719 this.value: number = 0
720 endclass
721
722 class Outer
723 this.inner: Inner
724 endclass
725
726 def F(outer: Outer)
727 outer.inner.value = 1
728 enddef
729
730 var script_inner = Inner.new(0)
731 var script_outer = Outer.new(script_inner)
732 script_outer.inner.value = 1
733 assert_equal(1, script_inner.value)
734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200735 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200736enddef
737
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000738def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200739 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000740 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200741 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000742
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200743 class Foo
744 public this.x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 def Add(n: number)
747 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100748 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200749 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200751 var f = Foo.new(3)
752 f.Add(17)
753 assert_equal(20, f.x)
754
755 def AddToFoo(obj: Foo)
756 obj.x += 3
757 enddef
758
759 AddToFoo(f)
760 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000761 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200762 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000763enddef
764
Bram Moolenaarf4508042023-01-15 16:54:57 +0000765def Test_list_of_objects()
766 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200767 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200769 class Foo
770 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000771 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200772 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000773
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200774 def ProcessList(fooList: list<Foo>)
775 for foo in fooList
776 foo.Add()
777 endfor
778 enddef
779
780 var l: list<Foo> = [Foo.new()]
781 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000782 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200783 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000784enddef
785
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000786def Test_expr_after_using_object()
787 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Something
791 this.label: string = ''
792 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def Foo(): Something
795 var v = Something.new()
796 echo 'in Foo(): ' .. typename(v)
797 return v
798 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000799
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000801 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200802 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000803enddef
804
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000805def Test_class_default_new()
806 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200807 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000808
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200809 class TextPosition
810 this.lnum: number = 1
811 this.col: number = 1
812 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000813
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200814 var pos = TextPosition.new()
815 assert_equal(1, pos.lnum)
816 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200818 pos = TextPosition.new(v:none, v:none)
819 assert_equal(1, pos.lnum)
820 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000821
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200822 pos = TextPosition.new(3, 22)
823 assert_equal(3, pos.lnum)
824 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200826 pos = TextPosition.new(v:none, 33)
827 assert_equal(1, pos.lnum)
828 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000829 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200830 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000831
832 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200833 vim9script
834 class Person
835 this.name: string
836 this.age: number = 42
837 this.education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 def new(this.name, this.age = v:none, this.education = v:none)
840 enddef
841 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000842
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200843 var piet = Person.new("Piet")
844 assert_equal("Piet", piet.name)
845 assert_equal(42, piet.age)
846 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000847
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200848 var chris = Person.new("Chris", 4, "none")
849 assert_equal("Chris", chris.name)
850 assert_equal(4, chris.age)
851 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000852 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200853 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000854
855 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200856 vim9script
857 class Person
858 this.name: string
859 this.age: number = 42
860 this.education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def new(this.name, this.age = v:none, this.education = v:none)
863 enddef
864 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200866 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200868 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200869
870 # Using a specific value to initialize an instance variable in the new()
871 # method.
872 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200873 vim9script
874 class A
875 this.val: string
876 def new(this.val = 'a')
877 enddef
878 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200879 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000881enddef
882
h-east2261c892023-08-16 21:49:54 +0900883def Test_class_new_with_object_member()
884 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200885 vim9script
h-east2261c892023-08-16 21:49:54 +0900886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200887 class C
888 this.str: string
889 this.num: number
890 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900891 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200892 def newVals(this.str, this.num)
893 enddef
894 endclass
h-east2261c892023-08-16 21:49:54 +0900895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200896 def Check()
897 try
898 var c = C.new('cats', 2)
899 assert_equal('cats', c.str)
900 assert_equal(2, c.num)
901
902 c = C.newVals('dogs', 4)
903 assert_equal('dogs', c.str)
904 assert_equal(4, c.num)
905 catch
906 assert_report($'Unexpected exception was caught: {v:exception}')
907 endtry
908 enddef
909
910 Check()
h-east2261c892023-08-16 21:49:54 +0900911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200912 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900913
914 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +0200915 vim9script
916
917 class C
918 this.str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200919 this.num: number
920 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +0200921 enddef
922 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200923
924 def Check()
925 try
926 var c = C.new(1, 2)
927 catch
928 assert_report($'Unexpected exception was caught: {v:exception}')
929 endtry
930 enddef
931
932 Check()
h-eastdb385522023-09-28 22:18:19 +0200933 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +0200935
936 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
h-eastb895b0f2023-09-24 15:46:31 +0200938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class C
940 this.str: string
941 this.num: number
942 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +0200943 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 endclass
h-eastb895b0f2023-09-24 15:46:31 +0200945
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 def Check()
947 try
948 var c = C.newVals('dogs', 'apes')
949 catch
950 assert_report($'Unexpected exception was caught: {v:exception}')
951 endtry
952 enddef
953
954 Check()
955 END
956 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
957
958 lines =<< trim END
959 vim9script
960
961 class C
962 this.str: string
963 def new(str: any)
964 enddef
965 endclass
966
967 def Check()
968 try
969 var c = C.new(1)
970 catch
971 assert_report($'Unexpected exception was caught: {v:exception}')
972 endtry
973 enddef
974
975 Check()
h-eastb895b0f2023-09-24 15:46:31 +0200976 END
977 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +0200978
979 # Try using "this." argument in a class method
980 lines =<< trim END
981 vim9script
982 class A
983 this.val = 10
984 static def Foo(this.val: number)
985 enddef
986 endclass
987 END
988 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
989
990 # Try using "this." argument in an object method
991 lines =<< trim END
992 vim9script
993 class A
994 this.val = 10
995 def Foo(this.val: number)
996 enddef
997 endclass
998 END
999 v9.CheckSourceFailure(lines, 'E1390: Cannot use an object variable "this.val" except with the "new" method', 4)
h-east2261c892023-08-16 21:49:54 +09001000enddef
1001
Bram Moolenaar74e12742022-12-13 21:14:28 +00001002def Test_class_object_member_inits()
1003 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001004 vim9script
1005 class TextPosition
1006 this.lnum: number
1007 this.col = 1
1008 this.addcol: number = 2
1009 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001010
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001011 var pos = TextPosition.new()
1012 assert_equal(0, pos.lnum)
1013 assert_equal(1, pos.col)
1014 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001015 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001016 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001017
1018 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001019 vim9script
1020 class TextPosition
1021 this.lnum
1022 this.col = 1
1023 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001024 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001025 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001026
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001027 # If the type is not specified for a member, then it should be set during
1028 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001029 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001030 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001031
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001032 var init_count = 0
1033 def Init(): string
1034 init_count += 1
1035 return 'foo'
1036 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001037
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001038 class A
1039 this.str1 = Init()
1040 this.str2: string = Init()
1041 this.col = 1
1042 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001043
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001044 assert_equal(init_count, 0)
1045 var a = A.new()
1046 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001047 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001049
1050 # Test for initializing an object member with an unknown variable/type
1051 lines =<< trim END
1052 vim9script
1053 class A
1054 this.value = init_val
1055 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001056 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001058 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001059
1060 # Test for initializing an object member with an special type
1061 lines =<< trim END
1062 vim9script
1063 class A
1064 this.value: void
1065 endclass
1066 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001067 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001068enddef
1069
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001070" Test for instance variable access
1071def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001072 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 vim9script
1074 class Triple
1075 this._one = 1
1076 this.two = 2
1077 public this.three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001078
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001079 def GetOne(): number
1080 return this._one
1081 enddef
1082 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001083
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001084 var trip = Triple.new()
1085 assert_equal(1, trip.GetOne())
1086 assert_equal(2, trip.two)
1087 assert_equal(3, trip.three)
Ernie Rael03042a22023-11-11 08:53:32 +01001088 assert_fails('echo trip._one', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001089
Ernie Rael03042a22023-11-11 08:53:32 +01001090 assert_fails('trip._one = 11', 'E1333: Cannot access protected variable "_one" in class "Triple"')
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001091 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1092 trip.three = 33
1093 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001094
Ernie Raeld4802ec2023-10-20 11:59:00 +02001095 assert_fails('trip.four = 4', 'E1326: Variable "four" not found in object "Triple"')
Bram Moolenaard505d172022-12-18 21:42:55 +00001096 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001097 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001098
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001099 # Test for a public member variable name beginning with an underscore
1100 lines =<< trim END
1101 vim9script
1102 class A
1103 public this._val = 10
1104 endclass
1105 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001106 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001107
Bram Moolenaar590162c2022-12-24 21:24:06 +00001108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001109 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001111 class MyCar
1112 this.make: string
1113 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001114
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001115 def new(make_arg: string)
1116 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001117 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001118
1119 def GetMake(): string
1120 return $"make = {this.make}"
1121 enddef
1122 def GetAge(): number
1123 return this.age
1124 enddef
1125 endclass
1126
1127 var c = MyCar.new("abc")
1128 assert_equal('make = abc', c.GetMake())
1129
1130 c = MyCar.new("def")
1131 assert_equal('make = def', c.GetMake())
1132
1133 var c2 = MyCar.new("123")
1134 assert_equal('make = 123', c2.GetMake())
1135
1136 def CheckCar()
1137 assert_equal("make = def", c.GetMake())
1138 assert_equal(5, c.GetAge())
1139 enddef
1140 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001141 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001142 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001143
1144 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001145 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001146
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001147 class MyCar
1148 this.make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001150 def new(make_arg: string)
1151 this.make = make_arg
1152 enddef
1153 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001154
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001155 var c = MyCar.new("abc")
1156 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001157 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001158 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001159
1160 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001161 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001162
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001163 class Foo
1164 this.x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001165
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001166 def Add(n: number): any
1167 this.x->add(n)
1168 return this
1169 enddef
1170 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001171
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001172 echo Foo.new().Add(1).Add(2).x
1173 echo Foo.new().Add(1).Add(2)
1174 .x
1175 echo Foo.new().Add(1)
1176 .Add(2).x
1177 echo Foo.new()
1178 .Add(1).Add(2).x
1179 echo Foo.new()
1180 .Add(1)
1181 .Add(2)
1182 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001183 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001184 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001185
1186 # Test for "public" cannot be abbreviated
1187 lines =<< trim END
1188 vim9script
1189 class Something
1190 pub this.val = 1
1191 endclass
1192 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001193 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001194
1195 # Test for "public" keyword must be followed by "this" or "static".
1196 lines =<< trim END
1197 vim9script
1198 class Something
1199 public val = 1
1200 endclass
1201 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001202 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001203
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001204 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001205 lines =<< trim END
1206 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001207 class A
1208 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001209 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001210 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001212 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001213
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001215 lines =<< trim END
1216 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001217 class A
1218 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001219 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001220 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001222 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001223
1224 # Modify a instance variable using the class name in a def function
1225 lines =<< trim END
1226 vim9script
1227 class A
1228 public this.val = 1
1229 endclass
1230 def T()
1231 A.val = 1
1232 enddef
1233 T()
1234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001235 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001236
1237 # Read a instance variable using the class name in a def function
1238 lines =<< trim END
1239 vim9script
1240 class A
1241 public this.val = 1
1242 endclass
1243 def T()
1244 var i = A.val
1245 enddef
1246 T()
1247 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001248 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001249
1250 # Access from child class extending a class:
1251 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001252 vim9script
1253 class A
1254 this.ro_obj_var = 10
1255 public this.rw_obj_var = 20
1256 this._priv_obj_var = 30
1257 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001258
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001259 class B extends A
1260 def Foo()
1261 var x: number
1262 x = this.ro_obj_var
1263 this.ro_obj_var = 0
1264 x = this.rw_obj_var
1265 this.rw_obj_var = 0
1266 x = this._priv_obj_var
1267 this._priv_obj_var = 0
1268 enddef
1269 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001270
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001271 var b = B.new()
1272 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001273 END
1274 v9.CheckSourceSuccess(lines)
1275enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001276
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001277" Test for class variable access
1278def Test_class_variable_access()
1279 # Test for "static" cannot be abbreviated
1280 var lines =<< trim END
1281 vim9script
1282 class Something
1283 stat this.val = 1
1284 endclass
1285 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001287
1288 # Test for "static" cannot be followed by "this".
1289 lines =<< trim END
1290 vim9script
1291 class Something
1292 static this.val = 1
1293 endclass
1294 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001295 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296
1297 # Test for "static" cannot be followed by "public".
1298 lines =<< trim END
1299 vim9script
1300 class Something
1301 static public val = 1
1302 endclass
1303 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001304 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001305
1306 # A readonly class variable cannot be modified from a child class
1307 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001308 vim9script
1309 class A
1310 static ro_class_var = 40
1311 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001312
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001313 class B extends A
1314 def Foo()
1315 A.ro_class_var = 50
1316 enddef
1317 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001318
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001319 var b = B.new()
1320 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001321 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001322 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001323
Ernie Rael03042a22023-11-11 08:53:32 +01001324 # A protected class variable cannot be accessed from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001325 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001326 vim9script
1327 class A
1328 static _priv_class_var = 60
1329 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001330
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001331 class B extends A
1332 def Foo()
1333 var i = A._priv_class_var
1334 enddef
1335 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001336
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001337 var b = B.new()
1338 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001339 END
Ernie Rael03042a22023-11-11 08:53:32 +01001340 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001341
Ernie Rael03042a22023-11-11 08:53:32 +01001342 # A protected class variable cannot be modified from a child class
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001343 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001344 vim9script
1345 class A
1346 static _priv_class_var = 60
1347 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001348
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001349 class B extends A
1350 def Foo()
1351 A._priv_class_var = 0
1352 enddef
1353 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001354
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001355 var b = B.new()
1356 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001357 END
Ernie Rael03042a22023-11-11 08:53:32 +01001358 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_priv_class_var" in class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001359
1360 # Access from child class extending a class and from script context
1361 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001362 vim9script
1363 class A
1364 static ro_class_var = 10
1365 public static rw_class_var = 20
1366 static _priv_class_var = 30
1367 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001368
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001369 class B extends A
1370 def Foo()
1371 var x: number
1372 x = A.ro_class_var
1373 assert_equal(10, x)
1374 x = A.rw_class_var
1375 assert_equal(25, x)
1376 A.rw_class_var = 20
1377 assert_equal(20, A.rw_class_var)
1378 enddef
1379 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001380
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001381 assert_equal(10, A.ro_class_var)
1382 assert_equal(20, A.rw_class_var)
1383 A.rw_class_var = 25
1384 assert_equal(25, A.rw_class_var)
1385 var b = B.new()
1386 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001387 END
1388 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001389enddef
1390
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001391def Test_class_object_compare()
1392 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001393 vim9script
1394 class Item
1395 this.nr = 0
1396 this.name = 'xx'
1397 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001398 END
1399
1400 # used at the script level and in a compiled function
1401 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001402 var i1 = Item.new()
1403 assert_equal(i1, i1)
1404 assert_true(i1 is i1)
1405 var i2 = Item.new()
1406 assert_equal(i1, i2)
1407 assert_false(i1 is i2)
1408 var i3 = Item.new(0, 'xx')
1409 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001410
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001411 var io1 = Item.new(1, 'xx')
1412 assert_notequal(i1, io1)
1413 var io2 = Item.new(0, 'yy')
1414 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001415 END
1416
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001417 v9.CheckSourceSuccess(class_lines + test_lines)
1418 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001419 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001420
1421 for op in ['>', '>=', '<', '<=', '=~', '!~']
1422 var op_lines = [
1423 'var i1 = Item.new()',
1424 'var i2 = Item.new()',
1425 'echo i1 ' .. op .. ' i2',
1426 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001427 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001428 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001429 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001430 endfor
1431enddef
1432
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001433def Test_object_type()
1434 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001437 class One
1438 this.one = 1
1439 endclass
1440 class Two
1441 this.two = 2
1442 endclass
1443 class TwoMore extends Two
1444 this.more = 9
1445 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001446
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001447 var o: One = One.new()
1448 var t: Two = Two.new()
1449 var m: TwoMore = TwoMore.new()
1450 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001451
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001452 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001453 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001454 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001455
1456 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001457 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001458
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 class One
1460 this.one = 1
1461 endclass
1462 class Two
1463 this.two = 2
1464 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001466 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001467 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001468 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001469
1470 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001471 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001472
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001473 interface One
1474 def GetMember(): number
1475 endinterface
1476 class Two implements One
1477 this.one = 1
1478 def GetMember(): number
1479 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001480 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001481 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001483 var o: One = Two.new(5)
1484 assert_equal(5, o.GetMember())
1485 END
1486 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001487
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001488 lines =<< trim END
1489 vim9script
1490
1491 class Num
1492 this.n: number = 0
1493 endclass
1494
1495 def Ref(name: string): func(Num): Num
1496 return (arg: Num): Num => {
1497 return eval(name)(arg)
1498 }
1499 enddef
1500
1501 const Fn = Ref('Double')
1502 var Double = (m: Num): Num => Num.new(m.n * 2)
1503
1504 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001505 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001506 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001507enddef
1508
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001509def Test_class_member()
1510 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001511 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001512 vim9script
1513 class TextPos
1514 this.lnum = 1
1515 this.col = 1
1516 static counter = 0
1517 static _secret = 7
1518 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001519
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 static def AddToCounter(nr: number)
1521 counter += nr
1522 enddef
1523 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001524
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001525 assert_equal(0, TextPos.counter)
1526 TextPos.AddToCounter(3)
1527 assert_equal(3, TextPos.counter)
1528 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001529
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 def GetCounter(): number
1531 return TextPos.counter
1532 enddef
1533 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1536 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1537 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001538
Ernie Rael03042a22023-11-11 08:53:32 +01001539 assert_fails('echo TextPos._secret', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
1540 assert_fails('TextPos._secret = 8', 'E1333: Cannot access protected variable "_secret" in class "TextPos"')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001541
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001542 assert_equal(42, TextPos.anybody)
1543 TextPos.anybody = 12
1544 assert_equal(12, TextPos.anybody)
1545 TextPos.anybody += 5
1546 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001547 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001548 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001549
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001550 # example in the help
1551 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001552 vim9script
1553 class OtherThing
1554 this.size: number
1555 static totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001556
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001557 def new(this.size)
1558 totalSize += this.size
1559 enddef
1560 endclass
1561 assert_equal(0, OtherThing.totalSize)
1562 var to3 = OtherThing.new(3)
1563 assert_equal(3, OtherThing.totalSize)
1564 var to7 = OtherThing.new(7)
1565 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001566 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001567 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001568
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001569 # using static class member twice
1570 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001572
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001573 class HTML
1574 static author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001575
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001576 static def MacroSubstitute(s: string): string
1577 return substitute(s, '{{author}}', author, 'gi')
1578 enddef
1579 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001580
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001581 assert_equal('some text', HTML.MacroSubstitute('some text'))
1582 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001583 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001584 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001585
Ernie Rael03042a22023-11-11 08:53:32 +01001586 # access protected member in lambda
Bram Moolenaar62a69232023-01-24 15:07:04 +00001587 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001588 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001589
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001590 class Foo
1591 this._x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001593 def Add(n: number): number
1594 const F = (): number => this._x + n
1595 return F()
1596 enddef
1597 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001598
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001599 var foo = Foo.new()
1600 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001601 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001602 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001603
Ernie Rael03042a22023-11-11 08:53:32 +01001604 # access protected member in lambda body
h-east2bd6a092023-05-19 19:01:17 +01001605 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001606 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001607
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001608 class Foo
1609 this._x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001610
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001611 def Add(n: number): number
1612 var Lam = () => {
1613 this._x = this._x + n
1614 }
1615 Lam()
1616 return this._x
1617 enddef
1618 endclass
h-east2bd6a092023-05-19 19:01:17 +01001619
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001620 var foo = Foo.new()
1621 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001622 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001623 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001624
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001625 # check shadowing
1626 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001627 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001628
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001629 class Some
1630 static count = 0
1631 def Method(count: number)
1632 echo count
1633 enddef
1634 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001635
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001636 var s = Some.new()
1637 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001638 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001639 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001640
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001641 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001642 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001643 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001644
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001645 class Some
1646 static count = 0
1647 def Method(arg: number)
1648 var count = 3
1649 echo arg count
1650 enddef
1651 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001652
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var s = Some.new()
1654 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001655 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001656 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001657
1658 # Test for using an invalid type for a member variable
1659 lines =<< trim END
1660 vim9script
1661 class A
1662 this.val: xxx
1663 endclass
1664 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001665 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001666
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001667 # Test for setting a member on a null object
1668 lines =<< trim END
1669 vim9script
1670 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001671 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001672 endclass
1673
1674 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001675 var obj: A
1676 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001677 enddef
1678 F()
1679 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001680 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001681
1682 # Test for accessing a member on a null object
1683 lines =<< trim END
1684 vim9script
1685 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001687 endclass
1688
1689 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001690 var obj: A
1691 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001692 enddef
1693 F()
1694 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001695 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001696
1697 # Test for setting a member on a null object, at script level
1698 lines =<< trim END
1699 vim9script
1700 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001701 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001702 endclass
1703
1704 var obj: A
1705 obj.val = ""
1706 END
Ernie Rael4c8da022023-10-11 21:35:11 +02001707 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001708
1709 # Test for accessing a member on a null object, at script level
1710 lines =<< trim END
1711 vim9script
1712 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001713 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001714 endclass
1715
1716 var obj: A
1717 echo obj.val
1718 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001719 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001720
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001721 # Test for no space before or after the '=' when initializing a member
1722 # variable
1723 lines =<< trim END
1724 vim9script
1725 class A
1726 this.val: number= 10
1727 endclass
1728 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001729 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001730 lines =<< trim END
1731 vim9script
1732 class A
1733 this.val: number =10
1734 endclass
1735 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001736 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001737
1738 # Access a non-existing member
1739 lines =<< trim END
1740 vim9script
1741 class A
1742 endclass
1743 var a = A.new()
1744 var v = a.bar
1745 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02001746 v9.CheckSourceFailure(lines, 'E1326: Variable "bar" not found in object "A"', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001747enddef
1748
Ernie Raele6c9aa52023-10-06 19:55:52 +02001749" These messages should show the defining class of the variable (base class),
1750" not the class that did the reference (super class)
1751def Test_defining_class_message()
1752 var lines =<< trim END
1753 vim9script
1754
1755 class Base
1756 this._v1: list<list<number>>
1757 endclass
1758
1759 class Child extends Base
1760 endclass
1761
1762 var o = Child.new()
1763 var x = o._v1
1764 END
Ernie Rael03042a22023-11-11 08:53:32 +01001765 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 11)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001766 lines =<< trim END
1767 vim9script
1768
1769 class Base
1770 this._v1: list<list<number>>
1771 endclass
1772
1773 class Child extends Base
1774 endclass
1775
1776 def F()
1777 var o = Child.new()
1778 var x = o._v1
1779 enddef
1780 F()
1781 END
Ernie Rael03042a22023-11-11 08:53:32 +01001782 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001783 lines =<< trim END
1784 vim9script
1785
1786 class Base
1787 this.v1: list<list<number>>
1788 endclass
1789
1790 class Child extends Base
1791 endclass
1792
1793 var o = Child.new()
1794 o.v1 = []
1795 END
1796 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 11)
1797 lines =<< trim END
1798 vim9script
1799
1800 class Base
1801 this.v1: list<list<number>>
1802 endclass
1803
1804 class Child extends Base
1805 endclass
1806
1807 def F()
1808 var o = Child.new()
1809 o.v1 = []
1810 enddef
1811 F()
1812 END
1813
Ernie Rael03042a22023-11-11 08:53:32 +01001814 # Attempt to read a protected variable that is in the middle
Ernie Raele6c9aa52023-10-06 19:55:52 +02001815 # of the class hierarchy.
1816 v9.CheckSourceFailure(lines, 'E1335: Variable "v1" in class "Base" is not writable', 2)
1817 lines =<< trim END
1818 vim9script
1819
1820 class Base0
1821 endclass
1822
1823 class Base extends Base0
1824 this._v1: list<list<number>>
1825 endclass
1826
1827 class Child extends Base
1828 endclass
1829
1830 def F()
1831 var o = Child.new()
1832 var x = o._v1
1833 enddef
1834 F()
1835 END
Ernie Rael03042a22023-11-11 08:53:32 +01001836 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Base"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001837
Ernie Rael03042a22023-11-11 08:53:32 +01001838 # Attempt to read a protected variable that is at the start
Ernie Raele6c9aa52023-10-06 19:55:52 +02001839 # of the class hierarchy.
1840 lines =<< trim END
1841 vim9script
1842
1843 class Base0
1844 endclass
1845
1846 class Base extends Base0
1847 endclass
1848
1849 class Child extends Base
1850 this._v1: list<list<number>>
1851 endclass
1852
1853 def F()
1854 var o = Child.new()
1855 var x = o._v1
1856 enddef
1857 F()
1858 END
Ernie Rael03042a22023-11-11 08:53:32 +01001859 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "Child"', 2)
Ernie Raele6c9aa52023-10-06 19:55:52 +02001860enddef
1861
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001862func Test_class_garbagecollect()
1863 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001864 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001866 class Point
1867 this.p = [2, 3]
1868 static pl = ['a', 'b']
1869 static pd = {a: 'a', b: 'b'}
1870 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001871
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001872 echo Point.pl Point.pd
1873 call test_garbagecollect_now()
1874 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001875 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001876 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001877
1878 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001879 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001880
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001881 interface View
1882 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001883
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001884 class Widget
1885 this.view: View
1886 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001888 class MyView implements View
1889 this.widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001890
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001891 def new()
1892 # this will result in a circular reference to this object
1893 this.widget = Widget.new(this)
1894 enddef
1895 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001896
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001897 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001898
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001899 # overwrite "view", will be garbage-collected next
1900 view = MyView.new()
1901 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001902 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001903 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001904endfunc
1905
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001906" Test interface garbage collection
1907func Test_interface_garbagecollect()
1908 let lines =<< trim END
1909 vim9script
1910
1911 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001912 this.ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001913
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001914 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001915 endinterface
1916
1917 class A implements I
1918 static ro_class_var: number = 10
1919 public static rw_class_var: number = 20
1920 static _priv_class_var: number = 30
1921 this.ro_obj_var: number = 40
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001922 this._priv_obj_var: number = 60
1923
1924 static def _ClassBar(): number
1925 return _priv_class_var
1926 enddef
1927
1928 static def ClassFoo(): number
1929 return ro_class_var + rw_class_var + A._ClassBar()
1930 enddef
1931
1932 def _ObjBar(): number
1933 return this._priv_obj_var
1934 enddef
1935
1936 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001937 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001938 enddef
1939 endclass
1940
1941 assert_equal(60, A.ClassFoo())
1942 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001943 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001944 test_garbagecollect_now()
1945 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001946 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001947 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001948 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001949endfunc
1950
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001951def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001952 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001953 vim9script
1954 class Value
1955 this.value = 0
1956 static objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001957
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001958 def new(v: number)
1959 this.value = v
1960 ++objects
1961 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001962
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001963 static def GetCount(): number
1964 return objects
1965 enddef
1966 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001967
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001968 assert_equal(0, Value.GetCount())
1969 var v1 = Value.new(2)
1970 assert_equal(1, Value.GetCount())
1971 var v2 = Value.new(7)
1972 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001973 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001974 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001975
1976 # Test for cleaning up after a class definition failure when using class
1977 # functions.
1978 lines =<< trim END
1979 vim9script
1980 class A
1981 static def Foo()
1982 enddef
1983 aaa
1984 endclass
1985 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001986 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001987
1988 # Test for calling a class method from another class method without the class
1989 # name prefix.
1990 lines =<< trim END
1991 vim9script
1992 class A
1993 static myList: list<number> = [1]
1994 static def Foo(n: number)
1995 myList->add(n)
1996 enddef
1997 static def Bar()
1998 Foo(2)
1999 enddef
2000 def Baz()
2001 Foo(3)
2002 enddef
2003 endclass
2004 A.Bar()
2005 var a = A.new()
2006 a.Baz()
2007 assert_equal([1, 2, 3], A.myList)
2008 END
2009 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00002010enddef
2011
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002012def Test_class_defcompile()
2013 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002014 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002015
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 class C
2017 def Fo(i: number): string
2018 return i
2019 enddef
2020 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002022 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002023 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002024 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002025
2026 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002027 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002028
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002029 class C
2030 static def Fc(): number
2031 return 'x'
2032 enddef
2033 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002034
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002035 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002036 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002038
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002040 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002041
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002042 class C
2043 static def new()
2044 enddef
2045 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002046
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002047 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002048 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002049 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02002050
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002051 # Trying to compile a function using a non-existing class variable
2052 lines =<< trim END
2053 vim9script
2054 defcompile x.Foo()
2055 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002056 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002057
2058 # Trying to compile a function using a variable which is not a class
2059 lines =<< trim END
2060 vim9script
2061 var x: number
2062 defcompile x.Foo()
2063 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002064 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002065
2066 # Trying to compile a function without specifying the name
2067 lines =<< trim END
2068 vim9script
2069 class A
2070 endclass
2071 defcompile A.
2072 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002073 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002074
2075 # Trying to compile a non-existing class object member function
2076 lines =<< trim END
2077 vim9script
2078 class A
2079 endclass
2080 var a = A.new()
2081 defcompile a.Foo()
2082 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02002083 v9.CheckSourceFailureList(lines, ['E1326: Variable "Foo" not found in object "A"', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00002084enddef
2085
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002086def Test_class_object_to_string()
2087 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002088 vim9script
2089 class TextPosition
2090 this.lnum = 1
2091 this.col = 22
2092 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002093
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002094 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002095
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002096 var pos = TextPosition.new()
2097 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002098 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002099 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00002100enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00002101
Bram Moolenaar554d0312023-01-05 19:59:18 +00002102def Test_interface_basics()
2103 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002104 vim9script
2105 interface Something
2106 this.ro_var: list<number>
2107 def GetCount(): number
2108 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002109 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002110 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002111
2112 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002113 interface SomethingWrong
2114 static count = 7
2115 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002117 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002118
2119 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002120 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00002121
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002122 interface Some
2123 this.value: number
2124 def Method(value: number)
2125 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00002126 END
h-east61378a12023-04-18 19:07:29 +01002127 # The argument name and the object member name are the same, but this is not a
2128 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002129 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002130
2131 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002132 vim9script
2133 interface somethingWrong
2134 static count = 7
2135 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002136 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002137 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002138
2139 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002140 vim9script
2141 interface SomethingWrong
2142 this.value: string
2143 this.count = 7
2144 def GetCount(): number
2145 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002146 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002147 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002148
2149 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002150 vim9script
2151 interface SomethingWrong
2152 this.value: string
2153 this.count: number
2154 def GetCount(): number
2155 return 5
2156 enddef
2157 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002158 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002159 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002160
2161 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002162 vim9script
2163 export interface EnterExit
2164 def Enter(): void
2165 def Exit(): void
2166 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002167 END
2168 writefile(lines, 'XdefIntf.vim', 'D')
2169
2170 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 vim9script
2172 import './XdefIntf.vim' as defIntf
2173 export def With(ee: defIntf.EnterExit, F: func)
2174 ee.Enter()
2175 try
2176 F()
2177 finally
2178 ee.Exit()
2179 endtry
2180 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002181 END
2182 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002183
2184 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002185 vim9script
2186 export abstract class EnterExit
2187 def Enter(): void
2188 enddef
2189 def Exit(): void
2190 enddef
2191 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002192 END
2193 writefile(imported, 'XdefIntf2.vim', 'D')
2194
2195 lines[1] = " import './XdefIntf2.vim' as defIntf"
2196 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002197enddef
2198
Bram Moolenaar94674f22023-01-06 18:42:20 +00002199def Test_class_implements_interface()
2200 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002201 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002203 interface Some
2204 this.count: number
2205 def Method(nr: number)
2206 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002207
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002208 class SomeImpl implements Some
2209 this.count: number
2210 def Method(nr: number)
2211 echo nr
2212 enddef
2213 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002214
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002215 interface Another
2216 this.member: string
2217 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002218
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002219 class AnotherImpl implements Some, Another
2220 this.member = 'abc'
2221 this.count = 20
2222 def Method(nr: number)
2223 echo nr
2224 enddef
2225 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002226 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002227 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002228
2229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002230 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002231
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002232 interface Some
2233 this.count: number
2234 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002235
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002236 class SomeImpl implements Some implements Some
2237 this.count: number
2238 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002239 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002240 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002241
2242 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002243 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002244
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002245 interface Some
2246 this.count: number
2247 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002249 class SomeImpl implements Some, Some
2250 this.count: number
2251 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002252 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002253 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002254
2255 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002256 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002257
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002258 interface Some
2259 this.counter: number
2260 def Method(nr: number)
2261 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002262
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002263 class SomeImpl implements Some
2264 this.count: number
2265 def Method(nr: number)
2266 echo nr
2267 enddef
2268 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002269 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002270 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002271
2272 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002273 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002274
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002275 interface Some
2276 this.count: number
2277 def Methods(nr: number)
2278 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002279
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002280 class SomeImpl implements Some
2281 this.count: number
2282 def Method(nr: number)
2283 echo nr
2284 enddef
2285 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002286 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002287 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002288
2289 # Check different order of members in class and interface works.
2290 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002291 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002292
2293 interface Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002294 this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002295 this.errpos: number
2296 endinterface
2297
2298 # order of members is opposite of interface
2299 class Failure implements Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002300 public this.lnum: number = 5
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002301 this.errpos: number = 42
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002302 this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002303 endclass
2304
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002305 def Test()
2306 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002307
2308 assert_equal('label', result.label)
2309 assert_equal(42, result.errpos)
2310 enddef
2311
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002312 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002313 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002314 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002315
2316 # Interface name after "extends" doesn't end in a space or NUL character
2317 lines =<< trim END
2318 vim9script
2319 interface A
2320 endinterface
2321 class B extends A"
2322 endclass
2323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002324 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002325
2326 # Trailing characters after a class name
2327 lines =<< trim END
2328 vim9script
2329 class A bbb
2330 endclass
2331 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002332 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002333
2334 # using "implements" with a non-existing class
2335 lines =<< trim END
2336 vim9script
2337 class A implements B
2338 endclass
2339 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002340 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002341
2342 # using "implements" with a regular class
2343 lines =<< trim END
2344 vim9script
2345 class A
2346 endclass
2347 class B implements A
2348 endclass
2349 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002350 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002351
2352 # using "implements" with a variable
2353 lines =<< trim END
2354 vim9script
2355 var T: number = 10
2356 class A implements T
2357 endclass
2358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002359 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002360
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002361 # implements should be followed by a white space
2362 lines =<< trim END
2363 vim9script
2364 interface A
2365 endinterface
2366 class B implements A;
2367 endclass
2368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002369 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002370
LemonBoyc5d27442023-08-19 13:02:35 +02002371 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002372 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002373
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002374 interface One
2375 def IsEven(nr: number): bool
2376 endinterface
2377 class Two implements One
2378 def IsEven(nr: number): string
2379 enddef
2380 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002381 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002383
2384 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002385 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002386
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002387 interface One
2388 def IsEven(nr: number): bool
2389 endinterface
2390 class Two implements One
2391 def IsEven(nr: bool): bool
2392 enddef
2393 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002394 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002395 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002396
2397 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002398 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002399
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002400 interface One
2401 def IsEven(nr: number): bool
2402 endinterface
2403 class Two implements One
2404 def IsEven(nr: number, ...extra: list<number>): bool
2405 enddef
2406 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002407 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002408 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool', 9)
Ernie Raelcf138d42023-09-06 20:45:03 +02002409
2410 # access superclass interface members from subclass, mix variable order
2411 lines =<< trim END
2412 vim9script
2413
2414 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002415 this.mvar1: number
2416 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002417 endinterface
2418
2419 # NOTE: the order is swapped
2420 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002421 this.mvar2: number
2422 this.mvar1: number
2423 public static svar2: number
2424 public static svar1: number
2425 def new()
2426 svar1 = 11
2427 svar2 = 12
2428 this.mvar1 = 111
2429 this.mvar2 = 112
2430 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002431 endclass
2432
2433 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002434 def new()
2435 this.mvar1 = 121
2436 this.mvar2 = 122
2437 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002438 endclass
2439
2440 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002441 def new()
2442 this.mvar1 = 131
2443 this.mvar2 = 132
2444 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002445 endclass
2446
Ernie Raelcf138d42023-09-06 20:45:03 +02002447 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002448 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002449 enddef
2450
2451 var oa = A.new()
2452 var ob = B.new()
2453 var oc = C.new()
2454
Ernie Raelcf138d42023-09-06 20:45:03 +02002455 assert_equal([111, 112], F2(oa))
2456 assert_equal([121, 122], F2(ob))
2457 assert_equal([131, 132], F2(oc))
2458 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002459 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002460
2461 # Access superclass interface members from subclass, mix variable order.
2462 # Two interfaces, one on A, one on B; each has both kinds of variables
2463 lines =<< trim END
2464 vim9script
2465
2466 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002467 this.mvar1: number
2468 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002469 endinterface
2470
2471 interface I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002472 this.mvar3: number
2473 this.mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002474 endinterface
2475
2476 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002477 public static svar1: number
2478 public static svar2: number
2479 this.mvar1: number
2480 this.mvar2: number
2481 def new()
2482 svar1 = 11
2483 svar2 = 12
2484 this.mvar1 = 111
2485 this.mvar2 = 112
2486 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002487 endclass
2488
2489 class B extends A implements I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002490 static svar3: number
2491 static svar4: number
2492 this.mvar3: number
2493 this.mvar4: number
2494 def new()
2495 svar3 = 23
2496 svar4 = 24
2497 this.mvar1 = 121
2498 this.mvar2 = 122
2499 this.mvar3 = 123
2500 this.mvar4 = 124
2501 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002502 endclass
2503
2504 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002505 public static svar5: number
2506 def new()
2507 svar5 = 1001
2508 this.mvar1 = 131
2509 this.mvar2 = 132
2510 this.mvar3 = 133
2511 this.mvar4 = 134
2512 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002513 endclass
2514
Ernie Raelcf138d42023-09-06 20:45:03 +02002515 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002516 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002517 enddef
2518
Ernie Raelcf138d42023-09-06 20:45:03 +02002519 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002520 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002521 enddef
2522
Ernie Raelcf138d42023-09-06 20:45:03 +02002523 var oa = A.new()
2524 var ob = B.new()
2525 var oc = C.new()
2526
Ernie Raelcf138d42023-09-06 20:45:03 +02002527 assert_equal([[111, 112]], [F2(oa)])
2528 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2529 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002530 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002531 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002532
2533 # Using two interface names without a space after the ","
2534 lines =<< trim END
2535 vim9script
2536 interface A
2537 endinterface
2538 interface B
2539 endinterface
2540 class C implements A,B
2541 endclass
2542 END
2543 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2544
2545 # No interface name after a comma
2546 lines =<< trim END
2547 vim9script
2548 interface A
2549 endinterface
2550 class B implements A,
2551 endclass
2552 END
2553 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2554
2555 # No interface name after implements
2556 lines =<< trim END
2557 vim9script
2558 class A implements
2559 endclass
2560 END
2561 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002562enddef
2563
Bram Moolenaard0200c82023-01-28 15:19:40 +00002564def Test_call_interface_method()
2565 var lines =<< trim END
2566 vim9script
2567 interface Base
2568 def Enter(): void
2569 endinterface
2570
2571 class Child implements Base
2572 def Enter(): void
2573 g:result ..= 'child'
2574 enddef
2575 endclass
2576
2577 def F(obj: Base)
2578 obj.Enter()
2579 enddef
2580
2581 g:result = ''
2582 F(Child.new())
2583 assert_equal('child', g:result)
2584 unlet g:result
2585 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002586 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002587
2588 lines =<< trim END
2589 vim9script
2590 class Base
2591 def Enter(): void
2592 g:result ..= 'base'
2593 enddef
2594 endclass
2595
2596 class Child extends Base
2597 def Enter(): void
2598 g:result ..= 'child'
2599 enddef
2600 endclass
2601
2602 def F(obj: Base)
2603 obj.Enter()
2604 enddef
2605
2606 g:result = ''
2607 F(Child.new())
2608 assert_equal('child', g:result)
2609 unlet g:result
2610 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002611 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002612
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002613 # method of interface returns a value
2614 lines =<< trim END
2615 vim9script
2616 interface Base
2617 def Enter(): string
2618 endinterface
2619
2620 class Child implements Base
2621 def Enter(): string
2622 g:result ..= 'child'
2623 return "/resource"
2624 enddef
2625 endclass
2626
2627 def F(obj: Base)
2628 var r = obj.Enter()
2629 g:result ..= r
2630 enddef
2631
2632 g:result = ''
2633 F(Child.new())
2634 assert_equal('child/resource', g:result)
2635 unlet g:result
2636 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002637 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002638
2639 lines =<< trim END
2640 vim9script
2641 class Base
2642 def Enter(): string
2643 return null_string
2644 enddef
2645 endclass
2646
2647 class Child extends Base
2648 def Enter(): string
2649 g:result ..= 'child'
2650 return "/resource"
2651 enddef
2652 endclass
2653
2654 def F(obj: Base)
2655 var r = obj.Enter()
2656 g:result ..= r
2657 enddef
2658
2659 g:result = ''
2660 F(Child.new())
2661 assert_equal('child/resource', g:result)
2662 unlet g:result
2663 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002664 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002665
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002666 # No class that implements the interface.
2667 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002668 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002669
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002670 interface IWithEE
2671 def Enter(): any
2672 def Exit(): void
2673 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002674
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002675 def With1(ee: IWithEE, F: func)
2676 var r = ee.Enter()
2677 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002678
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002679 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002680 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002681 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002682enddef
2683
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002684def Test_class_used_as_type()
2685 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002686 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002687
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002688 class Point
2689 this.x = 0
2690 this.y = 0
2691 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002692
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002693 var p: Point
2694 p = Point.new(2, 33)
2695 assert_equal(2, p.x)
2696 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002697 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002698 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002699
2700 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002701 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002702
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002703 interface HasX
2704 this.x: number
2705 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002706
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002707 class Point implements HasX
2708 this.x = 0
2709 this.y = 0
2710 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002711
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002712 var p: Point
2713 p = Point.new(2, 33)
2714 var hx = p
2715 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002716 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002717 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002718
2719 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002720 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002721
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002722 class Point
2723 this.x = 0
2724 this.y = 0
2725 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002726
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002727 var p: Point
2728 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002729 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002730 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002731enddef
2732
Bram Moolenaar83677162023-01-08 19:54:10 +00002733def Test_class_extends()
2734 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002735 vim9script
2736 class Base
2737 this.one = 1
2738 def GetOne(): number
2739 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002740 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002741 endclass
2742 class Child extends Base
2743 this.two = 2
2744 def GetTotal(): number
2745 return this.one + this.two
2746 enddef
2747 endclass
2748 var o = Child.new()
2749 assert_equal(1, o.one)
2750 assert_equal(2, o.two)
2751 assert_equal(1, o.GetOne())
2752 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002753 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002754 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002755
2756 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002757 vim9script
2758 class Base
2759 this.one = 1
2760 endclass
2761 class Child extends Base
2762 this.two = 2
2763 endclass
2764 var o = Child.new(3, 44)
2765 assert_equal(3, o.one)
2766 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002767 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002768 v9.CheckSourceSuccess(lines)
2769
2770 lines =<< trim END
2771 vim9script
2772 class Base
2773 this.one = 1
2774 endclass
2775 class Child extends Base extends Base
2776 this.two = 2
2777 endclass
2778 END
2779 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2780
2781 lines =<< trim END
2782 vim9script
2783 class Child extends BaseClass
2784 this.two = 2
2785 endclass
2786 END
2787 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2788
2789 lines =<< trim END
2790 vim9script
2791 var SomeVar = 99
2792 class Child extends SomeVar
2793 this.two = 2
2794 endclass
2795 END
2796 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2797
2798 lines =<< trim END
2799 vim9script
2800 class Base
2801 this.name: string
2802 def ToString(): string
2803 return this.name
2804 enddef
2805 endclass
2806
2807 class Child extends Base
2808 this.age: number
2809 def ToString(): string
2810 return super.ToString() .. ': ' .. this.age
2811 enddef
2812 endclass
2813
2814 var o = Child.new('John', 42)
2815 assert_equal('John: 42', o.ToString())
2816 END
2817 v9.CheckSourceSuccess(lines)
2818
2819 lines =<< trim END
2820 vim9script
2821 class Child
2822 this.age: number
2823 def ToString(): number
2824 return this.age
2825 enddef
2826 def ToString(): string
2827 return this.age
2828 enddef
2829 endclass
2830 END
2831 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2832
2833 lines =<< trim END
2834 vim9script
2835 class Child
2836 this.age: number
2837 def ToString(): string
2838 return super .ToString() .. ': ' .. this.age
2839 enddef
2840 endclass
2841 var o = Child.new(42)
2842 echo o.ToString()
2843 END
2844 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2845
2846 lines =<< trim END
2847 vim9script
2848 class Base
2849 this.name: string
2850 def ToString(): string
2851 return this.name
2852 enddef
2853 endclass
2854
2855 var age = 42
2856 def ToString(): string
2857 return super.ToString() .. ': ' .. age
2858 enddef
2859 echo ToString()
2860 END
2861 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2862
2863 lines =<< trim END
2864 vim9script
2865 class Child
2866 this.age: number
2867 def ToString(): string
2868 return super.ToString() .. ': ' .. this.age
2869 enddef
2870 endclass
2871 var o = Child.new(42)
2872 echo o.ToString()
2873 END
2874 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2875
2876 lines =<< trim END
2877 vim9script
2878 class Base
2879 this.name: string
2880 static def ToString(): string
2881 return 'Base class'
2882 enddef
2883 endclass
2884
2885 class Child extends Base
2886 this.age: number
2887 def ToString(): string
2888 return Base.ToString() .. ': ' .. this.age
2889 enddef
2890 endclass
2891
2892 var o = Child.new('John', 42)
2893 assert_equal('Base class: 42', o.ToString())
2894 END
2895 v9.CheckSourceSuccess(lines)
2896
2897 lines =<< trim END
2898 vim9script
2899 class Base
2900 this.value = 1
2901 def new(init: number)
2902 this.value = number + 1
2903 enddef
2904 endclass
2905 class Child extends Base
2906 def new()
2907 this.new(3)
2908 enddef
2909 endclass
2910 var c = Child.new()
2911 END
2912 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002913
2914 # base class with more than one object member
2915 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002916 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002917
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002918 class Result
2919 this.success: bool
2920 this.value: any = null
2921 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002922
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002923 class Success extends Result
2924 def new(this.value = v:none)
2925 this.success = true
2926 enddef
2927 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002928
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002929 var v = Success.new('asdf')
2930 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002931 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002932 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002933
2934 # class name after "extends" doesn't end in a space or NUL character
2935 lines =<< trim END
2936 vim9script
2937 class A
2938 endclass
2939 class B extends A"
2940 endclass
2941 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002942 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00002943enddef
2944
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002945def Test_using_base_class()
2946 var lines =<< trim END
2947 vim9script
2948
2949 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002950 def Enter(): any
2951 return null
2952 enddef
2953 def Exit(resource: any): void
2954 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002955 endclass
2956
2957 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002958 def Enter(): any
2959 return 42
2960 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002962 def Exit(resource: number): void
2963 g:result ..= '/exit'
2964 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002965 endclass
2966
2967 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 var r = ee.Enter()
2969 try
2970 g:result ..= r
2971 finally
2972 g:result ..= '/finally'
2973 ee.Exit(r)
2974 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002975 enddef
2976
2977 g:result = ''
2978 With(ChildEE.new())
2979 assert_equal('42/finally/exit', g:result)
2980 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002981 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002982 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002983
2984 # Using super, Child invokes Base method which has optional arg. #12471
2985 lines =<< trim END
2986 vim9script
2987
2988 class Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 this.success: bool = false
2990 def Method(arg = 0)
2991 this.success = true
2992 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002993 endclass
2994
2995 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002996 def new()
2997 super.Method()
2998 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002999 endclass
3000
3001 var obj = Child.new()
3002 assert_equal(true, obj.success)
3003 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003004 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00003005enddef
3006
Bram Moolenaara86655a2023-01-12 17:06:27 +00003007def Test_class_import()
3008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003009 vim9script
3010 export class Animal
3011 this.kind: string
3012 this.name: string
3013 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00003014 END
3015 writefile(lines, 'Xanimal.vim', 'D')
3016
3017 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003018 vim9script
3019 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00003020
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 var a: animal.Animal
3022 a = animal.Animal.new('fish', 'Eric')
3023 assert_equal('fish', a.kind)
3024 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00003025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003026 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
3027 assert_equal('cat', b.kind)
3028 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00003029 END
3030 v9.CheckScriptSuccess(lines)
3031enddef
3032
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003033def Test_abstract_class()
3034 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003035 vim9script
3036 abstract class Base
3037 this.name: string
3038 endclass
3039 class Person extends Base
3040 this.age: number
3041 endclass
3042 var p: Base = Person.new('Peter', 42)
3043 assert_equal('Peter', p.name)
3044 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003045 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003046 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003047
3048 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003049 vim9script
3050 abstract class Base
3051 this.name: string
3052 endclass
3053 class Person extends Base
3054 this.age: number
3055 endclass
3056 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003057 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003058 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003059
3060 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003061 abstract class Base
3062 this.name: string
3063 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003065 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003066
3067 # Abstract class cannot have a "new" function
3068 lines =<< trim END
3069 vim9script
3070 abstract class Base
3071 def new()
3072 enddef
3073 endclass
3074 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003075 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003076enddef
3077
Bram Moolenaar486fc252023-01-18 14:51:07 +00003078def Test_closure_in_class()
3079 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003080 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003081
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003082 class Foo
3083 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003085 def new()
3086 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3087 enddef
3088 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003089
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003090 Foo.new()
3091 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003092 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003093 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003094enddef
3095
Ernie Rael9ed53752023-12-11 17:40:46 +01003096def Test_construct_object_from_legacy()
3097 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003098 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003099 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003100
Ernie Rael9ed53752023-12-11 17:40:46 +01003101 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003102
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003103 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003104 def new(arg: string)
3105 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003106 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003107 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003108
Ernie Rael9ed53752023-12-11 17:40:46 +01003109 export def CreateA(...args: list<any>): A
3110 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003111 enddef
3112
Ernie Rael9ed53752023-12-11 17:40:46 +01003113 g:P = CreateA
3114 legacy call g:P('some_arg')
3115 assert_equal(true, newCalled)
3116 unlet g:P
3117 END
3118 v9.CheckSourceSuccess(lines)
3119
3120 lines =<< trim END
3121 vim9script
3122
3123 var newCalled = false
3124
3125 class A
3126 static def CreateA(options = {}): any
3127 return A.new()
3128 enddef
3129 def new()
3130 newCalled = true
3131 enddef
3132 endclass
3133
3134 g:P = A.CreateA
3135 legacy call g:P()
3136 assert_equal(true, newCalled)
3137 unlet g:P
3138 END
3139 v9.CheckSourceSuccess(lines)
3140
3141 # This also tests invoking "new()" with "call"
3142 lines =<< trim END
3143 vim9script
3144
3145 var createdObject: any
3146
3147 class A
3148 this.val1: number
3149 this.val2: number
3150 static def CreateA(...args: list<any>): any
3151 createdObject = call(A.new, args)
3152 return createdObject
3153 enddef
3154 endclass
3155
3156 g:P = A.CreateA
3157 legacy call g:P(3, 5)
3158 assert_equal(3, createdObject.val1)
3159 assert_equal(5, createdObject.val2)
3160 legacy call g:P()
3161 assert_equal(0, createdObject.val1)
3162 assert_equal(0, createdObject.val2)
3163 legacy call g:P(7)
3164 assert_equal(7, createdObject.val1)
3165 assert_equal(0, createdObject.val2)
3166 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003167 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003168 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003169enddef
3170
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003171def Test_defer_with_object()
3172 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003173 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003174
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003175 class CWithEE
3176 def Enter()
3177 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003178 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003179 def Exit()
3180 g:result ..= "exited"
3181 enddef
3182 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003183
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003184 def With(ee: CWithEE, F: func)
3185 ee.Enter()
3186 defer ee.Exit()
3187 F()
3188 enddef
3189
3190 g:result = ''
3191 var obj = CWithEE.new()
3192 obj->With(() => {
3193 g:result ..= "called/"
3194 })
3195 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003196 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003197 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003198 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003199
3200 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003201 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003202
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003203 class BaseWithEE
3204 def Enter()
3205 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003206 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003207 def Exit()
3208 g:result ..= "exited-base"
3209 enddef
3210 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003211
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003212 class CWithEE extends BaseWithEE
3213 def Enter()
3214 g:result ..= "entered-child/"
3215 enddef
3216 def Exit()
3217 g:result ..= "exited-child"
3218 enddef
3219 endclass
3220
3221 def With(ee: BaseWithEE, F: func)
3222 ee.Enter()
3223 defer ee.Exit()
3224 F()
3225 enddef
3226
3227 g:result = ''
3228 var obj = CWithEE.new()
3229 obj->With(() => {
3230 g:result ..= "called/"
3231 })
3232 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003233 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003234 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003235 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003236enddef
3237
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003238" The following test used to crash Vim (Github issue #12676)
3239def Test_extends_method_crashes_vim()
3240 var lines =<< trim END
3241 vim9script
3242
3243 class Observer
3244 endclass
3245
3246 class Property
3247 this.value: any
3248
3249 def Set(v: any)
3250 if v != this.value
3251 this.value = v
3252 endif
3253 enddef
3254
3255 def Register(observer: Observer)
3256 enddef
3257 endclass
3258
3259 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003260 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003261 endclass
3262
3263 def Observe(obj: Property, who: Observer)
3264 obj.Register(who)
3265 enddef
3266
3267 var p = Bool.new(false)
3268 var myObserver = Observer.new()
3269
3270 Observe(p, myObserver)
3271
3272 p.Set(true)
3273 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003274 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003275enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003276
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003277" Test for calling a method in a class that is extended
3278def Test_call_method_in_extended_class()
3279 var lines =<< trim END
3280 vim9script
3281
3282 var prop_init_called = false
3283 var prop_register_called = false
3284
3285 class Property
3286 def Init()
3287 prop_init_called = true
3288 enddef
3289
3290 def Register()
3291 prop_register_called = true
3292 enddef
3293 endclass
3294
3295 class Bool extends Property
3296 endclass
3297
3298 def Observe(obj: Property)
3299 obj.Register()
3300 enddef
3301
3302 var p = Property.new()
3303 Observe(p)
3304
3305 p.Init()
3306 assert_true(prop_init_called)
3307 assert_true(prop_register_called)
3308 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003309 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003310enddef
3311
LemonBoyafe04662023-08-23 21:08:11 +02003312def Test_instanceof()
3313 var lines =<< trim END
3314 vim9script
3315
3316 class Base1
3317 endclass
3318
3319 class Base2 extends Base1
3320 endclass
3321
3322 interface Intf1
3323 endinterface
3324
3325 class Mix1 implements Intf1
3326 endclass
3327
3328 class Base3 extends Mix1
3329 endclass
3330
3331 var b1 = Base1.new()
3332 var b2 = Base2.new()
3333 var b3 = Base3.new()
3334
3335 assert_true(instanceof(b1, Base1))
3336 assert_true(instanceof(b2, Base1))
3337 assert_false(instanceof(b1, Base2))
3338 assert_true(instanceof(b3, Mix1))
3339 assert_false(instanceof(b3, []))
3340 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003341
3342 def Foo()
3343 var a1 = Base1.new()
3344 var a2 = Base2.new()
3345 var a3 = Base3.new()
3346
3347 assert_true(instanceof(a1, Base1))
3348 assert_true(instanceof(a2, Base1))
3349 assert_false(instanceof(a1, Base2))
3350 assert_true(instanceof(a3, Mix1))
3351 assert_false(instanceof(a3, []))
3352 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3353 enddef
3354 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003355
3356 var o_null: Base1
3357 assert_false(instanceof(o_null, Base1))
3358
LemonBoyafe04662023-08-23 21:08:11 +02003359 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003360 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003361enddef
3362
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003363" Test for calling a method in the parent class that is extended partially.
3364" This used to fail with the 'E118: Too many arguments for function: Text' error
3365" message (Github issue #12524).
3366def Test_call_method_in_parent_class()
3367 var lines =<< trim END
3368 vim9script
3369
3370 class Widget
3371 this._lnum: number = 1
3372
3373 def SetY(lnum: number)
3374 this._lnum = lnum
3375 enddef
3376
3377 def Text(): string
3378 return ''
3379 enddef
3380 endclass
3381
3382 class Foo extends Widget
3383 def Text(): string
3384 return '<Foo>'
3385 enddef
3386 endclass
3387
3388 def Stack(w1: Widget, w2: Widget): list<Widget>
3389 w1.SetY(1)
3390 w2.SetY(2)
3391 return [w1, w2]
3392 enddef
3393
3394 var foo1 = Foo.new()
3395 var foo2 = Foo.new()
3396 var l = Stack(foo1, foo2)
3397 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003398 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003399enddef
3400
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003401" Test for calling methods from three levels of classes
3402def Test_multi_level_method_call()
3403 var lines =<< trim END
3404 vim9script
3405
3406 var A_func1: number = 0
3407 var A_func2: number = 0
3408 var A_func3: number = 0
3409 var B_func2: number = 0
3410 var B_func3: number = 0
3411 var C_func3: number = 0
3412
3413 class A
3414 def Func1()
3415 A_func1 += 1
3416 enddef
3417
3418 def Func2()
3419 A_func2 += 1
3420 enddef
3421
3422 def Func3()
3423 A_func3 += 1
3424 enddef
3425 endclass
3426
3427 class B extends A
3428 def Func2()
3429 B_func2 += 1
3430 enddef
3431
3432 def Func3()
3433 B_func3 += 1
3434 enddef
3435 endclass
3436
3437 class C extends B
3438 def Func3()
3439 C_func3 += 1
3440 enddef
3441 endclass
3442
3443 def A_CallFuncs(a: A)
3444 a.Func1()
3445 a.Func2()
3446 a.Func3()
3447 enddef
3448
3449 def B_CallFuncs(b: B)
3450 b.Func1()
3451 b.Func2()
3452 b.Func3()
3453 enddef
3454
3455 def C_CallFuncs(c: C)
3456 c.Func1()
3457 c.Func2()
3458 c.Func3()
3459 enddef
3460
3461 var cobj = C.new()
3462 A_CallFuncs(cobj)
3463 B_CallFuncs(cobj)
3464 C_CallFuncs(cobj)
3465 assert_equal(3, A_func1)
3466 assert_equal(0, A_func2)
3467 assert_equal(0, A_func3)
3468 assert_equal(3, B_func2)
3469 assert_equal(0, B_func3)
3470 assert_equal(3, C_func3)
3471 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003472 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003473enddef
3474
3475" Test for using members from three levels of classes
3476def Test_multi_level_member_access()
3477 var lines =<< trim END
3478 vim9script
3479
3480 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003481 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003482 endclass
3483
3484 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003485 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003486 endclass
3487
3488 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003489 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003490 endclass
3491
3492 def A_members(a: A)
3493 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003494 enddef
3495
3496 def B_members(b: B)
3497 b.val1 += 1
3498 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003499 enddef
3500
3501 def C_members(c: C)
3502 c.val1 += 1
3503 c.val2 += 1
3504 c.val3 += 1
3505 enddef
3506
3507 var cobj = C.new()
3508 A_members(cobj)
3509 B_members(cobj)
3510 C_members(cobj)
3511 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003512 assert_equal(2, cobj.val2)
3513 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003516enddef
3517
LemonBoy0ffc17a2023-08-20 18:09:11 +02003518" Test expansion of <stack> with class methods.
3519def Test_stack_expansion_with_methods()
3520 var lines =<< trim END
3521 vim9script
3522
3523 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003524 def M1()
3525 F0()
3526 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003527 endclass
3528
3529 def F0()
3530 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3531 enddef
3532
3533 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003534 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003535 enddef
3536
3537 F()
3538 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003539 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003540enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003541
3542" Test the return type of the new() constructor
3543def Test_new_return_type()
3544 # new() uses the default return type and there is no return statement
3545 var lines =<< trim END
3546 vim9script
3547
3548 class C
3549 this._bufnr: number
3550
3551 def new(this._bufnr)
3552 if !bufexists(this._bufnr)
3553 this._bufnr = -1
3554 endif
3555 enddef
3556 endclass
3557
3558 var c = C.new(12345)
3559 assert_equal('object<C>', typename(c))
3560
3561 var v1: C
3562 v1 = C.new(12345)
3563 assert_equal('object<C>', typename(v1))
3564
3565 def F()
3566 var v2: C
3567 v2 = C.new(12345)
3568 assert_equal('object<C>', typename(v2))
3569 enddef
3570 F()
3571 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003572 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003573
3574 # new() uses the default return type and an empty 'return' statement
3575 lines =<< trim END
3576 vim9script
3577
3578 class C
3579 this._bufnr: number
3580
3581 def new(this._bufnr)
3582 if !bufexists(this._bufnr)
3583 this._bufnr = -1
3584 return
3585 endif
3586 enddef
3587 endclass
3588
3589 var c = C.new(12345)
3590 assert_equal('object<C>', typename(c))
3591
3592 var v1: C
3593 v1 = C.new(12345)
3594 assert_equal('object<C>', typename(v1))
3595
3596 def F()
3597 var v2: C
3598 v2 = C.new(12345)
3599 assert_equal('object<C>', typename(v2))
3600 enddef
3601 F()
3602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003603 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003604
3605 # new() uses "any" return type and returns "this"
3606 lines =<< trim END
3607 vim9script
3608
3609 class C
3610 this._bufnr: number
3611
3612 def new(this._bufnr): any
3613 if !bufexists(this._bufnr)
3614 this._bufnr = -1
3615 return this
3616 endif
3617 enddef
3618 endclass
3619 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003620 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003621
3622 # new() uses 'Dict' return type and returns a Dict
3623 lines =<< trim END
3624 vim9script
3625
3626 class C
3627 this._state: dict<any>
3628
3629 def new(): dict<any>
3630 this._state = {}
3631 return this._state
3632 enddef
3633 endclass
3634
3635 var c = C.new()
3636 assert_equal('object<C>', typename(c))
3637 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003638 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003639enddef
3640
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003641" Test for checking a member initialization type at run time.
3642def Test_runtime_type_check_for_member_init()
3643 var lines =<< trim END
3644 vim9script
3645
3646 var retnum: bool = false
3647
3648 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003649 retnum = !retnum
3650 if retnum
3651 return 1
3652 else
3653 return "hello"
3654 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003655 enddef
3656
3657 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003658 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003659 endclass
3660
3661 var c1 = C.new()
3662 var c2 = C.new()
3663 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003664 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003665enddef
3666
3667" Test for locking a variable referring to an object and reassigning to another
3668" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003669def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003670 var lines =<< trim END
3671 vim9script
3672
3673 class C
3674 this.val: number
3675 def new(this.val)
3676 enddef
3677 endclass
3678
3679 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3680 lockvar 2 some_dict
3681
3682 var current: C
3683 current = some_dict['c']
3684 assert_equal(3, current.val)
3685 current = some_dict['b']
3686 assert_equal(2, current.val)
3687
3688 def F()
3689 current = some_dict['c']
3690 enddef
3691
3692 def G()
3693 current = some_dict['b']
3694 enddef
3695
3696 F()
3697 assert_equal(3, current.val)
3698 G()
3699 assert_equal(2, current.val)
3700 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003701 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003702enddef
3703
Ernie Raelee865f32023-09-29 19:53:55 +02003704" Test trying to lock an object variable from various places
3705def Test_lockvar_object_variable()
3706 # An object variable lockvar has several cases:
3707 # object method, scriptlevel, scriplevel from :def, :def arg
3708 # method arg, static method arg.
3709 # Also different depths
3710
Ernie Raelee865f32023-09-29 19:53:55 +02003711 #
3712 # lockvar of read-only object variable
3713 #
3714
3715 # read-only lockvar from object method
3716 var lines =<< trim END
3717 vim9script
3718
3719 class C
3720 this.val1: number
3721 def Lock()
3722 lockvar this.val1
3723 enddef
3724 endclass
3725 var o = C.new(3)
3726 o.Lock()
3727 END
Ernie Rael64885642023-10-04 20:16:22 +02003728 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003729
3730 # read-only lockvar from scriptlevel
3731 lines =<< trim END
3732 vim9script
3733
3734 class C
3735 this.val2: number
3736 endclass
3737 var o = C.new(3)
3738 lockvar o.val2
3739 END
3740 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3741
3742 # read-only lockvar of scriptlevel variable from def
3743 lines =<< trim END
3744 vim9script
3745
3746 class C
3747 this.val3: number
3748 endclass
3749 var o = C.new(3)
3750 def Lock()
3751 lockvar o.val3
3752 enddef
3753 Lock()
3754 END
3755 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3756
3757 # read-only lockvar of def argument variable
3758 lines =<< trim END
3759 vim9script
3760
3761 class C
3762 this.val4: number
3763 endclass
3764 def Lock(o: C)
3765 lockvar o.val4
3766 enddef
3767 Lock(C.new(3))
3768 END
3769 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3770
3771 # TODO: the following tests use type "any" for argument. Need a run time
3772 # check for access. Probably OK as is for now.
3773
3774 # read-only lockvar from object method arg
3775 lines =<< trim END
3776 vim9script
3777
3778 class C
3779 this.val5: number
3780 def Lock(o_any: any)
3781 lockvar o_any.val5
3782 enddef
3783 endclass
3784 var o = C.new(3)
3785 o.Lock(C.new(5))
3786 END
Ernie Rael64885642023-10-04 20:16:22 +02003787 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003788
3789 # read-only lockvar from class method arg
3790 lines =<< trim END
3791 vim9script
3792
3793 class C
3794 this.val6: number
3795 static def Lock(o_any: any)
3796 lockvar o_any.val6
3797 enddef
3798 endclass
3799 var o = C.new(3)
3800 C.Lock(o)
3801 END
Ernie Rael64885642023-10-04 20:16:22 +02003802 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003803
3804 #
3805 # lockvar of public object variable
3806 #
3807
3808 # lockvar from object method
3809 lines =<< trim END
3810 vim9script
3811
3812 class C
3813 public this.val1: number
3814 def Lock()
3815 lockvar this.val1
3816 enddef
3817 endclass
3818 var o = C.new(3)
3819 o.Lock()
3820 END
3821 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3822
3823 # lockvar from scriptlevel
3824 lines =<< trim END
3825 vim9script
3826
3827 class C
3828 public this.val2: number
3829 endclass
3830 var o = C.new(3)
3831 lockvar o.val2
3832 END
3833 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3834
3835 # lockvar of scriptlevel variable from def
3836 lines =<< trim END
3837 vim9script
3838
3839 class C
3840 public this.val3: number
3841 endclass
3842 var o = C.new(3)
3843 def Lock()
3844 lockvar o.val3
3845 enddef
3846 Lock()
3847 END
3848 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3849
3850 # lockvar of def argument variable
3851 lines =<< trim END
3852 vim9script
3853
3854 class C
3855 public this.val4: number
3856 endclass
3857 def Lock(o: C)
3858 lockvar o.val4
3859 enddef
3860 Lock(C.new(3))
3861 END
3862 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3863
3864 # lockvar from object method arg
3865 lines =<< trim END
3866 vim9script
3867
3868 class C
3869 public this.val5: number
3870 def Lock(o_any: any)
3871 lockvar o_any.val5
3872 enddef
3873 endclass
3874 var o = C.new(3)
3875 o.Lock(C.new(5))
3876 END
3877 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3878
3879 # lockvar from class method arg
3880 lines =<< trim END
3881 vim9script
3882
3883 class C
3884 public this.val6: number
3885 static def Lock(o_any: any)
3886 lockvar o_any.val6
3887 enddef
3888 endclass
3889 var o = C.new(3)
3890 C.Lock(o)
3891 END
3892 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3893enddef
3894
3895" Test trying to lock a class variable from various places
3896def Test_lockvar_class_variable()
3897
3898 # lockvar bare static from object method
3899 var lines =<< trim END
3900 vim9script
3901
3902 class C
3903 public static sval1: number
3904 def Lock()
3905 lockvar sval1
3906 enddef
3907 endclass
3908 var o = C.new()
3909 o.Lock()
3910 END
3911 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3912
3913 # lockvar C.static from object method
3914 lines =<< trim END
3915 vim9script
3916
3917 class C
3918 public static sval2: number
3919 def Lock()
3920 lockvar C.sval2
3921 enddef
3922 endclass
3923 var o = C.new()
3924 o.Lock()
3925 END
3926 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3927
3928 # lockvar bare static from class method
3929 lines =<< trim END
3930 vim9script
3931
3932 class C
3933 public static sval3: number
3934 static def Lock()
3935 lockvar sval3
3936 enddef
3937 endclass
3938 C.Lock()
3939 END
3940 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
3941
3942 # lockvar C.static from class method
3943 lines =<< trim END
3944 vim9script
3945
3946 class C
3947 public static sval4: number
3948 static def Lock()
3949 lockvar C.sval4
3950 enddef
3951 endclass
3952 C.Lock()
3953 END
3954 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
3955
3956 # lockvar C.static from script level
3957 lines =<< trim END
3958 vim9script
3959
3960 class C
3961 public static sval5: number
3962 endclass
3963 lockvar C.sval5
3964 END
3965 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
3966
3967 # lockvar o.static from script level
3968 lines =<< trim END
3969 vim9script
3970
3971 class C
3972 public static sval6: number
3973 endclass
3974 var o = C.new()
3975 lockvar o.sval6
3976 END
3977 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
3978enddef
3979
3980" Test locking an argument to :def
3981def Test_lockvar_argument()
3982 # Lockvar a function arg
3983 var lines =<< trim END
3984 vim9script
3985
3986 def Lock(val: any)
3987 lockvar val
3988 enddef
3989
3990 var d = {a: 1, b: 2}
3991 Lock(d)
3992
3993 d->extend({c: 3})
3994 END
3995 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
3996
3997 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
3998 # class member in "C". This tests lval_root_is_arg.
3999 lines =<< trim END
4000 vim9script
4001
4002 class C
4003 public static sval: list<number>
4004 endclass
4005
4006 def Lock2(sval: any)
4007 lockvar sval
4008 enddef
4009
4010 var o = C.new()
4011 Lock2(o)
4012 END
4013 v9.CheckSourceSuccess(lines)
4014
4015 # Lock a class.
4016 lines =<< trim END
4017 vim9script
4018
4019 class C
4020 public static sval: list<number>
4021 endclass
4022
4023 def Lock2(sval: any)
4024 lockvar sval
4025 enddef
4026
4027 Lock2(C)
4028 END
4029 v9.CheckSourceSuccess(lines)
4030
4031 # Lock an object.
4032 lines =<< trim END
4033 vim9script
4034
4035 class C
4036 public static sval: list<number>
4037 endclass
4038
4039 def Lock2(sval: any)
4040 lockvar sval
4041 enddef
4042
4043 Lock2(C.new())
4044 END
4045 v9.CheckSourceSuccess(lines)
4046
4047 # In this case (unlike previous) "lockvar sval" is a class member.
4048 lines =<< trim END
4049 vim9script
4050
4051 class C
4052 public static sval: list<number>
4053 def Lock2()
4054 lockvar sval
4055 enddef
4056 endclass
4057
4058
4059 var o = C.new()
4060 o.Lock2()
4061 END
4062 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4063enddef
4064
4065" Test that this can be locked without error
4066def Test_lockvar_this()
4067 # lockvar this
4068 var lines =<< trim END
4069 vim9script
4070 class C
4071 def TLock()
4072 lockvar this
4073 enddef
4074 endclass
4075 var o = C.new()
4076 o.TLock()
4077 END
4078 v9.CheckSourceSuccess(lines)
4079
4080 # lockvar four (four letter word, but not this)
4081 lines =<< trim END
4082 vim9script
4083 class C
4084 def TLock4()
4085 var four: number
4086 lockvar four
4087 enddef
4088 endclass
4089 var o = C.new()
4090 o.TLock4()
4091 END
4092 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4093
4094 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4095 lines =<< trim END
4096 vim9script
4097 class C
4098 def TLock5()
4099 var this5: number
4100 lockvar this5
4101 enddef
4102 endclass
4103 var o = C.new()
4104 o.TLock5()
4105 END
4106 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4107enddef
4108
4109" Test some general lockvar cases
4110def Test_lockvar_general()
4111 # lockvar an object and a class. It does nothing
4112 var lines =<< trim END
4113 vim9script
4114 class C
4115 endclass
4116 var o = C.new()
4117 lockvar o
4118 lockvar C
4119 END
4120 v9.CheckSourceSuccess(lines)
4121
4122 # Lock a list element that's nested in an object variable from a :def
4123 lines =<< trim END
4124 vim9script
4125
4126 class C
4127 public this.val: list<list<number>> = [ [1], [2], [3] ]
4128 endclass
4129 def Lock2(obj: any)
4130 lockvar obj.val[1]
4131 enddef
4132
4133 var o = C.new()
4134 Lock2(o)
4135 o.val[0] = [9]
4136 assert_equal([ [9], [2], [3] ], o.val)
4137 try
4138 o.val[1] = [999]
4139 call assert_false(true, 'assign should have failed')
4140 catch
4141 assert_exception('E741:')
4142 endtry
4143 o.val[2] = [8]
4144 assert_equal([ [9], [2], [8] ], o.val)
4145 END
4146 v9.CheckSourceSuccess(lines)
4147
4148 # Lock a list element that's nested in an object variable from scriptlevel
4149 lines =<< trim END
4150 vim9script
4151
4152 class C
4153 public this.val: list<list<number>> = [ [1], [2], [3] ]
4154 endclass
4155
4156 var o = C.new()
4157 lockvar o.val[1]
4158 o.val[0] = [9]
4159 assert_equal([ [9], [2], [3] ], o.val)
4160 try
4161 o.val[1] = [999]
4162 call assert_false(true, 'assign should have failed')
4163 catch
4164 assert_exception('E741:')
4165 endtry
4166 o.val[2] = [8]
4167 assert_equal([ [9], [2], [8] ], o.val)
4168 END
4169 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004170
4171 # lock a script level variable from an object method
4172 lines =<< trim END
4173 vim9script
4174
4175 class C
4176 def Lock()
4177 lockvar l
4178 enddef
4179 endclass
4180
4181 var l = [1]
4182 C.new().Lock()
4183 l[0] = 11
4184 END
4185 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4186
Ernie Rael03042a22023-11-11 08:53:32 +01004187 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004188 # in an object fetched via a script level list
4189 lines =<< trim END
4190 vim9script
4191
4192 class C
4193 this._v1: list<list<number>>
4194 def Lock()
4195 lockvar lc[0]._v1[1]
4196 enddef
4197 endclass
4198
4199 var l = [[1], [2], [3]]
4200 var o = C.new(l)
4201 var lc: list<C> = [ o ]
4202
4203 o.Lock()
4204 l[0] = [22]
4205 l[1] = [33]
4206 END
4207 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4208
4209 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004210 # in a class that does not own the protected variable.
4211 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004212 # the same name.
4213 lines =<< trim END
4214 vim9script
4215
4216 class C2
4217 this._v1: list<list<number>>
4218 def Lock(obj: any)
4219 lockvar lc[0]._v1[1]
4220 enddef
4221 endclass
4222
4223 class C
4224 this._v1: list<list<number>>
4225 endclass
4226
4227 var l = [[1], [2], [3]]
4228 var o = C.new(l)
4229 var lc: list<C> = [ o ]
4230
4231 var o2 = C2.new()
4232 o2.Lock(o)
4233 END
Ernie Rael03042a22023-11-11 08:53:32 +01004234 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004235enddef
4236
Ernie Rael9771b2a2023-10-07 22:05:40 +02004237" Test builtin islocked()
4238def Test_lockvar_islocked()
4239 # Can't lock class/object variable
4240 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004241 # Lock item of variable's value (a list item)
4242 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004243 var lines =<< trim END
4244 vim9script
4245
4246 class C
4247 this.o0: list<list<number>> = [ [0], [1], [2]]
4248 this.o1: list<list<number>> = [[10], [11], [12]]
4249 static c0: list<list<number>> = [[20], [21], [22]]
4250 static c1: list<list<number>> = [[30], [31], [32]]
4251 endclass
4252
4253 def LockIt(arg: any)
4254 lockvar arg
4255 enddef
4256
4257 def UnlockIt(arg: any)
4258 unlockvar arg
4259 enddef
4260
4261 var obj = C.new()
4262 #lockvar obj.o1 # can't lock something you can't write to
4263
4264 try
4265 lockvar obj.o1 # can't lock something you can't write to
4266 call assert_false(1, '"lockvar obj.o1" should have failed')
4267 catch
4268 call assert_exception('E1335:')
4269 endtry
4270
4271 LockIt(obj.o1) # but can lock it's value
4272 assert_equal(1, islocked("obj.o1"))
4273 assert_equal(1, islocked("obj.o1[0]"))
4274 assert_equal(1, islocked("obj.o1[1]"))
4275 UnlockIt(obj.o1)
4276 assert_equal(0, islocked("obj.o1"))
4277 assert_equal(0, islocked("obj.o1[0]"))
4278
4279 lockvar obj.o1[0]
4280 assert_equal(0, islocked("obj.o1"))
4281 assert_equal(1, islocked("obj.o1[0]"))
4282 assert_equal(0, islocked("obj.o1[1]"))
4283 unlockvar obj.o1[0]
4284 assert_equal(0, islocked("obj.o1"))
4285 assert_equal(0, islocked("obj.o1[0]"))
4286
4287 # Same thing, but with a static
4288
4289 try
4290 lockvar C.c1 # can't lock something you can't write to
4291 call assert_false(1, '"lockvar C.c1" should have failed')
4292 catch
4293 call assert_exception('E1335:')
4294 endtry
4295
4296 LockIt(C.c1) # but can lock it's value
4297 assert_equal(1, islocked("C.c1"))
4298 assert_equal(1, islocked("C.c1[0]"))
4299 assert_equal(1, islocked("C.c1[1]"))
4300 UnlockIt(C.c1)
4301 assert_equal(0, islocked("C.c1"))
4302 assert_equal(0, islocked("C.c1[0]"))
4303
4304 lockvar C.c1[0]
4305 assert_equal(0, islocked("C.c1"))
4306 assert_equal(1, islocked("C.c1[0]"))
4307 assert_equal(0, islocked("C.c1[1]"))
4308 unlockvar C.c1[0]
4309 assert_equal(0, islocked("C.c1"))
4310 assert_equal(0, islocked("C.c1[0]"))
4311 END
4312 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004313
4314 # Do islocked() from an object method
4315 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004316 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004317 vim9script
4318
4319 var l0o0 = [ [0], [1], [2]]
4320 var l0o1 = [ [10], [11], [12]]
4321 var l0c0 = [[120], [121], [122]]
4322 var l0c1 = [[130], [131], [132]]
4323
4324 class C0
4325 this.o0: list<list<number>> = l0o0
4326 this.o1: list<list<number>> = l0o1
4327 static c0: list<list<number>> = l0c0
4328 static c1: list<list<number>> = l0c1
4329 def Islocked(arg: string): number
4330 return islocked(arg)
4331 enddef
4332 static def SIslocked(arg: string): number
4333 return islocked(arg)
4334 enddef
4335 endclass
4336
4337 var l2o0 = [[20000], [20001], [20002]]
4338 var l2o1 = [[20010], [20011], [20012]]
4339 var l2c0 = [[20120], [20121], [20122]]
4340 var l2c1 = [[20130], [20131], [20132]]
4341
4342 class C2
4343 this.o0: list<list<number>> = l2o0
4344 this.o1: list<list<number>> = l2o1
4345 static c0: list<list<number>> = l2c0
4346 static c1: list<list<number>> = l2c1
4347 def Islocked(arg: string): number
4348 return islocked(arg)
4349 enddef
4350 static def SIslocked(arg: string): number
4351 return islocked(arg)
4352 enddef
4353 endclass
4354
4355 var obj0 = C0.new()
4356 var obj2 = C2.new()
4357
4358 var l = [ obj0, null_object, obj2 ]
4359
4360 # lock list, object func access through script var expr
4361 assert_equal(0, obj0.Islocked("l[0].o0"))
4362 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4363 lockvar l0o0
4364 assert_equal(1, obj0.Islocked("l[0].o0"))
4365 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4366
4367 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4368
4369 # lock list element, object func access through script var expr
4370 lockvar l0o1[1]
4371 assert_equal(0, obj0.Islocked("this.o1[0]"))
4372 assert_equal(1, obj0.Islocked("this.o1[1]"))
4373
4374 assert_equal(0, obj0.Islocked("this.o1"))
4375 lockvar l0o1
4376 assert_equal(1, obj0.Islocked("this.o1"))
4377 unlockvar l0o1
4378
4379 lockvar l0c1[1]
4380
4381 # static by class name member expr from same class
4382 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4383 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4384 # static by bare name member expr from same class
4385 assert_equal(0, obj0.Islocked("c1[0]"))
4386 assert_equal(1, obj0.Islocked("c1[1]"))
4387
4388 # static by class name member expr from other class
4389 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4390 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4391 # static by bare name member expr from other class
4392 assert_equal(0, obj2.Islocked("c1[0]"))
4393 assert_equal(0, obj2.Islocked("c1[1]"))
4394
4395
4396 # static by bare name in same class
4397 assert_equal(0, obj0.Islocked("c0"))
4398 lockvar l0c0
4399 assert_equal(1, obj0.Islocked("c0"))
4400
4401 #
4402 # similar stuff, but use static method
4403 #
4404
4405 unlockvar l0o0
4406
4407 # lock list, object func access through script var expr
4408 assert_equal(0, C0.SIslocked("l[0].o0"))
4409 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4410 lockvar l0o0
4411 assert_equal(1, C0.SIslocked("l[0].o0"))
4412 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4413
4414 unlockvar l0o1
4415
4416 # can't access "this" from class method
4417 try
4418 C0.SIslocked("this.o1[0]")
4419 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4420 catch
4421 call assert_exception('E121: Undefined variable: this')
4422 endtry
4423
4424 lockvar l0c1[1]
4425
4426 # static by class name member expr from same class
4427 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4428 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4429 # static by bare name member expr from same class
4430 assert_equal(0, C0.SIslocked("c1[0]"))
4431 assert_equal(1, C0.SIslocked("c1[1]"))
4432
4433 # static by class name member expr from other class
4434 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4435 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4436 # static by bare name member expr from other class
4437 assert_equal(0, C2.SIslocked("c1[0]"))
4438 assert_equal(0, C2.SIslocked("c1[1]"))
4439
4440
4441 # static by bare name in same class
4442 unlockvar l0c0
4443 assert_equal(0, C0.SIslocked("c0"))
4444 lockvar l0c0
4445 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004446 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004447 v9.CheckSourceSuccess(lines)
4448
4449 # Check islocked class/object from various places.
4450 lines =<< trim END
4451 vim9script
4452
4453 class C
4454 def Islocked(arg: string): number
4455 return islocked(arg)
4456 enddef
4457 static def SIslocked(arg: string): number
4458 return islocked(arg)
4459 enddef
4460 endclass
4461 var obj = C.new()
4462
4463 # object method
4464 assert_equal(0, obj.Islocked("this"))
4465 assert_equal(0, obj.Islocked("C"))
4466
4467 # class method
4468 ### assert_equal(0, C.SIslocked("this"))
4469 assert_equal(0, C.SIslocked("C"))
4470
4471 #script level
4472 var v: number
4473 v = islocked("C")
4474 assert_equal(0, v)
4475 v = islocked("obj")
4476 assert_equal(0, v)
4477 END
4478 v9.CheckSourceSuccess(lines)
4479enddef
4480
4481def Test_lockvar_islocked_notfound()
4482 # Try non-existent things
4483 var lines =<< trim END
4484 vim9script
4485
4486 class C
4487 def Islocked(arg: string): number
4488 return islocked(arg)
4489 enddef
4490 static def SIslocked(arg: string): number
4491 return islocked(arg)
4492 enddef
4493 endclass
4494 var obj = C.new()
4495 assert_equal(-1, obj.Islocked("anywhere"))
4496 assert_equal(-1, C.SIslocked("notanywhere"))
4497 END
4498 v9.CheckSourceSuccess(lines)
4499
4500 # Something not found of the form "name1.name2" is an error
4501 lines =<< trim END
4502 vim9script
4503
4504 islocked("one.two")
4505 END
4506 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4507
4508 lines =<< trim END
4509 vim9script
4510
4511 class C
4512 this.val = { key: "value" }
4513 def Islocked(arg: string): number
4514 return islocked(arg)
4515 enddef
4516 endclass
4517 var obj = C.new()
4518 obj.Islocked("this.val.not_there"))
4519 END
4520 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4521
4522 lines =<< trim END
4523 vim9script
4524
4525 class C
4526 def Islocked(arg: string): number
4527 return islocked(arg)
4528 enddef
4529 endclass
4530 var obj = C.new()
4531 obj.Islocked("this.notobjmember")
4532 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004533 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004534
4535 # access a script variable through methods
4536 lines =<< trim END
4537 vim9script
4538
4539 var l = [1]
4540 class C
4541 def Islocked(arg: string): number
4542 return islocked(arg)
4543 enddef
4544 static def SIslocked(arg: string): number
4545 return islocked(arg)
4546 enddef
4547 endclass
4548 var obj = C.new()
4549 assert_equal(0, obj.Islocked("l"))
4550 assert_equal(0, C.SIslocked("l"))
4551 lockvar l
4552 assert_equal(1, obj.Islocked("l"))
4553 assert_equal(1, C.SIslocked("l"))
4554 END
4555 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004556enddef
4557
Ernie Rael03042a22023-11-11 08:53:32 +01004558" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004559def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004560 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004561 var lines =<< trim END
4562 vim9script
4563
4564 class A
4565 def _Foo(): number
4566 return 1234
4567 enddef
4568 endclass
4569 var a = A.new()
4570 a._Foo()
4571 END
Ernie Rael03042a22023-11-11 08:53:32 +01004572 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004573
Ernie Rael03042a22023-11-11 08:53:32 +01004574 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004575 lines =<< trim END
4576 vim9script
4577
4578 class A
4579 def _Foo(): number
4580 return 1234
4581 enddef
4582 endclass
4583 def T()
4584 var a = A.new()
4585 a._Foo()
4586 enddef
4587 T()
4588 END
Ernie Rael03042a22023-11-11 08:53:32 +01004589 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004590
Ernie Rael03042a22023-11-11 08:53:32 +01004591 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004592 lines =<< trim END
4593 vim9script
4594
4595 class A
4596 def _Foo(): number
4597 return 1234
4598 enddef
4599 def Bar(): number
4600 return this._Foo()
4601 enddef
4602 endclass
4603 var a = A.new()
4604 assert_equal(1234, a.Bar())
4605 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004606 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004607
Ernie Rael03042a22023-11-11 08:53:32 +01004608 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004609 lines =<< trim END
4610 vim9script
4611
4612 class A
4613 def _Foo(): number
4614 return 1234
4615 enddef
4616 def Bar(): number
4617 return this._Foo()
4618 enddef
4619 endclass
4620 def T()
4621 var a = A.new()
4622 assert_equal(1234, a.Bar())
4623 enddef
4624 T()
4625 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004626 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004627
Ernie Rael03042a22023-11-11 08:53:32 +01004628 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004629 lines =<< trim END
4630 vim9script
4631
4632 class A
4633 def _Foo(): number
4634 return 1234
4635 enddef
4636 def Bar(): number
4637 return _Foo()
4638 enddef
4639 endclass
4640 var a = A.new()
4641 a.Bar()
4642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004643 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004644
Ernie Rael03042a22023-11-11 08:53:32 +01004645 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004646 lines =<< trim END
4647 vim9script
4648
4649 class A
4650 def _Foo(): number
4651 return 1234
4652 enddef
4653 endclass
4654 A._Foo()
4655 END
Ernie Rael03042a22023-11-11 08:53:32 +01004656 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004657
Ernie Rael03042a22023-11-11 08:53:32 +01004658 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004659 lines =<< trim END
4660 vim9script
4661
4662 class A
4663 def _Foo()
4664 enddef
4665 def _Foo()
4666 enddef
4667 endclass
4668 var a = A.new()
4669 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004670 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004671
Ernie Rael03042a22023-11-11 08:53:32 +01004672 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004673 lines =<< trim END
4674 vim9script
4675
4676 class A
4677 def _Foo()
4678 enddef
4679 def Foo()
4680 enddef
4681 endclass
4682 var a = A.new()
4683 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004684 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004685
Ernie Rael03042a22023-11-11 08:53:32 +01004686 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004687 lines =<< trim END
4688 vim9script
4689
4690 class A
4691 def Foo()
4692 enddef
4693 def _Foo()
4694 enddef
4695 endclass
4696 var a = A.new()
4697 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004698 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004699
Ernie Rael03042a22023-11-11 08:53:32 +01004700 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004701 lines =<< trim END
4702 vim9script
4703
4704 class A
4705 def Foo(): number
4706 return 100
4707 enddef
4708 def _Bar(): number
4709 return 200
4710 enddef
4711 def _Baz()
4712 assert_equal(100, this.Foo())
4713 assert_equal(200, this._Bar())
4714 enddef
4715 def T()
4716 this._Baz()
4717 enddef
4718 endclass
4719 var a = A.new()
4720 a.T()
4721 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004722 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004723
Ernie Rael03042a22023-11-11 08:53:32 +01004724 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004725 lines =<< trim END
4726 vim9script
4727
4728 class A
4729 def _Foo(): number
4730 return 100
4731 enddef
4732 endclass
4733 class B
4734 def Foo(): number
4735 var a = A.new()
4736 a._Foo()
4737 enddef
4738 endclass
4739 var b = B.new()
4740 b.Foo()
4741 END
Ernie Rael03042a22023-11-11 08:53:32 +01004742 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004743
Ernie Rael03042a22023-11-11 08:53:32 +01004744 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004745 lines =<< trim END
4746 vim9script
4747 class A
4748 def _Foo(): number
4749 return 1234
4750 enddef
4751 endclass
4752 class B extends A
4753 def Bar()
4754 enddef
4755 endclass
4756 class C extends B
4757 def Baz(): number
4758 return this._Foo()
4759 enddef
4760 endclass
4761 var c = C.new()
4762 assert_equal(1234, c.Baz())
4763 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004764 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004765
Ernie Rael03042a22023-11-11 08:53:32 +01004766 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004767 lines =<< trim END
4768 vim9script
4769 class A
4770 def _Foo(): number
4771 return 1234
4772 enddef
4773 endclass
4774 class B extends A
4775 def Bar()
4776 enddef
4777 endclass
4778 class C extends B
4779 def Baz(): number
4780 enddef
4781 endclass
4782 var c = C.new()
4783 assert_equal(1234, c._Foo())
4784 END
Ernie Rael03042a22023-11-11 08:53:32 +01004785 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004786
4787 # Using "_" prefix in a method name should fail outside of a class
4788 lines =<< trim END
4789 vim9script
4790 def _Foo(): number
4791 return 1234
4792 enddef
4793 var a = _Foo()
4794 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004795 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004796enddef
4797
Ernie Rael03042a22023-11-11 08:53:32 +01004798" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004799def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004800 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004801 var lines =<< trim END
4802 vim9script
4803
4804 class A
4805 static def _Foo(): number
4806 return 1234
4807 enddef
4808 endclass
4809 A._Foo()
4810 END
Ernie Rael03042a22023-11-11 08:53:32 +01004811 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004812
Ernie Rael03042a22023-11-11 08:53:32 +01004813 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004814 lines =<< trim END
4815 vim9script
4816
4817 class A
4818 static def _Foo(): number
4819 return 1234
4820 enddef
4821 endclass
4822 def T()
4823 A._Foo()
4824 enddef
4825 T()
4826 END
Ernie Rael03042a22023-11-11 08:53:32 +01004827 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004828
Ernie Rael03042a22023-11-11 08:53:32 +01004829 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004830 lines =<< trim END
4831 vim9script
4832
4833 class A
4834 static def _Foo(): number
4835 return 1234
4836 enddef
4837 endclass
4838 var a = A.new()
4839 a._Foo()
4840 END
Ernie Rael03042a22023-11-11 08:53:32 +01004841 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004842
Ernie Rael03042a22023-11-11 08:53:32 +01004843 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004844 lines =<< trim END
4845 vim9script
4846
4847 class A
4848 static def _Foo(): number
4849 return 1234
4850 enddef
4851 endclass
4852 def T()
4853 var a = A.new()
4854 a._Foo()
4855 enddef
4856 T()
4857 END
Ernie Rael03042a22023-11-11 08:53:32 +01004858 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004859
Ernie Rael03042a22023-11-11 08:53:32 +01004860 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004861 lines =<< trim END
4862 vim9script
4863
4864 class A
4865 static def _Foo(): number
4866 return 1234
4867 enddef
4868 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004869 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004870 enddef
4871 endclass
4872 var a = A.new()
4873 a.Bar()
4874 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004875 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004876
Ernie Rael03042a22023-11-11 08:53:32 +01004877 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004878 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004879 lines =<< trim END
4880 vim9script
4881
4882 class A
4883 static def _Foo1(): number
4884 return 1234
4885 enddef
4886 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004887 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004888 enddef
4889 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004890 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004891 enddef
4892 endclass
4893 var a = A.new()
4894 a.Bar()
4895 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004896 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004897
Ernie Rael03042a22023-11-11 08:53:32 +01004898 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004899 lines =<< trim END
4900 vim9script
4901
4902 class A
4903 static def _Foo()
4904 enddef
4905 static def Foo()
4906 enddef
4907 endclass
4908 var a = A.new()
4909 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004910 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004911
Ernie Rael03042a22023-11-11 08:53:32 +01004912 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004913 lines =<< trim END
4914 vim9script
4915
4916 class A
4917 static def _Foo(): number
4918 return 1234
4919 enddef
4920 endclass
4921 class B
4922 def Foo(): number
4923 return A._Foo()
4924 enddef
4925 endclass
4926 var b = B.new()
4927 assert_equal(1234, b.Foo())
4928 END
Ernie Rael03042a22023-11-11 08:53:32 +01004929 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004930
Ernie Rael03042a22023-11-11 08:53:32 +01004931 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004932 lines =<< trim END
4933 vim9script
4934 class A
4935 static def _Foo(): number
4936 return 1234
4937 enddef
4938 endclass
4939 class B extends A
4940 def Bar()
4941 enddef
4942 endclass
4943 class C extends B
4944 def Baz(): number
4945 return A._Foo()
4946 enddef
4947 endclass
4948 var c = C.new()
4949 assert_equal(1234, c.Baz())
4950 END
Ernie Rael03042a22023-11-11 08:53:32 +01004951 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004952
Ernie Rael03042a22023-11-11 08:53:32 +01004953 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004954 lines =<< trim END
4955 vim9script
4956 class A
4957 static def _Foo(): number
4958 return 1234
4959 enddef
4960 endclass
4961 class B extends A
4962 def Bar()
4963 enddef
4964 endclass
4965 class C extends B
4966 static def Baz(): number
4967 return A._Foo()
4968 enddef
4969 endclass
4970 assert_equal(1234, C.Baz())
4971 END
Ernie Rael03042a22023-11-11 08:53:32 +01004972 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004973
Ernie Rael03042a22023-11-11 08:53:32 +01004974 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004975 lines =<< trim END
4976 vim9script
4977 class A
4978 static def _Foo(): number
4979 return 1234
4980 enddef
4981 endclass
4982 class B extends A
4983 def Bar()
4984 enddef
4985 endclass
4986 class C extends B
4987 def Baz(): number
4988 enddef
4989 endclass
4990 var c = C.new()
4991 assert_equal(1234, C._Foo())
4992 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004993 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004994enddef
4995
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004996" Test for using the return value of a class/object method as a function
4997" argument.
4998def Test_objmethod_funcarg()
4999 var lines =<< trim END
5000 vim9script
5001
5002 class C
5003 def Foo(): string
5004 return 'foo'
5005 enddef
5006 endclass
5007
5008 def Bar(a: number, s: string): string
5009 return s
5010 enddef
5011
5012 def Baz(c: C)
5013 assert_equal('foo', Bar(10, c.Foo()))
5014 enddef
5015
5016 var t = C.new()
5017 Baz(t)
5018 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005019 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005020
5021 lines =<< trim END
5022 vim9script
5023
5024 class C
5025 static def Foo(): string
5026 return 'foo'
5027 enddef
5028 endclass
5029
5030 def Bar(a: number, s: string): string
5031 return s
5032 enddef
5033
5034 def Baz()
5035 assert_equal('foo', Bar(10, C.Foo()))
5036 enddef
5037
5038 Baz()
5039 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005040 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005041enddef
5042
Ernie Raelcf138d42023-09-06 20:45:03 +02005043def Test_static_inheritence()
5044 # subclasses get their own static copy
5045 var lines =<< trim END
5046 vim9script
5047
5048 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005049 static _svar: number
5050 this._mvar: number
5051 def new()
5052 _svar = 1
5053 this._mvar = 101
5054 enddef
5055 def AccessObject(): number
5056 return this._mvar
5057 enddef
5058 def AccessStaticThroughObject(): number
5059 return _svar
5060 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005061 endclass
5062
5063 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005064 def new()
5065 this._mvar = 102
5066 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005067 endclass
5068
5069 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005070 def new()
5071 this._mvar = 103
5072 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005073
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005074 def AccessPrivateStaticThroughClassName(): number
5075 assert_equal(1, A._svar)
5076 return 444
5077 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005078 endclass
5079
5080 var oa = A.new()
5081 var ob = B.new()
5082 var oc = C.new()
5083 assert_equal(101, oa.AccessObject())
5084 assert_equal(102, ob.AccessObject())
5085 assert_equal(103, oc.AccessObject())
5086
Ernie Rael03042a22023-11-11 08:53:32 +01005087 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005088
5089 # verify object properly resolves to correct static
5090 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005091 assert_equal(1, ob.AccessStaticThroughObject())
5092 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005093 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005094 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005095enddef
5096
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005097" Test for declaring duplicate object and class members
5098def Test_dup_member_variable()
5099 # Duplicate member variable
5100 var lines =<< trim END
5101 vim9script
5102 class C
5103 this.val = 10
5104 this.val = 20
5105 endclass
5106 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005107 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005108
Ernie Rael03042a22023-11-11 08:53:32 +01005109 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005110 lines =<< trim END
5111 vim9script
5112 class C
5113 this._val = 10
5114 this._val = 20
5115 endclass
5116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005117 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005118
5119 # Duplicate public member variable
5120 lines =<< trim END
5121 vim9script
5122 class C
5123 public this.val = 10
5124 public this.val = 20
5125 endclass
5126 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005127 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005128
Ernie Rael03042a22023-11-11 08:53:32 +01005129 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005130 lines =<< trim END
5131 vim9script
5132 class C
5133 this.val = 10
5134 this._val = 20
5135 endclass
5136 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005137 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005138
Ernie Rael03042a22023-11-11 08:53:32 +01005139 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005140 lines =<< trim END
5141 vim9script
5142 class C
5143 this._val = 20
5144 public this.val = 10
5145 endclass
5146 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005147 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005148
5149 # Duplicate class member variable
5150 lines =<< trim END
5151 vim9script
5152 class C
5153 static s: string = "abc"
5154 static _s: string = "def"
5155 endclass
5156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005157 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005158
Ernie Rael03042a22023-11-11 08:53:32 +01005159 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005160 lines =<< trim END
5161 vim9script
5162 class C
5163 public static s: string = "abc"
5164 static _s: string = "def"
5165 endclass
5166 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005167 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005168
5169 # Duplicate class and object member variable
5170 lines =<< trim END
5171 vim9script
5172 class C
5173 static val = 10
5174 this.val = 20
5175 def new()
5176 enddef
5177 endclass
5178 var c = C.new()
5179 assert_equal(10, C.val)
5180 assert_equal(20, c.val)
5181 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005182 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005183
5184 # Duplicate object member variable in a derived class
5185 lines =<< trim END
5186 vim9script
5187 class A
5188 this.val = 10
5189 endclass
5190 class B extends A
5191 endclass
5192 class C extends B
5193 this.val = 20
5194 endclass
5195 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005196 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005197
Ernie Rael03042a22023-11-11 08:53:32 +01005198 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005199 lines =<< trim END
5200 vim9script
5201 class A
5202 this._val = 10
5203 endclass
5204 class B extends A
5205 endclass
5206 class C extends B
5207 this._val = 20
5208 endclass
5209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005210 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005211
Ernie Rael03042a22023-11-11 08:53:32 +01005212 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005213 lines =<< trim END
5214 vim9script
5215 class A
5216 this.val = 10
5217 endclass
5218 class B extends A
5219 endclass
5220 class C extends B
5221 this._val = 20
5222 endclass
5223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005224 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005225
5226 # Duplicate object member variable in a derived class
5227 lines =<< trim END
5228 vim9script
5229 class A
5230 this._val = 10
5231 endclass
5232 class B extends A
5233 endclass
5234 class C extends B
5235 this.val = 20
5236 endclass
5237 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005238 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005239
5240 # Two member variables with a common prefix
5241 lines =<< trim END
5242 vim9script
5243 class A
5244 public static svar2: number
5245 public static svar: number
5246 endclass
5247 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005248 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005249enddef
5250
Ernie Rael03042a22023-11-11 08:53:32 +01005251" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005252def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005253 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005254 var lines =<< trim END
5255 vim9script
5256 class A
5257 this._val = 10
5258 def GetVal(): number
5259 return this._val
5260 enddef
5261 endclass
5262 def T()
5263 var a = A.new()
5264 a._val = 20
5265 enddef
5266 T()
5267 END
Ernie Rael03042a22023-11-11 08:53:32 +01005268 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005269
Ernie Rael03042a22023-11-11 08:53:32 +01005270 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005271 lines =<< trim END
5272 vim9script
5273 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005274 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005275 endclass
5276 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005277 var a = A.new()
5278 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005279 enddef
5280 T()
5281 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005282 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005283
Ernie Rael03042a22023-11-11 08:53:32 +01005284 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005285 lines =<< trim END
5286 vim9script
5287 class A
5288 static _val = 10
5289 endclass
5290 def T()
5291 var a = A.new()
5292 var x = a._val
5293 enddef
5294 T()
5295 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005296 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005297
Ernie Rael03042a22023-11-11 08:53:32 +01005298 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005299 lines =<< trim END
5300 vim9script
5301 class A
5302 static _val = 10
5303 endclass
5304 def T()
5305 var a = A.new()
5306 a._val = 3
5307 enddef
5308 T()
5309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005310 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005311
Ernie Rael03042a22023-11-11 08:53:32 +01005312 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005313 lines =<< trim END
5314 vim9script
5315 class A
5316 static _val = 10
5317 endclass
5318 def T()
5319 var x = A._val
5320 enddef
5321 T()
5322 END
Ernie Rael03042a22023-11-11 08:53:32 +01005323 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005324
Ernie Rael03042a22023-11-11 08:53:32 +01005325 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005326 lines =<< trim END
5327 vim9script
5328 class A
5329 static _val = 10
5330 endclass
5331 def T()
5332 A._val = 3
5333 enddef
5334 T()
5335 END
Ernie Rael03042a22023-11-11 08:53:32 +01005336 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005337enddef
5338
5339" Test for changing the member access of an interface in a implementation class
5340def Test_change_interface_member_access()
5341 var lines =<< trim END
5342 vim9script
5343 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005344 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005345 endinterface
5346 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005347 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005348 endclass
5349 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005350 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005351
5352 lines =<< trim END
5353 vim9script
5354 interface A
5355 this.val: number
5356 endinterface
5357 class B implements A
5358 public this.val = 10
5359 endclass
5360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005361 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005362enddef
5363
5364" Test for trying to change a readonly member from a def function
5365def Test_readonly_member_change_in_def_func()
5366 var lines =<< trim END
5367 vim9script
5368 class A
5369 this.val: number
5370 endclass
5371 def T()
5372 var a = A.new()
5373 a.val = 20
5374 enddef
5375 T()
5376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005377 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005378enddef
5379
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005380" Test for reading and writing a class member from a def function
5381def Test_modify_class_member_from_def_function()
5382 var lines =<< trim END
5383 vim9script
5384 class A
5385 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005386 public static var2: list<number> = [1, 2]
5387 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005388 static _priv_var4: number = 40
5389 endclass
5390 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005391 assert_equal([1, 2], A.var2)
5392 assert_equal({a: 1, b: 2}, A.var3)
5393 A.var2 = [3, 4]
5394 A.var3 = {c: 3, d: 4}
5395 assert_equal([3, 4], A.var2)
5396 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005397 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005398 enddef
5399 T()
5400 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005401 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005402enddef
5403
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005404" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005405def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005406 var lines =<< trim END
5407 vim9script
5408 class A
5409 public static svar1: list<number> = [1]
5410 public static svar2: list<number> = [2]
5411 endclass
5412
5413 A.svar1->add(3)
5414 A.svar2->add(4)
5415 assert_equal([1, 3], A.svar1)
5416 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005417
5418 def Foo()
5419 A.svar1->add(7)
5420 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005421 assert_equal([1, 3, 7], A.svar1)
5422 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005423 enddef
5424 Foo()
5425 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005426 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005427
5428 # Cannot read from a class variable using an object in script context
5429 lines =<< trim END
5430 vim9script
5431 class A
5432 public this.var1: number
5433 public static svar2: list<number> = [1]
5434 endclass
5435
5436 var a = A.new()
5437 echo a.svar2
5438 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005439 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005440
5441 # Cannot write to a class variable using an object in script context
5442 lines =<< trim END
5443 vim9script
5444 class A
5445 public this.var1: number
5446 public static svar2: list<number> = [1]
5447 endclass
5448
5449 var a = A.new()
5450 a.svar2 = [2]
5451 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005452 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005453
5454 # Cannot read from a class variable using an object in def method context
5455 lines =<< trim END
5456 vim9script
5457 class A
5458 public this.var1: number
5459 public static svar2: list<number> = [1]
5460 endclass
5461
5462 def T()
5463 var a = A.new()
5464 echo a.svar2
5465 enddef
5466 T()
5467 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005468 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005469
5470 # Cannot write to a class variable using an object in def method context
5471 lines =<< trim END
5472 vim9script
5473 class A
5474 public this.var1: number
5475 public static svar2: list<number> = [1]
5476 endclass
5477
5478 def T()
5479 var a = A.new()
5480 a.svar2 = [2]
5481 enddef
5482 T()
5483 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005484 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005485enddef
5486
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005487" Test for using a interface method using a child object
5488def Test_interface_method_from_child()
5489 var lines =<< trim END
5490 vim9script
5491
5492 interface A
5493 def Foo(): string
5494 endinterface
5495
5496 class B implements A
5497 def Foo(): string
5498 return 'foo'
5499 enddef
5500 endclass
5501
5502 class C extends B
5503 def Bar(): string
5504 return 'bar'
5505 enddef
5506 endclass
5507
5508 def T1(a: A)
5509 assert_equal('foo', a.Foo())
5510 enddef
5511
5512 def T2(b: B)
5513 assert_equal('foo', b.Foo())
5514 enddef
5515
5516 var c = C.new()
5517 T1(c)
5518 T2(c)
5519 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005520 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005521enddef
5522
5523" Test for using an interface method using a child object when it is overridden
5524" by the child class.
5525" FIXME: This test fails.
5526" def Test_interface_overridden_method_from_child()
5527" var lines =<< trim END
5528" vim9script
5529"
5530" interface A
5531" def Foo(): string
5532" endinterface
5533"
5534" class B implements A
5535" def Foo(): string
5536" return 'b-foo'
5537" enddef
5538" endclass
5539"
5540" class C extends B
5541" def Bar(): string
5542" return 'bar'
5543" enddef
5544" def Foo(): string
5545" return 'c-foo'
5546" enddef
5547" endclass
5548"
5549" def T1(a: A)
5550" assert_equal('c-foo', a.Foo())
5551" enddef
5552"
5553" def T2(b: B)
5554" assert_equal('c-foo', b.Foo())
5555" enddef
5556"
5557" var c = C.new()
5558" T1(c)
5559" T2(c)
5560" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005561" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005562" enddef
5563
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005564" Test for abstract methods
5565def Test_abstract_method()
5566 # Use two abstract methods
5567 var lines =<< trim END
5568 vim9script
5569 abstract class A
5570 def M1(): number
5571 return 10
5572 enddef
5573 abstract def M2(): number
5574 abstract def M3(): number
5575 endclass
5576 class B extends A
5577 def M2(): number
5578 return 20
5579 enddef
5580 def M3(): number
5581 return 30
5582 enddef
5583 endclass
5584 var b = B.new()
5585 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005587 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005588
5589 # Don't define an abstract method
5590 lines =<< trim END
5591 vim9script
5592 abstract class A
5593 abstract def Foo()
5594 endclass
5595 class B extends A
5596 endclass
5597 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005598 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005599
5600 # Use abstract method in a concrete class
5601 lines =<< trim END
5602 vim9script
5603 class A
5604 abstract def Foo()
5605 endclass
5606 class B extends A
5607 endclass
5608 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005609 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005610
5611 # Use abstract method in an interface
5612 lines =<< trim END
5613 vim9script
5614 interface A
5615 abstract def Foo()
5616 endinterface
5617 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005618 def Foo()
5619 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005620 endclass
5621 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005622 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5623
5624 # Use abstract static method in an interface
5625 lines =<< trim END
5626 vim9script
5627 interface A
5628 abstract static def Foo()
5629 enddef
5630 endinterface
5631 END
5632 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5633
5634 # Use abstract static variable in an interface
5635 lines =<< trim END
5636 vim9script
5637 interface A
5638 abstract static foo: number = 10
5639 endinterface
5640 END
5641 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005642
5643 # Abbreviate the "abstract" keyword
5644 lines =<< trim END
5645 vim9script
5646 class A
5647 abs def Foo()
5648 endclass
5649 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005650 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005651
5652 # Use "abstract" with a member variable
5653 lines =<< trim END
5654 vim9script
5655 abstract class A
5656 abstract this.val = 10
5657 endclass
5658 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005659 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005660
5661 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005662 lines =<< trim END
5663 vim9script
5664 abstract class A
5665 abstract static def Foo(): number
5666 endclass
5667 END
5668 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005669
5670 # Type mismatch between abstract method and concrete method
5671 lines =<< trim END
5672 vim9script
5673 abstract class A
5674 abstract def Foo(a: string, b: number): list<number>
5675 endclass
5676 class B extends A
5677 def Foo(a: number, b: string): list<string>
5678 return []
5679 enddef
5680 endclass
5681 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005682 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 +02005683
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005684 # Invoke an abstract method from a def function
5685 lines =<< trim END
5686 vim9script
5687 abstract class A
5688 abstract def Foo(): list<number>
5689 endclass
5690 class B extends A
5691 def Foo(): list<number>
5692 return [3, 5]
5693 enddef
5694 endclass
5695 def Bar(c: B)
5696 assert_equal([3, 5], c.Foo())
5697 enddef
5698 var b = B.new()
5699 Bar(b)
5700 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005701 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005702
5703 # Use a static method in an abstract class
5704 lines =<< trim END
5705 vim9script
5706 abstract class A
5707 static def Foo(): string
5708 return 'foo'
5709 enddef
5710 endclass
5711 assert_equal('foo', A.Foo())
5712 END
5713 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005714enddef
5715
5716" Test for calling a class method from a subclass
5717def Test_class_method_call_from_subclass()
5718 # class method call from a subclass
5719 var lines =<< trim END
5720 vim9script
5721
5722 class A
5723 static def Foo()
5724 echo "foo"
5725 enddef
5726 endclass
5727
5728 class B extends A
5729 def Bar()
5730 Foo()
5731 enddef
5732 endclass
5733
5734 var b = B.new()
5735 b.Bar()
5736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005737 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005738enddef
5739
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005740" Test for calling a class method using an object in a def function context and
5741" script context.
5742def Test_class_method_call_using_object()
5743 # script context
5744 var lines =<< trim END
5745 vim9script
5746 class A
5747 static def Foo(): list<string>
5748 return ['a', 'b']
5749 enddef
5750 def Bar()
5751 assert_equal(['a', 'b'], A.Foo())
5752 assert_equal(['a', 'b'], Foo())
5753 enddef
5754 endclass
5755
5756 def T()
5757 assert_equal(['a', 'b'], A.Foo())
5758 var t_a = A.new()
5759 t_a.Bar()
5760 enddef
5761
5762 assert_equal(['a', 'b'], A.Foo())
5763 var a = A.new()
5764 a.Bar()
5765 T()
5766 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005767 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005768
5769 # script context
5770 lines =<< trim END
5771 vim9script
5772 class A
5773 static def Foo(): string
5774 return 'foo'
5775 enddef
5776 endclass
5777
5778 var a = A.new()
5779 assert_equal('foo', a.Foo())
5780 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005781 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005782
5783 # def function context
5784 lines =<< trim END
5785 vim9script
5786 class A
5787 static def Foo(): string
5788 return 'foo'
5789 enddef
5790 endclass
5791
5792 def T()
5793 var a = A.new()
5794 assert_equal('foo', a.Foo())
5795 enddef
5796 T()
5797 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005798 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005799enddef
5800
5801def Test_class_variable()
5802 var lines =<< trim END
5803 vim9script
5804
5805 class A
5806 public static val: number = 10
5807 static def ClassFunc()
5808 assert_equal(10, val)
5809 enddef
5810 def ObjFunc()
5811 assert_equal(10, val)
5812 enddef
5813 endclass
5814
5815 class B extends A
5816 endclass
5817
5818 assert_equal(10, A.val)
5819 A.ClassFunc()
5820 var a = A.new()
5821 a.ObjFunc()
5822 var b = B.new()
5823 b.ObjFunc()
5824
5825 def T1(a1: A)
5826 a1.ObjFunc()
5827 A.ClassFunc()
5828 enddef
5829 T1(b)
5830
5831 A.val = 20
5832 assert_equal(20, A.val)
5833 END
5834 v9.CheckSourceSuccess(lines)
5835
5836 # Modifying a parent class variable from a child class method
5837 lines =<< trim END
5838 vim9script
5839
5840 class A
5841 static val: number = 10
5842 endclass
5843
5844 class B extends A
5845 static def ClassFunc()
5846 val = 20
5847 enddef
5848 endclass
5849 B.ClassFunc()
5850 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005851 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005852
5853 # Reading a parent class variable from a child class method
5854 lines =<< trim END
5855 vim9script
5856
5857 class A
5858 static val: number = 10
5859 endclass
5860
5861 class B extends A
5862 static def ClassFunc()
5863 var i = val
5864 enddef
5865 endclass
5866 B.ClassFunc()
5867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005868 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005869
5870 # Modifying a parent class variable from a child object method
5871 lines =<< trim END
5872 vim9script
5873
5874 class A
5875 static val: number = 10
5876 endclass
5877
5878 class B extends A
5879 def ObjFunc()
5880 val = 20
5881 enddef
5882 endclass
5883 var b = B.new()
5884 b.ObjFunc()
5885 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005886 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005887
5888 # Reading a parent class variable from a child object method
5889 lines =<< trim END
5890 vim9script
5891
5892 class A
5893 static val: number = 10
5894 endclass
5895
5896 class B extends A
5897 def ObjFunc()
5898 var i = val
5899 enddef
5900 endclass
5901 var b = B.new()
5902 b.ObjFunc()
5903 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005904 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005905
5906 # Modifying a class variable using an object at script level
5907 lines =<< trim END
5908 vim9script
5909
5910 class A
5911 static val: number = 10
5912 endclass
5913 var a = A.new()
5914 a.val = 20
5915 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005916 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005917
5918 # Reading a class variable using an object at script level
5919 lines =<< trim END
5920 vim9script
5921
5922 class A
5923 static val: number = 10
5924 endclass
5925 var a = A.new()
5926 var i = a.val
5927 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005928 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005929
5930 # Modifying a class variable using an object at function level
5931 lines =<< trim END
5932 vim9script
5933
5934 class A
5935 static val: number = 10
5936 endclass
5937
5938 def T()
5939 var a = A.new()
5940 a.val = 20
5941 enddef
5942 T()
5943 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005944 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005945
5946 # Reading a class variable using an object at function level
5947 lines =<< trim END
5948 vim9script
5949
5950 class A
5951 static val: number = 10
5952 endclass
5953 def T()
5954 var a = A.new()
5955 var i = a.val
5956 enddef
5957 T()
5958 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005959 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005960enddef
5961
5962" Test for using a duplicate class method and class variable in a child class
5963def Test_dup_class_member()
5964 # duplicate class variable, class method and overridden object method
5965 var lines =<< trim END
5966 vim9script
5967 class A
5968 static sval = 100
5969 static def Check()
5970 assert_equal(100, sval)
5971 enddef
5972 def GetVal(): number
5973 return sval
5974 enddef
5975 endclass
5976
5977 class B extends A
5978 static sval = 200
5979 static def Check()
5980 assert_equal(200, sval)
5981 enddef
5982 def GetVal(): number
5983 return sval
5984 enddef
5985 endclass
5986
5987 def T1(aa: A): number
5988 return aa.GetVal()
5989 enddef
5990
5991 def T2(bb: B): number
5992 return bb.GetVal()
5993 enddef
5994
5995 assert_equal(100, A.sval)
5996 assert_equal(200, B.sval)
5997 var a = A.new()
5998 assert_equal(100, a.GetVal())
5999 var b = B.new()
6000 assert_equal(200, b.GetVal())
6001 assert_equal(200, T1(b))
6002 assert_equal(200, T2(b))
6003 END
6004 v9.CheckSourceSuccess(lines)
6005
6006 # duplicate class variable and class method
6007 lines =<< trim END
6008 vim9script
6009 class A
6010 static sval = 100
6011 static def Check()
6012 assert_equal(100, sval)
6013 enddef
6014 def GetVal(): number
6015 return sval
6016 enddef
6017 endclass
6018
6019 class B extends A
6020 static sval = 200
6021 static def Check()
6022 assert_equal(200, sval)
6023 enddef
6024 endclass
6025
6026 def T1(aa: A): number
6027 return aa.GetVal()
6028 enddef
6029
6030 def T2(bb: B): number
6031 return bb.GetVal()
6032 enddef
6033
6034 assert_equal(100, A.sval)
6035 assert_equal(200, B.sval)
6036 var a = A.new()
6037 assert_equal(100, a.GetVal())
6038 var b = B.new()
6039 assert_equal(100, b.GetVal())
6040 assert_equal(100, T1(b))
6041 assert_equal(100, T2(b))
6042 END
6043 v9.CheckSourceSuccess(lines)
6044enddef
6045
6046" Test for calling an instance method using the class
6047def Test_instance_method_call_using_class()
6048 # Invoke an object method using a class in script context
6049 var lines =<< trim END
6050 vim9script
6051 class A
6052 def Foo()
6053 echo "foo"
6054 enddef
6055 endclass
6056 A.Foo()
6057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006058 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006059
6060 # Invoke an object method using a class in def function context
6061 lines =<< trim END
6062 vim9script
6063 class A
6064 def Foo()
6065 echo "foo"
6066 enddef
6067 endclass
6068 def T()
6069 A.Foo()
6070 enddef
6071 T()
6072 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006073 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006074enddef
6075
6076" Test for duplicate class method and instance method
6077def Test_dup_classmethod_objmethod()
6078 # Duplicate instance method
6079 var lines =<< trim END
6080 vim9script
6081 class A
6082 static def Foo()
6083 enddef
6084 def Foo()
6085 enddef
6086 endclass
6087 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006088 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006089
Ernie Rael03042a22023-11-11 08:53:32 +01006090 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006091 lines =<< trim END
6092 vim9script
6093 class A
6094 static def Foo()
6095 enddef
6096 def _Foo()
6097 enddef
6098 endclass
6099 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006100 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006101
6102 # Duplicate class method
6103 lines =<< trim END
6104 vim9script
6105 class A
6106 def Foo()
6107 enddef
6108 static def Foo()
6109 enddef
6110 endclass
6111 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006112 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006113
Ernie Rael03042a22023-11-11 08:53:32 +01006114 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006115 lines =<< trim END
6116 vim9script
6117 class A
6118 def Foo()
6119 enddef
6120 static def _Foo()
6121 enddef
6122 endclass
6123 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006124 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006125
Ernie Rael03042a22023-11-11 08:53:32 +01006126 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006127 lines =<< trim END
6128 vim9script
6129 class A
6130 def _Foo()
6131 enddef
6132 static def _Foo()
6133 enddef
6134 endclass
6135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006136 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006137enddef
6138
6139" Test for an instance method access level comparison with parent instance
6140" methods.
6141def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006142 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006143 var lines =<< trim END
6144 vim9script
6145 class A
6146 def Foo()
6147 enddef
6148 endclass
6149 class B extends A
6150 endclass
6151 class C extends B
6152 def _Foo()
6153 enddef
6154 endclass
6155 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006156 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006157
6158 # Public method in subclass
6159 lines =<< trim END
6160 vim9script
6161 class A
6162 def _Foo()
6163 enddef
6164 endclass
6165 class B extends A
6166 endclass
6167 class C extends B
6168 def Foo()
6169 enddef
6170 endclass
6171 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006172 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006173enddef
6174
6175def Test_extend_empty_class()
6176 var lines =<< trim END
6177 vim9script
6178 class A
6179 endclass
6180 class B extends A
6181 endclass
6182 class C extends B
6183 public static rw_class_var = 1
6184 public this.rw_obj_var = 2
6185 static def ClassMethod(): number
6186 return 3
6187 enddef
6188 def ObjMethod(): number
6189 return 4
6190 enddef
6191 endclass
6192 assert_equal(1, C.rw_class_var)
6193 assert_equal(3, C.ClassMethod())
6194 var c = C.new()
6195 assert_equal(2, c.rw_obj_var)
6196 assert_equal(4, c.ObjMethod())
6197 END
6198 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006199enddef
6200
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006201" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006202" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006203def Test_interface_with_unsupported_members()
6204 var lines =<< trim END
6205 vim9script
6206 interface A
6207 static num: number
6208 endinterface
6209 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006210 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006211
6212 lines =<< trim END
6213 vim9script
6214 interface A
6215 static _num: number
6216 endinterface
6217 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006218 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006219
6220 lines =<< trim END
6221 vim9script
6222 interface A
6223 public static num: number
6224 endinterface
6225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006226 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006227
6228 lines =<< trim END
6229 vim9script
6230 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006231 public static num: number
6232 endinterface
6233 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006234 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006235
6236 lines =<< trim END
6237 vim9script
6238 interface A
6239 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006240 endinterface
6241 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006242 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006243
6244 lines =<< trim END
6245 vim9script
6246 interface A
6247 static def Foo(d: dict<any>): list<string>
6248 endinterface
6249 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006250 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006251
6252 lines =<< trim END
6253 vim9script
6254 interface A
6255 static def _Foo(d: dict<any>): list<string>
6256 endinterface
6257 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006258 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006259
6260 lines =<< trim END
6261 vim9script
6262 interface A
6263 this._Foo: list<string>
6264 endinterface
6265 END
Ernie Rael03042a22023-11-11 08:53:32 +01006266 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006267
6268 lines =<< trim END
6269 vim9script
6270 interface A
6271 def _Foo(d: dict<any>): list<string>
6272 endinterface
6273 END
Ernie Rael03042a22023-11-11 08:53:32 +01006274 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006275enddef
6276
6277" Test for extending an interface
6278def Test_extend_interface()
6279 var lines =<< trim END
6280 vim9script
6281 interface A
6282 this.var1: list<string>
6283 def Foo()
6284 endinterface
6285 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006286 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006287 def Bar()
6288 endinterface
6289 class C implements A, B
6290 this.var1 = [1, 2]
6291 def Foo()
6292 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006293 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006294 def Bar()
6295 enddef
6296 endclass
6297 END
6298 v9.CheckSourceSuccess(lines)
6299
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006300 # extending empty interface
6301 lines =<< trim END
6302 vim9script
6303 interface A
6304 endinterface
6305 interface B extends A
6306 endinterface
6307 class C implements B
6308 endclass
6309 END
6310 v9.CheckSourceSuccess(lines)
6311
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006312 lines =<< trim END
6313 vim9script
6314 interface A
6315 def Foo()
6316 endinterface
6317 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006318 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006319 endinterface
6320 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006321 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006322 endclass
6323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006324 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006325
6326 lines =<< trim END
6327 vim9script
6328 interface A
6329 def Foo()
6330 endinterface
6331 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006332 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006333 endinterface
6334 class C implements A, B
6335 def Foo()
6336 enddef
6337 endclass
6338 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006339 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006340
6341 # interface cannot extend a class
6342 lines =<< trim END
6343 vim9script
6344 class A
6345 endclass
6346 interface B extends A
6347 endinterface
6348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006349 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006350
6351 # class cannot extend an interface
6352 lines =<< trim END
6353 vim9script
6354 interface A
6355 endinterface
6356 class B extends A
6357 endclass
6358 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006359 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006360
6361 # interface cannot implement another interface
6362 lines =<< trim END
6363 vim9script
6364 interface A
6365 endinterface
6366 interface B implements A
6367 endinterface
6368 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006369 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006370
6371 # interface cannot extend multiple interfaces
6372 lines =<< trim END
6373 vim9script
6374 interface A
6375 endinterface
6376 interface B
6377 endinterface
6378 interface C extends A, B
6379 endinterface
6380 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006381 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006382
6383 # Variable type in an extended interface is of different type
6384 lines =<< trim END
6385 vim9script
6386 interface A
6387 this.val1: number
6388 endinterface
6389 interface B extends A
6390 this.val2: string
6391 endinterface
6392 interface C extends B
6393 this.val1: string
6394 this.val2: number
6395 endinterface
6396 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006397 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006398enddef
6399
6400" Test for a child class implementing an interface when some of the methods are
6401" defined in the parent class.
6402def Test_child_class_implements_interface()
6403 var lines =<< trim END
6404 vim9script
6405
6406 interface Intf
6407 def F1(): list<list<number>>
6408 def F2(): list<list<number>>
6409 def F3(): list<list<number>>
6410 this.var1: list<dict<number>>
6411 this.var2: list<dict<number>>
6412 this.var3: list<dict<number>>
6413 endinterface
6414
6415 class A
6416 def A1()
6417 enddef
6418 def F3(): list<list<number>>
6419 return [[3]]
6420 enddef
6421 this.v1: list<list<number>> = [[0]]
6422 this.var3 = [{c: 30}]
6423 endclass
6424
6425 class B extends A
6426 def B1()
6427 enddef
6428 def F2(): list<list<number>>
6429 return [[2]]
6430 enddef
6431 this.v2: list<list<number>> = [[0]]
6432 this.var2 = [{b: 20}]
6433 endclass
6434
6435 class C extends B implements Intf
6436 def C1()
6437 enddef
6438 def F1(): list<list<number>>
6439 return [[1]]
6440 enddef
6441 this.v3: list<list<number>> = [[0]]
6442 this.var1 = [{a: 10}]
6443 endclass
6444
6445 def T(if: Intf)
6446 assert_equal([[1]], if.F1())
6447 assert_equal([[2]], if.F2())
6448 assert_equal([[3]], if.F3())
6449 assert_equal([{a: 10}], if.var1)
6450 assert_equal([{b: 20}], if.var2)
6451 assert_equal([{c: 30}], if.var3)
6452 enddef
6453
6454 var c = C.new()
6455 T(c)
6456 assert_equal([[1]], c.F1())
6457 assert_equal([[2]], c.F2())
6458 assert_equal([[3]], c.F3())
6459 assert_equal([{a: 10}], c.var1)
6460 assert_equal([{b: 20}], c.var2)
6461 assert_equal([{c: 30}], c.var3)
6462 END
6463 v9.CheckSourceSuccess(lines)
6464
6465 # One of the interface methods is not found
6466 lines =<< trim END
6467 vim9script
6468
6469 interface Intf
6470 def F1()
6471 def F2()
6472 def F3()
6473 endinterface
6474
6475 class A
6476 def A1()
6477 enddef
6478 endclass
6479
6480 class B extends A
6481 def B1()
6482 enddef
6483 def F2()
6484 enddef
6485 endclass
6486
6487 class C extends B implements Intf
6488 def C1()
6489 enddef
6490 def F1()
6491 enddef
6492 endclass
6493 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006494 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006495
6496 # One of the interface methods is of different type
6497 lines =<< trim END
6498 vim9script
6499
6500 interface Intf
6501 def F1()
6502 def F2()
6503 def F3()
6504 endinterface
6505
6506 class A
6507 def F3(): number
6508 return 0
6509 enddef
6510 def A1()
6511 enddef
6512 endclass
6513
6514 class B extends A
6515 def B1()
6516 enddef
6517 def F2()
6518 enddef
6519 endclass
6520
6521 class C extends B implements Intf
6522 def C1()
6523 enddef
6524 def F1()
6525 enddef
6526 endclass
6527 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006528 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006529
6530 # One of the interface variables is not present
6531 lines =<< trim END
6532 vim9script
6533
6534 interface Intf
6535 this.var1: list<dict<number>>
6536 this.var2: list<dict<number>>
6537 this.var3: list<dict<number>>
6538 endinterface
6539
6540 class A
6541 this.v1: list<list<number>> = [[0]]
6542 endclass
6543
6544 class B extends A
6545 this.v2: list<list<number>> = [[0]]
6546 this.var2 = [{b: 20}]
6547 endclass
6548
6549 class C extends B implements Intf
6550 this.v3: list<list<number>> = [[0]]
6551 this.var1 = [{a: 10}]
6552 endclass
6553 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006554 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006555
6556 # One of the interface variables is of different type
6557 lines =<< trim END
6558 vim9script
6559
6560 interface Intf
6561 this.var1: list<dict<number>>
6562 this.var2: list<dict<number>>
6563 this.var3: list<dict<number>>
6564 endinterface
6565
6566 class A
6567 this.v1: list<list<number>> = [[0]]
6568 this.var3: list<dict<string>>
6569 endclass
6570
6571 class B extends A
6572 this.v2: list<list<number>> = [[0]]
6573 this.var2 = [{b: 20}]
6574 endclass
6575
6576 class C extends B implements Intf
6577 this.v3: list<list<number>> = [[0]]
6578 this.var1 = [{a: 10}]
6579 endclass
6580 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006581 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 +02006582enddef
6583
6584" Test for extending an interface with duplicate variables and methods
6585def Test_interface_extends_with_dup_members()
6586 var lines =<< trim END
6587 vim9script
6588 interface A
6589 this.n1: number
6590 def Foo1(): number
6591 endinterface
6592 interface B extends A
6593 this.n2: number
6594 this.n1: number
6595 def Foo2(): number
6596 def Foo1(): number
6597 endinterface
6598 class C implements B
6599 this.n1 = 10
6600 this.n2 = 20
6601 def Foo1(): number
6602 return 30
6603 enddef
6604 def Foo2(): number
6605 return 40
6606 enddef
6607 endclass
6608 def T1(a: A)
6609 assert_equal(10, a.n1)
6610 assert_equal(30, a.Foo1())
6611 enddef
6612 def T2(b: B)
6613 assert_equal(10, b.n1)
6614 assert_equal(20, b.n2)
6615 assert_equal(30, b.Foo1())
6616 assert_equal(40, b.Foo2())
6617 enddef
6618 var c = C.new()
6619 T1(c)
6620 T2(c)
6621 END
6622 v9.CheckSourceSuccess(lines)
6623enddef
6624
6625" Test for using "any" type for a variable in a sub-class while it has a
6626" concrete type in the interface
6627def Test_implements_using_var_type_any()
6628 var lines =<< trim END
6629 vim9script
6630 interface A
6631 this.val: list<dict<string>>
6632 endinterface
6633 class B implements A
6634 this.val = [{a: '1'}, {b: '2'}]
6635 endclass
6636 var b = B.new()
6637 assert_equal([{a: '1'}, {b: '2'}], b.val)
6638 END
6639 v9.CheckSourceSuccess(lines)
6640
6641 # initialize instance variable using a different type
6642 lines =<< trim END
6643 vim9script
6644 interface A
6645 this.val: list<dict<string>>
6646 endinterface
6647 class B implements A
6648 this.val = {a: 1, b: 2}
6649 endclass
6650 var b = B.new()
6651 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006652 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006653enddef
6654
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006655" Test for assigning to a member variable in a nested class
6656def Test_nested_object_assignment()
6657 var lines =<< trim END
6658 vim9script
6659
6660 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006661 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006662 endclass
6663
6664 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006665 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006666 endclass
6667
6668 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006669 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006670 endclass
6671
6672 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006673 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006674 endclass
6675
6676 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006677 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006678 enddef
6679
6680 var d = D.new()
6681 T(d)
6682 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006683 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006684enddef
6685
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006686" Test for calling methods using a null object
6687def Test_null_object_method_call()
6688 # Calling a object method using a null object in script context
6689 var lines =<< trim END
6690 vim9script
6691
6692 class C
6693 def Foo()
6694 assert_report('This method should not be executed')
6695 enddef
6696 endclass
6697
6698 var o: C
6699 o.Foo()
6700 END
6701 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6702
6703 # Calling a object method using a null object in def function context
6704 lines =<< trim END
6705 vim9script
6706
6707 class C
6708 def Foo()
6709 assert_report('This method should not be executed')
6710 enddef
6711 endclass
6712
6713 def T()
6714 var o: C
6715 o.Foo()
6716 enddef
6717 T()
6718 END
6719 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6720
6721 # Calling a object method through another class method using a null object in
6722 # script context
6723 lines =<< trim END
6724 vim9script
6725
6726 class C
6727 def Foo()
6728 assert_report('This method should not be executed')
6729 enddef
6730
6731 static def Bar(o_any: any)
6732 var o_typed: C = o_any
6733 o_typed.Foo()
6734 enddef
6735 endclass
6736
6737 var o: C
6738 C.Bar(o)
6739 END
6740 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6741
6742 # Calling a object method through another class method using a null object in
6743 # def function context
6744 lines =<< trim END
6745 vim9script
6746
6747 class C
6748 def Foo()
6749 assert_report('This method should not be executed')
6750 enddef
6751
6752 static def Bar(o_any: any)
6753 var o_typed: C = o_any
6754 o_typed.Foo()
6755 enddef
6756 endclass
6757
6758 def T()
6759 var o: C
6760 C.Bar(o)
6761 enddef
6762 T()
6763 END
6764 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6765enddef
6766
6767" Test for using a dict as an object member
6768def Test_dict_object_member()
6769 var lines =<< trim END
6770 vim9script
6771
6772 class Context
6773 public this.state: dict<number> = {}
6774 def GetState(): dict<number>
6775 return this.state
6776 enddef
6777 endclass
6778
6779 var ctx = Context.new()
6780 ctx.state->extend({a: 1})
6781 ctx.state['b'] = 2
6782 assert_equal({a: 1, b: 2}, ctx.GetState())
6783
6784 def F()
6785 ctx.state['c'] = 3
6786 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6787 enddef
6788 F()
6789 assert_equal(3, ctx.state.c)
6790 ctx.state.c = 4
6791 assert_equal(4, ctx.state.c)
6792 END
6793 v9.CheckSourceSuccess(lines)
6794enddef
6795
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006796" The following test was failing after 9.0.1914. This was caused by using a
6797" freed object from a previous method call.
6798def Test_freed_object_from_previous_method_call()
6799 var lines =<< trim END
6800 vim9script
6801
6802 class Context
6803 endclass
6804
6805 class Result
6806 endclass
6807
6808 def Failure(): Result
6809 return Result.new()
6810 enddef
6811
6812 def GetResult(ctx: Context): Result
6813 return Failure()
6814 enddef
6815
6816 def Test_GetResult()
6817 var ctx = Context.new()
6818 var result = GetResult(ctx)
6819 enddef
6820
6821 Test_GetResult()
6822 END
6823 v9.CheckSourceSuccess(lines)
6824enddef
6825
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006826" Test for duplicate object and class variable
6827def Test_duplicate_variable()
6828 # Object variable name is same as the class variable name
6829 var lines =<< trim END
6830 vim9script
6831 class A
6832 public static sval: number
6833 public this.sval: number
6834 endclass
6835 var a = A.new()
6836 END
6837 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6838
6839 # Duplicate variable name and calling a class method
6840 lines =<< trim END
6841 vim9script
6842 class A
6843 public static sval: number
6844 public this.sval: number
6845 def F1()
6846 echo this.sval
6847 enddef
6848 static def F2()
6849 echo sval
6850 enddef
6851 endclass
6852 A.F2()
6853 END
6854 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6855
6856 # Duplicate variable with an empty constructor
6857 lines =<< trim END
6858 vim9script
6859 class A
6860 public static sval: number
6861 public this.sval: number
6862 def new()
6863 enddef
6864 endclass
6865 var a = A.new()
6866 END
6867 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6868enddef
6869
6870" Test for using a reserved keyword as a variable name
6871def Test_reserved_varname()
6872 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6873 'null_function', 'null_list', 'null_partial', 'null_string',
6874 'null_channel', 'null_job', 'super', 'this']
6875
6876 var lines =<< trim eval END
6877 vim9script
6878 class C
6879 public this.{kword}: list<number> = [1, 2, 3]
6880 endclass
6881 var o = C.new()
6882 END
6883 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6884
6885 lines =<< trim eval END
6886 vim9script
6887 class C
6888 public this.{kword}: list<number> = [1, 2, 3]
6889 def new()
6890 enddef
6891 endclass
6892 var o = C.new()
6893 END
6894 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6895
6896 lines =<< trim eval END
6897 vim9script
6898 class C
6899 public this.{kword}: list<number> = [1, 2, 3]
6900 def new()
6901 enddef
6902 def F()
6903 echo this.{kword}
6904 enddef
6905 endclass
6906 var o = C.new()
6907 o.F()
6908 END
6909 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006910
6911 # class variable name
6912 if kword != 'this'
6913 lines =<< trim eval END
6914 vim9script
6915 class C
6916 public static {kword}: list<number> = [1, 2, 3]
6917 endclass
6918 END
6919 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6920 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006921 endfor
6922enddef
6923
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006924" Test for checking the type of the arguments and the return value of a object
6925" method in an extended class.
6926def Test_extended_obj_method_type_check()
6927 var lines =<< trim END
6928 vim9script
6929
6930 class A
6931 endclass
6932 class B extends A
6933 endclass
6934 class C extends B
6935 endclass
6936
6937 class Foo
6938 def Doit(p: B): B
6939 return B.new()
6940 enddef
6941 endclass
6942
6943 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006944 def Doit(p: C): B
6945 return B.new()
6946 enddef
6947 endclass
6948 END
6949 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6950
6951 lines =<< trim END
6952 vim9script
6953
6954 class A
6955 endclass
6956 class B extends A
6957 endclass
6958 class C extends B
6959 endclass
6960
6961 class Foo
6962 def Doit(p: B): B
6963 return B.new()
6964 enddef
6965 endclass
6966
6967 class Bar extends Foo
6968 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006969 return C.new()
6970 enddef
6971 endclass
6972 END
6973 v9.CheckSourceSuccess(lines)
6974
6975 lines =<< trim END
6976 vim9script
6977
6978 class A
6979 endclass
6980 class B extends A
6981 endclass
6982 class C extends B
6983 endclass
6984
6985 class Foo
6986 def Doit(p: B): B
6987 return B.new()
6988 enddef
6989 endclass
6990
6991 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006992 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006993 return B.new()
6994 enddef
6995 endclass
6996 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02006997 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 +02006998
6999 lines =<< trim END
7000 vim9script
7001
7002 class A
7003 endclass
7004 class B extends A
7005 endclass
7006 class C extends B
7007 endclass
7008
7009 class Foo
7010 def Doit(p: B): B
7011 return B.new()
7012 enddef
7013 endclass
7014
7015 class Bar extends Foo
7016 def Doit(p: B): A
7017 return A.new()
7018 enddef
7019 endclass
7020 END
7021 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
Ernie Rael96952b22023-10-17 18:15:01 +02007022
7023 # check varargs type mismatch
7024 lines =<< trim END
7025 vim9script
7026
7027 class B
7028 def F(...xxx: list<any>)
7029 enddef
7030 endclass
7031 class C extends B
7032 def F(xxx: list<any>)
7033 enddef
7034 endclass
7035 END
7036 v9.CheckSourceFailure(lines, 'E1383: Method "F": type mismatch, expected func(...list<any>) but got func(list<any>)', 10)
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007037enddef
7038
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007039" Test type checking for class variable in assignments
7040func Test_class_variable_complex_type_check()
7041 " class variable with a specific type. Try assigning a different type at
7042 " script level.
7043 let lines =<< trim END
7044 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007045 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007046 return {}
7047 enddef
7048 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007049 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007050 endclass
7051 test_garbagecollect_now()
7052 A.Fn = "abc"
7053 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007054 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007055
7056 " class variable with a specific type. Try assigning a different type at
7057 " class def method level.
7058 let lines =<< trim END
7059 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007060 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007061 return {}
7062 enddef
7063 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007064 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007065 def Bar()
7066 Fn = "abc"
7067 enddef
7068 endclass
7069 var a = A.new()
7070 test_garbagecollect_now()
7071 a.Bar()
7072 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007073 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 +02007074
7075 " class variable with a specific type. Try assigning a different type at
7076 " script def method level.
7077 let lines =<< trim END
7078 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007079 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007080 return {}
7081 enddef
7082 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007083 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007084 endclass
7085 def Bar()
7086 A.Fn = "abc"
7087 enddef
7088 test_garbagecollect_now()
7089 Bar()
7090 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007091 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 +02007092
7093 " class variable without any type. Should be set to the initialization
7094 " expression type. Try assigning a different type from script level.
7095 let lines =<< trim END
7096 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007097 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007098 return {}
7099 enddef
7100 class A
7101 public static Fn = Foo
7102 endclass
7103 test_garbagecollect_now()
7104 A.Fn = "abc"
7105 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007106 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 +02007107
7108 " class variable without any type. Should be set to the initialization
7109 " expression type. Try assigning a different type at class def level.
7110 let lines =<< trim END
7111 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007112 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007113 return {}
7114 enddef
7115 class A
7116 public static Fn = Foo
7117 def Bar()
7118 Fn = "abc"
7119 enddef
7120 endclass
7121 var a = A.new()
7122 test_garbagecollect_now()
7123 a.Bar()
7124 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007125 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 +02007126
7127 " class variable without any type. Should be set to the initialization
7128 " expression type. Try assigning a different type at script def level.
7129 let lines =<< trim END
7130 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007131 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007132 return {}
7133 enddef
7134 class A
7135 public static Fn = Foo
7136 endclass
7137 def Bar()
7138 A.Fn = "abc"
7139 enddef
7140 test_garbagecollect_now()
7141 Bar()
7142 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007143 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 +02007144
7145 " class variable with 'any" type. Can be assigned different types.
7146 let lines =<< trim END
7147 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007148 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007149 return {}
7150 enddef
7151 class A
7152 public static Fn: any = Foo
7153 public static Fn2: any
7154 endclass
7155 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007156 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007157 A.Fn = "abc"
7158 test_garbagecollect_now()
7159 assert_equal('string', typename(A.Fn))
7160 A.Fn2 = Foo
7161 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007162 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007163 A.Fn2 = "xyz"
7164 test_garbagecollect_now()
7165 assert_equal('string', typename(A.Fn2))
7166 END
7167 call v9.CheckSourceSuccess(lines)
7168
7169 " class variable with 'any" type. Can be assigned different types.
7170 let lines =<< trim END
7171 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007172 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007173 return {}
7174 enddef
7175 class A
7176 public static Fn: any = Foo
7177 public static Fn2: any
7178
7179 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007180 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007181 Fn = "abc"
7182 assert_equal('string', typename(Fn))
7183 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007184 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007185 Fn2 = "xyz"
7186 assert_equal('string', typename(Fn2))
7187 enddef
7188 endclass
7189 var a = A.new()
7190 test_garbagecollect_now()
7191 a.Bar()
7192 test_garbagecollect_now()
7193 A.Fn = Foo
7194 a.Bar()
7195 END
7196 call v9.CheckSourceSuccess(lines)
7197
7198 " class variable with 'any" type. Can be assigned different types.
7199 let lines =<< trim END
7200 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007201 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007202 return {}
7203 enddef
7204 class A
7205 public static Fn: any = Foo
7206 public static Fn2: any
7207 endclass
7208
7209 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007210 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007211 A.Fn = "abc"
7212 assert_equal('string', typename(A.Fn))
7213 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007214 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007215 A.Fn2 = "xyz"
7216 assert_equal('string', typename(A.Fn2))
7217 enddef
7218 Bar()
7219 test_garbagecollect_now()
7220 A.Fn = Foo
7221 Bar()
7222 END
7223 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007224
7225 let lines =<< trim END
7226 vim9script
7227 class A
7228 public static foo = [0z10, 0z20]
7229 endclass
7230 assert_equal([0z10, 0z20], A.foo)
7231 A.foo = [0z30]
7232 assert_equal([0z30], A.foo)
7233 var a = A.foo
7234 assert_equal([0z30], a)
7235 END
7236 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007237endfunc
7238
7239" Test type checking for object variable in assignments
7240func Test_object_variable_complex_type_check()
7241 " object variable with a specific type. Try assigning a different type at
7242 " script level.
7243 let lines =<< trim END
7244 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007245 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007246 return {}
7247 enddef
7248 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007249 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007250 endclass
7251 var a = A.new()
7252 test_garbagecollect_now()
7253 a.Fn = "abc"
7254 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007255 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 +02007256
7257 " object variable with a specific type. Try assigning a different type at
7258 " object def method level.
7259 let lines =<< trim END
7260 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007261 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007262 return {}
7263 enddef
7264 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007265 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007266 def Bar()
7267 this.Fn = "abc"
7268 this.Fn = Foo
7269 enddef
7270 endclass
7271 var a = A.new()
7272 test_garbagecollect_now()
7273 a.Bar()
7274 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007275 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 +02007276
7277 " object variable with a specific type. Try assigning a different type at
7278 " script def method level.
7279 let lines =<< trim END
7280 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007281 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007282 return {}
7283 enddef
7284 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007285 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007286 endclass
7287 def Bar()
7288 var a = A.new()
7289 a.Fn = "abc"
7290 a.Fn = Foo
7291 enddef
7292 test_garbagecollect_now()
7293 Bar()
7294 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007295 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 +02007296
7297 " object variable without any type. Should be set to the initialization
7298 " expression type. Try assigning a different type from script level.
7299 let lines =<< trim END
7300 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007301 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007302 return {}
7303 enddef
7304 class A
7305 public this.Fn = Foo
7306 endclass
7307 var a = A.new()
7308 test_garbagecollect_now()
7309 a.Fn = "abc"
7310 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007311 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 +02007312
7313 " object variable without any type. Should be set to the initialization
7314 " expression type. Try assigning a different type at object def level.
7315 let lines =<< trim END
7316 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007317 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007318 return {}
7319 enddef
7320 class A
7321 public this.Fn = Foo
7322 def Bar()
7323 this.Fn = "abc"
7324 this.Fn = Foo
7325 enddef
7326 endclass
7327 var a = A.new()
7328 test_garbagecollect_now()
7329 a.Bar()
7330 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007331 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 +02007332
7333 " object variable without any type. Should be set to the initialization
7334 " expression type. Try assigning a different type at script def level.
7335 let lines =<< trim END
7336 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007337 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007338 return {}
7339 enddef
7340 class A
7341 public this.Fn = Foo
7342 endclass
7343 def Bar()
7344 var a = A.new()
7345 a.Fn = "abc"
7346 a.Fn = Foo
7347 enddef
7348 test_garbagecollect_now()
7349 Bar()
7350 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007351 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 +02007352
7353 " object variable with 'any" type. Can be assigned different types.
7354 let lines =<< trim END
7355 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007356 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007357 return {}
7358 enddef
7359 class A
7360 public this.Fn: any = Foo
7361 public this.Fn2: any
7362 endclass
7363
7364 var a = A.new()
7365 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007366 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007367 a.Fn = "abc"
7368 test_garbagecollect_now()
7369 assert_equal('string', typename(a.Fn))
7370 a.Fn2 = Foo
7371 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007372 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007373 a.Fn2 = "xyz"
7374 test_garbagecollect_now()
7375 assert_equal('string', typename(a.Fn2))
7376 END
7377 call v9.CheckSourceSuccess(lines)
7378
7379 " object variable with 'any" type. Can be assigned different types.
7380 let lines =<< trim END
7381 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007382 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007383 return {}
7384 enddef
7385 class A
7386 public this.Fn: any = Foo
7387 public this.Fn2: any
7388
7389 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007390 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007391 this.Fn = "abc"
7392 assert_equal('string', typename(this.Fn))
7393 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007394 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007395 this.Fn2 = "xyz"
7396 assert_equal('string', typename(this.Fn2))
7397 enddef
7398 endclass
7399
7400 var a = A.new()
7401 test_garbagecollect_now()
7402 a.Bar()
7403 test_garbagecollect_now()
7404 a.Fn = Foo
7405 a.Bar()
7406 END
7407 call v9.CheckSourceSuccess(lines)
7408
7409 " object variable with 'any" type. Can be assigned different types.
7410 let lines =<< trim END
7411 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007412 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007413 return {}
7414 enddef
7415 class A
7416 public this.Fn: any = Foo
7417 public this.Fn2: any
7418 endclass
7419
7420 def Bar()
7421 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007422 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007423 a.Fn = "abc"
7424 assert_equal('string', typename(a.Fn))
7425 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007426 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007427 a.Fn2 = "xyz"
7428 assert_equal('string', typename(a.Fn2))
7429 enddef
7430 test_garbagecollect_now()
7431 Bar()
7432 test_garbagecollect_now()
7433 Bar()
7434 END
7435 call v9.CheckSourceSuccess(lines)
7436endfunc
7437
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007438" Test for recursively calling an object method. This used to cause an
7439" use-after-free error.
7440def Test_recursive_object_method_call()
7441 var lines =<< trim END
7442 vim9script
7443 class A
7444 this.val: number = 0
7445 def Foo(): number
7446 if this.val >= 90
7447 return this.val
7448 endif
7449 this.val += 1
7450 return this.Foo()
7451 enddef
7452 endclass
7453 var a = A.new()
7454 assert_equal(90, a.Foo())
7455 END
7456 v9.CheckSourceSuccess(lines)
7457enddef
7458
7459" Test for recursively calling a class method.
7460def Test_recursive_class_method_call()
7461 var lines =<< trim END
7462 vim9script
7463 class A
7464 static val: number = 0
7465 static def Foo(): number
7466 if val >= 90
7467 return val
7468 endif
7469 val += 1
7470 return Foo()
7471 enddef
7472 endclass
7473 assert_equal(90, A.Foo())
7474 END
7475 v9.CheckSourceSuccess(lines)
7476enddef
7477
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007478" Test for checking the argument types and the return type when assigning a
7479" funcref to make sure the invariant class type is used.
7480def Test_funcref_argtype_returntype_check()
7481 var lines =<< trim END
7482 vim9script
7483 class A
7484 endclass
7485 class B extends A
7486 endclass
7487
7488 def Foo(p: B): B
7489 return B.new()
7490 enddef
7491
7492 var Bar: func(A): A = Foo
7493 END
7494 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7495
7496 lines =<< trim END
7497 vim9script
7498 class A
7499 endclass
7500 class B extends A
7501 endclass
7502
7503 def Foo(p: B): B
7504 return B.new()
7505 enddef
7506
7507 def Baz()
7508 var Bar: func(A): A = Foo
7509 enddef
7510 Baz()
7511 END
7512 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7513enddef
7514
Ernie Rael96952b22023-10-17 18:15:01 +02007515def Test_funcref_argtype_invariance_check()
7516 var lines =<< trim END
7517 vim9script
7518
7519 class A
7520 endclass
7521 class B extends A
7522 endclass
7523 class C extends B
7524 endclass
7525
7526 var Func: func(B): number
7527 Func = (o: B): number => 3
7528 assert_equal(3, Func(B.new()))
7529 END
7530 v9.CheckSourceSuccess(lines)
7531
7532 lines =<< trim END
7533 vim9script
7534
7535 class A
7536 endclass
7537 class B extends A
7538 endclass
7539 class C extends B
7540 endclass
7541
7542 var Func: func(B): number
7543 Func = (o: A): number => 3
7544 END
7545 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7546
7547 lines =<< trim END
7548 vim9script
7549
7550 class A
7551 endclass
7552 class B extends A
7553 endclass
7554 class C extends B
7555 endclass
7556
7557 var Func: func(B): number
7558 Func = (o: C): number => 3
7559 END
7560 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7561enddef
7562
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007563" Test for using an operator (e.g. +) with an assignment
7564def Test_op_and_assignment()
7565 # Using += with a class variable
7566 var lines =<< trim END
7567 vim9script
7568 class A
7569 public static val: list<number> = []
7570 static def Foo(): list<number>
7571 val += [1]
7572 return val
7573 enddef
7574 endclass
7575 def Bar(): list<number>
7576 A.val += [2]
7577 return A.val
7578 enddef
7579 assert_equal([1], A.Foo())
7580 assert_equal([1, 2], Bar())
7581 A.val += [3]
7582 assert_equal([1, 2, 3], A.val)
7583 END
7584 v9.CheckSourceSuccess(lines)
7585
7586 # Using += with an object variable
7587 lines =<< trim END
7588 vim9script
7589 class A
7590 public this.val: list<number> = []
7591 def Foo(): list<number>
7592 this.val += [1]
7593 return this.val
7594 enddef
7595 endclass
7596 def Bar(bar_a: A): list<number>
7597 bar_a.val += [2]
7598 return bar_a.val
7599 enddef
7600 var a = A.new()
7601 assert_equal([1], a.Foo())
7602 assert_equal([1, 2], Bar(a))
7603 a.val += [3]
7604 assert_equal([1, 2, 3], a.val)
7605 END
7606 v9.CheckSourceSuccess(lines)
7607enddef
7608
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007609" Test for using an object method as a funcref
7610def Test_object_funcref()
7611 # Using object method funcref from a def function
7612 var lines =<< trim END
7613 vim9script
7614 class A
7615 def Foo(): list<number>
7616 return [3, 2, 1]
7617 enddef
7618 endclass
7619 def Bar()
7620 var a = A.new()
7621 var Fn = a.Foo
7622 assert_equal([3, 2, 1], Fn())
7623 enddef
7624 Bar()
7625 END
7626 v9.CheckSourceSuccess(lines)
7627
7628 # Using object method funcref at the script level
7629 lines =<< trim END
7630 vim9script
7631 class A
7632 def Foo(): dict<number>
7633 return {a: 1, b: 2}
7634 enddef
7635 endclass
7636 var a = A.new()
7637 var Fn = a.Foo
7638 assert_equal({a: 1, b: 2}, Fn())
7639 END
7640 v9.CheckSourceSuccess(lines)
7641
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007642 # Using object method funcref at the script level
7643 lines =<< trim END
7644 vim9script
7645 class A
7646 this.val: number
7647 def Foo(): number
7648 return this.val
7649 enddef
7650 endclass
7651 var a = A.new(345)
7652 var Fn = a.Foo
7653 assert_equal(345, Fn())
7654 END
7655 v9.CheckSourceSuccess(lines)
7656
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007657 # Using object method funcref from another object method
7658 lines =<< trim END
7659 vim9script
7660 class A
7661 def Foo(): list<number>
7662 return [3, 2, 1]
7663 enddef
7664 def Bar()
7665 var Fn = this.Foo
7666 assert_equal([3, 2, 1], Fn())
7667 enddef
7668 endclass
7669 var a = A.new()
7670 a.Bar()
7671 END
7672 v9.CheckSourceSuccess(lines)
7673
7674 # Using function() to get a object method funcref
7675 lines =<< trim END
7676 vim9script
7677 class A
7678 def Foo(l: list<any>): list<any>
7679 return l
7680 enddef
7681 endclass
7682 var a = A.new()
7683 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7684 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7685 END
7686 v9.CheckSourceSuccess(lines)
7687
7688 # Use an object method with a function returning a funcref and then call the
7689 # funcref.
7690 lines =<< trim END
7691 vim9script
7692
7693 def Map(F: func(number): number): func(number): number
7694 return (n: number) => F(n)
7695 enddef
7696
7697 class Math
7698 def Double(n: number): number
7699 return 2 * n
7700 enddef
7701 endclass
7702
7703 const math = Math.new()
7704 assert_equal(48, Map(math.Double)(24))
7705 END
7706 v9.CheckSourceSuccess(lines)
7707
Ernie Rael03042a22023-11-11 08:53:32 +01007708 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007709 lines =<< trim END
7710 vim9script
7711 class A
7712 def _Foo()
7713 enddef
7714 endclass
7715 def Bar()
7716 var a = A.new()
7717 var Fn = a._Foo
7718 enddef
7719 Bar()
7720 END
Ernie Rael03042a22023-11-11 08:53:32 +01007721 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007722
Ernie Rael03042a22023-11-11 08:53:32 +01007723 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007724 lines =<< trim END
7725 vim9script
7726 class A
7727 def _Foo()
7728 enddef
7729 endclass
7730 var a = A.new()
7731 var Fn = a._Foo
7732 END
Ernie Rael03042a22023-11-11 08:53:32 +01007733 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007734
Ernie Rael03042a22023-11-11 08:53:32 +01007735 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007736 lines =<< trim END
7737 vim9script
7738 class A
7739 def _Foo(): list<number>
7740 return [3, 2, 1]
7741 enddef
7742 def Bar()
7743 var Fn = this._Foo
7744 assert_equal([3, 2, 1], Fn())
7745 enddef
7746 endclass
7747 var a = A.new()
7748 a.Bar()
7749 END
7750 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007751
7752 # Using object method funcref using call()
7753 lines =<< trim END
7754 vim9script
7755 class A
7756 this.val: number
7757 def Foo(): number
7758 return this.val
7759 enddef
7760 endclass
7761
7762 def Bar(obj: A)
7763 assert_equal(123, call(obj.Foo, []))
7764 enddef
7765
7766 var a = A.new(123)
7767 Bar(a)
7768 assert_equal(123, call(a.Foo, []))
7769 END
7770 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007771enddef
7772
7773" Test for using a class method as a funcref
7774def Test_class_funcref()
7775 # Using class method funcref in a def function
7776 var lines =<< trim END
7777 vim9script
7778 class A
7779 static def Foo(): list<number>
7780 return [3, 2, 1]
7781 enddef
7782 endclass
7783 def Bar()
7784 var Fn = A.Foo
7785 assert_equal([3, 2, 1], Fn())
7786 enddef
7787 Bar()
7788 END
7789 v9.CheckSourceSuccess(lines)
7790
7791 # Using class method funcref at script level
7792 lines =<< trim END
7793 vim9script
7794 class A
7795 static def Foo(): dict<number>
7796 return {a: 1, b: 2}
7797 enddef
7798 endclass
7799 var Fn = A.Foo
7800 assert_equal({a: 1, b: 2}, Fn())
7801 END
7802 v9.CheckSourceSuccess(lines)
7803
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007804 # Using class method funcref at the script level
7805 lines =<< trim END
7806 vim9script
7807 class A
7808 public static val: number
7809 static def Foo(): number
7810 return val
7811 enddef
7812 endclass
7813 A.val = 567
7814 var Fn = A.Foo
7815 assert_equal(567, Fn())
7816 END
7817 v9.CheckSourceSuccess(lines)
7818
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007819 # Using function() to get a class method funcref
7820 lines =<< trim END
7821 vim9script
7822 class A
7823 static def Foo(l: list<any>): list<any>
7824 return l
7825 enddef
7826 endclass
7827 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
7828 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7829 END
7830 v9.CheckSourceSuccess(lines)
7831
7832 # Using a class method funcref from another class method
7833 lines =<< trim END
7834 vim9script
7835 class A
7836 static def Foo(): list<number>
7837 return [3, 2, 1]
7838 enddef
7839 static def Bar()
7840 var Fn = Foo
7841 assert_equal([3, 2, 1], Fn())
7842 enddef
7843 endclass
7844 A.Bar()
7845 END
7846 v9.CheckSourceSuccess(lines)
7847
7848 # Use a class method with a function returning a funcref and then call the
7849 # funcref.
7850 lines =<< trim END
7851 vim9script
7852
7853 def Map(F: func(number): number): func(number): number
7854 return (n: number) => F(n)
7855 enddef
7856
7857 class Math
7858 static def StaticDouble(n: number): number
7859 return 2 * n
7860 enddef
7861 endclass
7862
7863 assert_equal(48, Map(Math.StaticDouble)(24))
7864 END
7865 v9.CheckSourceSuccess(lines)
7866
Ernie Rael03042a22023-11-11 08:53:32 +01007867 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007868 lines =<< trim END
7869 vim9script
7870 class A
7871 static def _Foo()
7872 enddef
7873 endclass
7874 def Bar()
7875 var Fn = A._Foo
7876 enddef
7877 Bar()
7878 END
Ernie Rael03042a22023-11-11 08:53:32 +01007879 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007880
Ernie Rael03042a22023-11-11 08:53:32 +01007881 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007882 lines =<< trim END
7883 vim9script
7884 class A
7885 static def _Foo()
7886 enddef
7887 endclass
7888 var Fn = A._Foo
7889 END
Ernie Rael03042a22023-11-11 08:53:32 +01007890 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007891
Ernie Rael03042a22023-11-11 08:53:32 +01007892 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007893 lines =<< trim END
7894 vim9script
7895 class A
7896 static def _Foo(): list<number>
7897 return [3, 2, 1]
7898 enddef
7899 static def Bar()
7900 var Fn = _Foo
7901 assert_equal([3, 2, 1], Fn())
7902 enddef
7903 endclass
7904 A.Bar()
7905 END
7906 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007907
7908 # Using class method funcref using call()
7909 lines =<< trim END
7910 vim9script
7911 class A
7912 public static val: number
7913 static def Foo(): number
7914 return val
7915 enddef
7916 endclass
7917
7918 def Bar()
7919 A.val = 468
7920 assert_equal(468, call(A.Foo, []))
7921 enddef
7922 Bar()
7923 assert_equal(468, call(A.Foo, []))
7924 END
7925 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007926enddef
7927
7928" Test for using an object member as a funcref
7929def Test_object_member_funcref()
7930 # Using a funcref object variable in an object method
7931 var lines =<< trim END
7932 vim9script
7933 def Foo(n: number): number
7934 return n * 10
7935 enddef
7936
7937 class A
7938 this.Cb: func(number): number = Foo
7939 def Bar()
7940 assert_equal(200, this.Cb(20))
7941 enddef
7942 endclass
7943
7944 var a = A.new()
7945 a.Bar()
7946 END
7947 v9.CheckSourceSuccess(lines)
7948
7949 # Using a funcref object variable in a def method
7950 lines =<< trim END
7951 vim9script
7952 def Foo(n: number): number
7953 return n * 10
7954 enddef
7955
7956 class A
7957 this.Cb: func(number): number = Foo
7958 endclass
7959
7960 def Bar()
7961 var a = A.new()
7962 assert_equal(200, a.Cb(20))
7963 enddef
7964 Bar()
7965 END
7966 v9.CheckSourceSuccess(lines)
7967
7968 # Using a funcref object variable at script level
7969 lines =<< trim END
7970 vim9script
7971 def Foo(n: number): number
7972 return n * 10
7973 enddef
7974
7975 class A
7976 this.Cb: func(number): number = Foo
7977 endclass
7978
7979 var a = A.new()
7980 assert_equal(200, a.Cb(20))
7981 END
7982 v9.CheckSourceSuccess(lines)
7983
7984 # Using a funcref object variable pointing to an object method in an object
7985 # method.
7986 lines =<< trim END
7987 vim9script
7988 class A
7989 this.Cb: func(number): number = this.Foo
7990 def Foo(n: number): number
7991 return n * 10
7992 enddef
7993 def Bar()
7994 assert_equal(200, this.Cb(20))
7995 enddef
7996 endclass
7997
7998 var a = A.new()
7999 a.Bar()
8000 END
8001 v9.CheckSourceSuccess(lines)
8002
8003 # Using a funcref object variable pointing to an object method in a def
8004 # method.
8005 lines =<< trim END
8006 vim9script
8007 class A
8008 this.Cb: func(number): number = this.Foo
8009 def Foo(n: number): number
8010 return n * 10
8011 enddef
8012 endclass
8013
8014 def Bar()
8015 var a = A.new()
8016 assert_equal(200, a.Cb(20))
8017 enddef
8018 Bar()
8019 END
8020 v9.CheckSourceSuccess(lines)
8021
8022 # Using a funcref object variable pointing to an object method at script
8023 # level.
8024 lines =<< trim END
8025 vim9script
8026 class A
8027 this.Cb = this.Foo
8028 def Foo(n: number): number
8029 return n * 10
8030 enddef
8031 endclass
8032
8033 var a = A.new()
8034 assert_equal(200, a.Cb(20))
8035 END
8036 v9.CheckSourceSuccess(lines)
8037enddef
8038
8039" Test for using a class member as a funcref
8040def Test_class_member_funcref()
8041 # Using a funcref class variable in a class method
8042 var lines =<< trim END
8043 vim9script
8044 def Foo(n: number): number
8045 return n * 10
8046 enddef
8047
8048 class A
8049 static Cb = Foo
8050 static def Bar()
8051 assert_equal(200, Cb(20))
8052 enddef
8053 endclass
8054
8055 A.Bar()
8056 END
8057 v9.CheckSourceSuccess(lines)
8058
8059 # Using a funcref class variable in a def method
8060 lines =<< trim END
8061 vim9script
8062 def Foo(n: number): number
8063 return n * 10
8064 enddef
8065
8066 class A
8067 public static Cb = Foo
8068 endclass
8069
8070 def Bar()
8071 assert_equal(200, A.Cb(20))
8072 enddef
8073 Bar()
8074 END
8075 v9.CheckSourceSuccess(lines)
8076
8077 # Using a funcref class variable at script level
8078 lines =<< trim END
8079 vim9script
8080 def Foo(n: number): number
8081 return n * 10
8082 enddef
8083
8084 class A
8085 public static Cb = Foo
8086 endclass
8087
8088 assert_equal(200, A.Cb(20))
8089 END
8090 v9.CheckSourceSuccess(lines)
8091
8092 # Using a funcref class variable pointing to a class method in a class
8093 # method.
8094 lines =<< trim END
8095 vim9script
8096 class A
8097 static Cb: func(number): number
8098 static def Foo(n: number): number
8099 return n * 10
8100 enddef
8101 static def Init()
8102 Cb = Foo
8103 enddef
8104 static def Bar()
8105 assert_equal(200, Cb(20))
8106 enddef
8107 endclass
8108
8109 A.Init()
8110 A.Bar()
8111 END
8112 v9.CheckSourceSuccess(lines)
8113
8114 # Using a funcref class variable pointing to a class method in a def method.
8115 lines =<< trim END
8116 vim9script
8117 class A
8118 static Cb: func(number): number
8119 static def Foo(n: number): number
8120 return n * 10
8121 enddef
8122 static def Init()
8123 Cb = Foo
8124 enddef
8125 endclass
8126
8127 def Bar()
8128 A.Init()
8129 assert_equal(200, A.Cb(20))
8130 enddef
8131 Bar()
8132 END
8133 v9.CheckSourceSuccess(lines)
8134
8135 # Using a funcref class variable pointing to a class method at script level.
8136 lines =<< trim END
8137 vim9script
8138 class A
8139 static Cb: func(number): number
8140 static def Foo(n: number): number
8141 return n * 10
8142 enddef
8143 static def Init()
8144 Cb = Foo
8145 enddef
8146 endclass
8147
8148 A.Init()
8149 assert_equal(200, A.Cb(20))
8150 END
8151 v9.CheckSourceSuccess(lines)
8152enddef
8153
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008154" Test for using object methods as popup callback functions
8155def Test_objmethod_popup_callback()
8156 # Use the popup from the script level
8157 var lines =<< trim END
8158 vim9script
8159
8160 class A
8161 this.selection: number = -1
8162 this.filterkeys: list<string> = []
8163
8164 def PopupFilter(id: number, key: string): bool
8165 add(this.filterkeys, key)
8166 return popup_filter_yesno(id, key)
8167 enddef
8168
8169 def PopupCb(id: number, result: number)
8170 this.selection = result ? 100 : 200
8171 enddef
8172 endclass
8173
8174 var a = A.new()
8175 feedkeys('', 'xt')
8176 var winid = popup_create('Y/N?',
8177 {filter: a.PopupFilter, callback: a.PopupCb})
8178 feedkeys('y', 'xt')
8179 popup_close(winid)
8180 assert_equal(100, a.selection)
8181 assert_equal(['y'], a.filterkeys)
8182 feedkeys('', 'xt')
8183 winid = popup_create('Y/N?',
8184 {filter: a.PopupFilter, callback: a.PopupCb})
8185 feedkeys('n', 'xt')
8186 popup_close(winid)
8187 assert_equal(200, a.selection)
8188 assert_equal(['y', 'n'], a.filterkeys)
8189 END
8190 v9.CheckSourceSuccess(lines)
8191
8192 # Use the popup from a def function
8193 lines =<< trim END
8194 vim9script
8195
8196 class A
8197 this.selection: number = -1
8198 this.filterkeys: list<string> = []
8199
8200 def PopupFilter(id: number, key: string): bool
8201 add(this.filterkeys, key)
8202 return popup_filter_yesno(id, key)
8203 enddef
8204
8205 def PopupCb(id: number, result: number)
8206 this.selection = result ? 100 : 200
8207 enddef
8208 endclass
8209
8210 def Foo()
8211 var a = A.new()
8212 feedkeys('', 'xt')
8213 var winid = popup_create('Y/N?',
8214 {filter: a.PopupFilter, callback: a.PopupCb})
8215 feedkeys('y', 'xt')
8216 popup_close(winid)
8217 assert_equal(100, a.selection)
8218 assert_equal(['y'], a.filterkeys)
8219 feedkeys('', 'xt')
8220 winid = popup_create('Y/N?',
8221 {filter: a.PopupFilter, callback: a.PopupCb})
8222 feedkeys('n', 'xt')
8223 popup_close(winid)
8224 assert_equal(200, a.selection)
8225 assert_equal(['y', 'n'], a.filterkeys)
8226 enddef
8227 Foo()
8228 END
8229 v9.CheckSourceSuccess(lines)
8230enddef
8231
8232" Test for using class methods as popup callback functions
8233def Test_classmethod_popup_callback()
8234 # Use the popup from the script level
8235 var lines =<< trim END
8236 vim9script
8237
8238 class A
8239 static selection: number = -1
8240 static filterkeys: list<string> = []
8241
8242 static def PopupFilter(id: number, key: string): bool
8243 add(filterkeys, key)
8244 return popup_filter_yesno(id, key)
8245 enddef
8246
8247 static def PopupCb(id: number, result: number)
8248 selection = result ? 100 : 200
8249 enddef
8250 endclass
8251
8252 feedkeys('', 'xt')
8253 var winid = popup_create('Y/N?',
8254 {filter: A.PopupFilter, callback: A.PopupCb})
8255 feedkeys('y', 'xt')
8256 popup_close(winid)
8257 assert_equal(100, A.selection)
8258 assert_equal(['y'], A.filterkeys)
8259 feedkeys('', 'xt')
8260 winid = popup_create('Y/N?',
8261 {filter: A.PopupFilter, callback: A.PopupCb})
8262 feedkeys('n', 'xt')
8263 popup_close(winid)
8264 assert_equal(200, A.selection)
8265 assert_equal(['y', 'n'], A.filterkeys)
8266 END
8267 v9.CheckSourceSuccess(lines)
8268
8269 # Use the popup from a def function
8270 lines =<< trim END
8271 vim9script
8272
8273 class A
8274 static selection: number = -1
8275 static filterkeys: list<string> = []
8276
8277 static def PopupFilter(id: number, key: string): bool
8278 add(filterkeys, key)
8279 return popup_filter_yesno(id, key)
8280 enddef
8281
8282 static def PopupCb(id: number, result: number)
8283 selection = result ? 100 : 200
8284 enddef
8285 endclass
8286
8287 def Foo()
8288 feedkeys('', 'xt')
8289 var winid = popup_create('Y/N?',
8290 {filter: A.PopupFilter, callback: A.PopupCb})
8291 feedkeys('y', 'xt')
8292 popup_close(winid)
8293 assert_equal(100, A.selection)
8294 assert_equal(['y'], A.filterkeys)
8295 feedkeys('', 'xt')
8296 winid = popup_create('Y/N?',
8297 {filter: A.PopupFilter, callback: A.PopupCb})
8298 feedkeys('n', 'xt')
8299 popup_close(winid)
8300 assert_equal(200, A.selection)
8301 assert_equal(['y', 'n'], A.filterkeys)
8302 enddef
8303 Foo()
8304 END
8305 v9.CheckSourceSuccess(lines)
8306enddef
8307
8308" Test for using an object method as a timer callback function
8309def Test_objmethod_timer_callback()
8310 # Use the timer callback from script level
8311 var lines =<< trim END
8312 vim9script
8313
8314 class A
8315 this.timerTick: number = -1
8316 def TimerCb(timerID: number)
8317 this.timerTick = 6
8318 enddef
8319 endclass
8320
8321 var a = A.new()
8322 timer_start(0, a.TimerCb)
8323 var maxWait = 5
8324 while maxWait > 0 && a.timerTick == -1
8325 :sleep 10m
8326 maxWait -= 1
8327 endwhile
8328 assert_equal(6, a.timerTick)
8329 END
8330 v9.CheckSourceSuccess(lines)
8331
8332 # Use the timer callback from a def function
8333 lines =<< trim END
8334 vim9script
8335
8336 class A
8337 this.timerTick: number = -1
8338 def TimerCb(timerID: number)
8339 this.timerTick = 6
8340 enddef
8341 endclass
8342
8343 def Foo()
8344 var a = A.new()
8345 timer_start(0, a.TimerCb)
8346 var maxWait = 5
8347 while maxWait > 0 && a.timerTick == -1
8348 :sleep 10m
8349 maxWait -= 1
8350 endwhile
8351 assert_equal(6, a.timerTick)
8352 enddef
8353 Foo()
8354 END
8355 v9.CheckSourceSuccess(lines)
8356enddef
8357
8358" Test for using a class method as a timer callback function
8359def Test_classmethod_timer_callback()
8360 # Use the timer callback from script level
8361 var lines =<< trim END
8362 vim9script
8363
8364 class A
8365 static timerTick: number = -1
8366 static def TimerCb(timerID: number)
8367 timerTick = 6
8368 enddef
8369 endclass
8370
8371 timer_start(0, A.TimerCb)
8372 var maxWait = 5
8373 while maxWait > 0 && A.timerTick == -1
8374 :sleep 10m
8375 maxWait -= 1
8376 endwhile
8377 assert_equal(6, A.timerTick)
8378 END
8379 v9.CheckSourceSuccess(lines)
8380
8381 # Use the timer callback from a def function
8382 lines =<< trim END
8383 vim9script
8384
8385 class A
8386 static timerTick: number = -1
8387 static def TimerCb(timerID: number)
8388 timerTick = 6
8389 enddef
8390 endclass
8391
8392 def Foo()
8393 timer_start(0, A.TimerCb)
8394 var maxWait = 5
8395 while maxWait > 0 && A.timerTick == -1
8396 :sleep 10m
8397 maxWait -= 1
8398 endwhile
8399 assert_equal(6, A.timerTick)
8400 enddef
8401 Foo()
8402 END
8403 v9.CheckSourceSuccess(lines)
8404enddef
8405
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008406" Test for using a class variable as the first and/or second operand of a binary
8407" operator.
8408def Test_class_variable_as_operands()
8409 var lines =<< trim END
8410 vim9script
8411 class Tests
8412 static truthy: bool = true
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008413 public static TruthyFn: func
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008414 static list: list<any> = []
8415 static four: number = 4
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008416 static str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008417
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008418 static def Str(): string
8419 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008420 enddef
8421
8422 static def Four(): number
8423 return four
8424 enddef
8425
8426 static def List(): list<any>
8427 return list
8428 enddef
8429
8430 static def Truthy(): bool
8431 return truthy
8432 enddef
8433
8434 def TestOps()
8435 assert_true(Tests.truthy == truthy)
8436 assert_true(truthy == Tests.truthy)
8437 assert_true(Tests.list isnot [])
8438 assert_true([] isnot Tests.list)
8439 assert_equal(2, Tests.four >> 1)
8440 assert_equal(16, 1 << Tests.four)
8441 assert_equal(8, Tests.four + four)
8442 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008443 assert_equal('hellohello', Tests.str .. str)
8444 assert_equal('hellohello', str .. Tests.str)
8445
8446 # Using class variable for list indexing
8447 var l = range(10)
8448 assert_equal(4, l[Tests.four])
8449 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8450
8451 # Using class variable for Dict key
8452 var d = {hello: 'abc'}
8453 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008454 enddef
8455 endclass
8456
8457 def TestOps2()
8458 assert_true(Tests.truthy == Tests.Truthy())
8459 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008460 assert_true(Tests.truthy == Tests.TruthyFn())
8461 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008462 assert_true(Tests.list is Tests.List())
8463 assert_true(Tests.List() is Tests.list)
8464 assert_equal(2, Tests.four >> 1)
8465 assert_equal(16, 1 << Tests.four)
8466 assert_equal(8, Tests.four + Tests.Four())
8467 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008468 assert_equal('hellohello', Tests.str .. Tests.Str())
8469 assert_equal('hellohello', Tests.Str() .. Tests.str)
8470
8471 # Using class variable for list indexing
8472 var l = range(10)
8473 assert_equal(4, l[Tests.four])
8474 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8475
8476 # Using class variable for Dict key
8477 var d = {hello: 'abc'}
8478 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008479 enddef
8480
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008481 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008482 var t = Tests.new()
8483 t.TestOps()
8484 TestOps2()
8485
8486 assert_true(Tests.truthy == Tests.Truthy())
8487 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008488 assert_true(Tests.truthy == Tests.TruthyFn())
8489 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008490 assert_true(Tests.list is Tests.List())
8491 assert_true(Tests.List() is Tests.list)
8492 assert_equal(2, Tests.four >> 1)
8493 assert_equal(16, 1 << Tests.four)
8494 assert_equal(8, Tests.four + Tests.Four())
8495 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008496 assert_equal('hellohello', Tests.str .. Tests.Str())
8497 assert_equal('hellohello', Tests.Str() .. Tests.str)
8498
8499 # Using class variable for list indexing
8500 var l = range(10)
8501 assert_equal(4, l[Tests.four])
8502 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8503
8504 # Using class variable for Dict key
8505 var d = {hello: 'abc'}
8506 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008507 END
8508 v9.CheckSourceSuccess(lines)
8509enddef
8510
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008511" Test for checking the type of the key used to access an object dict member.
8512def Test_dict_member_key_type_check()
8513 var lines =<< trim END
8514 vim9script
8515
8516 abstract class State
8517 this.numbers: dict<string> = {0: 'nil', 1: 'unity'}
8518 endclass
8519
8520 class Test extends State
8521 def ObjMethodTests()
8522 var cursor: number = 0
8523 var z: number = 0
8524 [this.numbers[cursor]] = ['zero.1']
8525 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8526 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8527 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8528 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8529 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8530 [this.numbers[cursor], z] = ['zero.4', 1]
8531 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8532 [z, this.numbers[cursor]] = [1, 'zero.5']
8533 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8534 enddef
8535
8536 static def ClassMethodTests(that: State)
8537 var cursor: number = 0
8538 var z: number = 0
8539 [that.numbers[cursor]] = ['zero.1']
8540 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8541 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8542 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8543 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8544 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8545 [that.numbers[cursor], z] = ['zero.4', 1]
8546 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8547 [z, that.numbers[cursor]] = [1, 'zero.5']
8548 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8549 enddef
8550
8551 def new()
8552 enddef
8553
8554 def newMethodTests()
8555 var cursor: number = 0
8556 var z: number
8557 [this.numbers[cursor]] = ['zero.1']
8558 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8559 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8560 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8561 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8562 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8563 [this.numbers[cursor], z] = ['zero.4', 1]
8564 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8565 [z, this.numbers[cursor]] = [1, 'zero.5']
8566 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8567 enddef
8568 endclass
8569
8570 def DefFuncTests(that: Test)
8571 var cursor: number = 0
8572 var z: number
8573 [that.numbers[cursor]] = ['zero.1']
8574 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8575 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8576 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8577 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8578 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8579 [that.numbers[cursor], z] = ['zero.4', 1]
8580 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8581 [z, that.numbers[cursor]] = [1, 'zero.5']
8582 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8583 enddef
8584
8585 Test.newMethodTests()
8586 Test.new().ObjMethodTests()
8587 Test.ClassMethodTests(Test.new())
8588 DefFuncTests(Test.new())
8589
8590 const test: Test = Test.new()
8591 var cursor: number = 0
8592 [test.numbers[cursor], cursor] = ['zero', 1]
8593 [cursor, test.numbers[cursor]] = [1, 'one']
8594 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8595 END
8596 v9.CheckSourceSuccess(lines)
8597
8598 lines =<< trim END
8599 vim9script
8600
8601 class A
8602 this.numbers: dict<string> = {a: '1', b: '2'}
8603
8604 def new()
8605 enddef
8606
8607 def Foo()
8608 var z: number
8609 [this.numbers.a, z] = [{}, 10]
8610 enddef
8611 endclass
8612
8613 var a = A.new()
8614 a.Foo()
8615 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008616 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008617
8618 lines =<< trim END
8619 vim9script
8620
8621 class A
8622 this.numbers: dict<number> = {a: 1, b: 2}
8623
8624 def new()
8625 enddef
8626
8627 def Foo()
8628 var x: string = 'a'
8629 var y: number
8630 [this.numbers[x], y] = [{}, 10]
8631 enddef
8632 endclass
8633
8634 var a = A.new()
8635 a.Foo()
8636 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008637 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008638enddef
8639
mityua5550692023-11-25 15:41:20 +01008640def Test_compile_many_def_functions_in_funcref_instr()
8641 # This used to crash Vim. This is reproducible only when run on new instance
8642 # of Vim.
8643 var lines =<< trim END
8644 vim9script
8645
8646 class A
8647 def new()
8648 this.TakeFunc(this.F00)
8649 enddef
8650
8651 def TakeFunc(F: func)
8652 enddef
8653
8654 def F00()
8655 this.F01()
8656 this.F02()
8657 this.F03()
8658 this.F04()
8659 this.F05()
8660 this.F06()
8661 this.F07()
8662 this.F08()
8663 this.F09()
8664 this.F10()
8665 this.F11()
8666 this.F12()
8667 this.F13()
8668 this.F14()
8669 this.F15()
8670 this.F16()
8671 this.F17()
8672 this.F18()
8673 this.F19()
8674 this.F20()
8675 this.F21()
8676 this.F22()
8677 this.F23()
8678 this.F24()
8679 this.F25()
8680 this.F26()
8681 this.F27()
8682 this.F28()
8683 this.F29()
8684 this.F30()
8685 this.F31()
8686 this.F32()
8687 this.F33()
8688 this.F34()
8689 this.F35()
8690 this.F36()
8691 this.F37()
8692 this.F38()
8693 this.F39()
8694 this.F40()
8695 this.F41()
8696 this.F42()
8697 this.F43()
8698 this.F44()
8699 this.F45()
8700 this.F46()
8701 this.F47()
8702 enddef
8703
8704 def F01()
8705 enddef
8706 def F02()
8707 enddef
8708 def F03()
8709 enddef
8710 def F04()
8711 enddef
8712 def F05()
8713 enddef
8714 def F06()
8715 enddef
8716 def F07()
8717 enddef
8718 def F08()
8719 enddef
8720 def F09()
8721 enddef
8722 def F10()
8723 enddef
8724 def F11()
8725 enddef
8726 def F12()
8727 enddef
8728 def F13()
8729 enddef
8730 def F14()
8731 enddef
8732 def F15()
8733 enddef
8734 def F16()
8735 enddef
8736 def F17()
8737 enddef
8738 def F18()
8739 enddef
8740 def F19()
8741 enddef
8742 def F20()
8743 enddef
8744 def F21()
8745 enddef
8746 def F22()
8747 enddef
8748 def F23()
8749 enddef
8750 def F24()
8751 enddef
8752 def F25()
8753 enddef
8754 def F26()
8755 enddef
8756 def F27()
8757 enddef
8758 def F28()
8759 enddef
8760 def F29()
8761 enddef
8762 def F30()
8763 enddef
8764 def F31()
8765 enddef
8766 def F32()
8767 enddef
8768 def F33()
8769 enddef
8770 def F34()
8771 enddef
8772 def F35()
8773 enddef
8774 def F36()
8775 enddef
8776 def F37()
8777 enddef
8778 def F38()
8779 enddef
8780 def F39()
8781 enddef
8782 def F40()
8783 enddef
8784 def F41()
8785 enddef
8786 def F42()
8787 enddef
8788 def F43()
8789 enddef
8790 def F44()
8791 enddef
8792 def F45()
8793 enddef
8794 def F46()
8795 enddef
8796 def F47()
8797 enddef
8798 endclass
8799
8800 A.new()
8801 END
8802 writefile(lines, 'Xscript', 'D')
8803 g:RunVim([], [], '-u NONE -S Xscript -c qa')
8804 assert_equal(0, v:shell_error)
8805enddef
8806
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008807" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker