blob: e0f5db6253d07d192f8e42bfa865fe9ea46919b7 [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
Ernie Rael2025af12023-12-12 16:58:00 +01003331 type AliasBase1 = Base1
3332 type AliasBase2 = Base2
3333 type AliasIntf1 = Intf1
3334 type AliasMix1 = Mix1
3335
LemonBoyafe04662023-08-23 21:08:11 +02003336 var b1 = Base1.new()
3337 var b2 = Base2.new()
3338 var b3 = Base3.new()
3339
3340 assert_true(instanceof(b1, Base1))
3341 assert_true(instanceof(b2, Base1))
3342 assert_false(instanceof(b1, Base2))
3343 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003344 assert_true(instanceof(b3, Base1, Base2, Intf1))
3345
3346 assert_true(instanceof(b1, AliasBase1))
3347 assert_true(instanceof(b2, AliasBase1))
3348 assert_false(instanceof(b1, AliasBase2))
3349 assert_true(instanceof(b3, AliasMix1))
3350 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003351
3352 def Foo()
3353 var a1 = Base1.new()
3354 var a2 = Base2.new()
3355 var a3 = Base3.new()
3356
3357 assert_true(instanceof(a1, Base1))
3358 assert_true(instanceof(a2, Base1))
3359 assert_false(instanceof(a1, Base2))
3360 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003361 assert_true(instanceof(a3, Base1, Base2, Intf1))
3362
3363 assert_true(instanceof(a1, AliasBase1))
3364 assert_true(instanceof(a2, AliasBase1))
3365 assert_false(instanceof(a1, AliasBase2))
3366 assert_true(instanceof(a3, AliasMix1))
3367 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003368 enddef
3369 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003370
3371 var o_null: Base1
3372 assert_false(instanceof(o_null, Base1))
3373
LemonBoyafe04662023-08-23 21:08:11 +02003374 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003375 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003376
3377 lines =<< trim END
3378 vim9script
3379
3380 class Base1
3381 endclass
3382 instanceof(Base1.new())
3383 END
3384 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3385
3386 lines =<< trim END
3387 vim9script
3388
3389 class Base1
3390 endclass
3391 def F()
3392 instanceof(Base1.new())
3393 enddef
3394 F()
3395 END
3396 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3397
3398 lines =<< trim END
3399 vim9script
3400
3401 class Base1
3402 endclass
3403
3404 class Base2
3405 endclass
3406
3407 var o = Base2.new()
3408 instanceof(o, Base1, Base2, 3)
3409 END
3410 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3411
3412 lines =<< trim END
3413 vim9script
3414
3415 class Base1
3416 endclass
3417
3418 class Base2
3419 endclass
3420
3421 def F()
3422 var o = Base2.new()
3423 instanceof(o, Base1, Base2, 3)
3424 enddef
3425 F()
3426 END
3427 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003428enddef
3429
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003430" Test for calling a method in the parent class that is extended partially.
3431" This used to fail with the 'E118: Too many arguments for function: Text' error
3432" message (Github issue #12524).
3433def Test_call_method_in_parent_class()
3434 var lines =<< trim END
3435 vim9script
3436
3437 class Widget
3438 this._lnum: number = 1
3439
3440 def SetY(lnum: number)
3441 this._lnum = lnum
3442 enddef
3443
3444 def Text(): string
3445 return ''
3446 enddef
3447 endclass
3448
3449 class Foo extends Widget
3450 def Text(): string
3451 return '<Foo>'
3452 enddef
3453 endclass
3454
3455 def Stack(w1: Widget, w2: Widget): list<Widget>
3456 w1.SetY(1)
3457 w2.SetY(2)
3458 return [w1, w2]
3459 enddef
3460
3461 var foo1 = Foo.new()
3462 var foo2 = Foo.new()
3463 var l = Stack(foo1, foo2)
3464 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003465 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003466enddef
3467
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003468" Test for calling methods from three levels of classes
3469def Test_multi_level_method_call()
3470 var lines =<< trim END
3471 vim9script
3472
3473 var A_func1: number = 0
3474 var A_func2: number = 0
3475 var A_func3: number = 0
3476 var B_func2: number = 0
3477 var B_func3: number = 0
3478 var C_func3: number = 0
3479
3480 class A
3481 def Func1()
3482 A_func1 += 1
3483 enddef
3484
3485 def Func2()
3486 A_func2 += 1
3487 enddef
3488
3489 def Func3()
3490 A_func3 += 1
3491 enddef
3492 endclass
3493
3494 class B extends A
3495 def Func2()
3496 B_func2 += 1
3497 enddef
3498
3499 def Func3()
3500 B_func3 += 1
3501 enddef
3502 endclass
3503
3504 class C extends B
3505 def Func3()
3506 C_func3 += 1
3507 enddef
3508 endclass
3509
3510 def A_CallFuncs(a: A)
3511 a.Func1()
3512 a.Func2()
3513 a.Func3()
3514 enddef
3515
3516 def B_CallFuncs(b: B)
3517 b.Func1()
3518 b.Func2()
3519 b.Func3()
3520 enddef
3521
3522 def C_CallFuncs(c: C)
3523 c.Func1()
3524 c.Func2()
3525 c.Func3()
3526 enddef
3527
3528 var cobj = C.new()
3529 A_CallFuncs(cobj)
3530 B_CallFuncs(cobj)
3531 C_CallFuncs(cobj)
3532 assert_equal(3, A_func1)
3533 assert_equal(0, A_func2)
3534 assert_equal(0, A_func3)
3535 assert_equal(3, B_func2)
3536 assert_equal(0, B_func3)
3537 assert_equal(3, C_func3)
3538 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003539 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003540enddef
3541
3542" Test for using members from three levels of classes
3543def Test_multi_level_member_access()
3544 var lines =<< trim END
3545 vim9script
3546
3547 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003548 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003549 endclass
3550
3551 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003552 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003553 endclass
3554
3555 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003556 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003557 endclass
3558
3559 def A_members(a: A)
3560 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003561 enddef
3562
3563 def B_members(b: B)
3564 b.val1 += 1
3565 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003566 enddef
3567
3568 def C_members(c: C)
3569 c.val1 += 1
3570 c.val2 += 1
3571 c.val3 += 1
3572 enddef
3573
3574 var cobj = C.new()
3575 A_members(cobj)
3576 B_members(cobj)
3577 C_members(cobj)
3578 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003579 assert_equal(2, cobj.val2)
3580 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003581 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003582 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003583enddef
3584
LemonBoy0ffc17a2023-08-20 18:09:11 +02003585" Test expansion of <stack> with class methods.
3586def Test_stack_expansion_with_methods()
3587 var lines =<< trim END
3588 vim9script
3589
3590 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003591 def M1()
3592 F0()
3593 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003594 endclass
3595
3596 def F0()
3597 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3598 enddef
3599
3600 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003601 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003602 enddef
3603
3604 F()
3605 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003606 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003607enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003608
3609" Test the return type of the new() constructor
3610def Test_new_return_type()
3611 # new() uses the default return type and there is no return statement
3612 var lines =<< trim END
3613 vim9script
3614
3615 class C
3616 this._bufnr: number
3617
3618 def new(this._bufnr)
3619 if !bufexists(this._bufnr)
3620 this._bufnr = -1
3621 endif
3622 enddef
3623 endclass
3624
3625 var c = C.new(12345)
3626 assert_equal('object<C>', typename(c))
3627
3628 var v1: C
3629 v1 = C.new(12345)
3630 assert_equal('object<C>', typename(v1))
3631
3632 def F()
3633 var v2: C
3634 v2 = C.new(12345)
3635 assert_equal('object<C>', typename(v2))
3636 enddef
3637 F()
3638 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003639 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003640
3641 # new() uses the default return type and an empty 'return' statement
3642 lines =<< trim END
3643 vim9script
3644
3645 class C
3646 this._bufnr: number
3647
3648 def new(this._bufnr)
3649 if !bufexists(this._bufnr)
3650 this._bufnr = -1
3651 return
3652 endif
3653 enddef
3654 endclass
3655
3656 var c = C.new(12345)
3657 assert_equal('object<C>', typename(c))
3658
3659 var v1: C
3660 v1 = C.new(12345)
3661 assert_equal('object<C>', typename(v1))
3662
3663 def F()
3664 var v2: C
3665 v2 = C.new(12345)
3666 assert_equal('object<C>', typename(v2))
3667 enddef
3668 F()
3669 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003670 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003671
3672 # new() uses "any" return type and returns "this"
3673 lines =<< trim END
3674 vim9script
3675
3676 class C
3677 this._bufnr: number
3678
3679 def new(this._bufnr): any
3680 if !bufexists(this._bufnr)
3681 this._bufnr = -1
3682 return this
3683 endif
3684 enddef
3685 endclass
3686 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003687 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003688
3689 # new() uses 'Dict' return type and returns a Dict
3690 lines =<< trim END
3691 vim9script
3692
3693 class C
3694 this._state: dict<any>
3695
3696 def new(): dict<any>
3697 this._state = {}
3698 return this._state
3699 enddef
3700 endclass
3701
3702 var c = C.new()
3703 assert_equal('object<C>', typename(c))
3704 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003705 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003706enddef
3707
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003708" Test for checking a member initialization type at run time.
3709def Test_runtime_type_check_for_member_init()
3710 var lines =<< trim END
3711 vim9script
3712
3713 var retnum: bool = false
3714
3715 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003716 retnum = !retnum
3717 if retnum
3718 return 1
3719 else
3720 return "hello"
3721 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003722 enddef
3723
3724 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003725 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003726 endclass
3727
3728 var c1 = C.new()
3729 var c2 = C.new()
3730 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003731 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003732enddef
3733
3734" Test for locking a variable referring to an object and reassigning to another
3735" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003736def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003737 var lines =<< trim END
3738 vim9script
3739
3740 class C
3741 this.val: number
3742 def new(this.val)
3743 enddef
3744 endclass
3745
3746 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3747 lockvar 2 some_dict
3748
3749 var current: C
3750 current = some_dict['c']
3751 assert_equal(3, current.val)
3752 current = some_dict['b']
3753 assert_equal(2, current.val)
3754
3755 def F()
3756 current = some_dict['c']
3757 enddef
3758
3759 def G()
3760 current = some_dict['b']
3761 enddef
3762
3763 F()
3764 assert_equal(3, current.val)
3765 G()
3766 assert_equal(2, current.val)
3767 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003768 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003769enddef
3770
Ernie Raelee865f32023-09-29 19:53:55 +02003771" Test trying to lock an object variable from various places
3772def Test_lockvar_object_variable()
3773 # An object variable lockvar has several cases:
3774 # object method, scriptlevel, scriplevel from :def, :def arg
3775 # method arg, static method arg.
3776 # Also different depths
3777
Ernie Raelee865f32023-09-29 19:53:55 +02003778 #
3779 # lockvar of read-only object variable
3780 #
3781
3782 # read-only lockvar from object method
3783 var lines =<< trim END
3784 vim9script
3785
3786 class C
3787 this.val1: number
3788 def Lock()
3789 lockvar this.val1
3790 enddef
3791 endclass
3792 var o = C.new(3)
3793 o.Lock()
3794 END
Ernie Rael64885642023-10-04 20:16:22 +02003795 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003796
3797 # read-only lockvar from scriptlevel
3798 lines =<< trim END
3799 vim9script
3800
3801 class C
3802 this.val2: number
3803 endclass
3804 var o = C.new(3)
3805 lockvar o.val2
3806 END
3807 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3808
3809 # read-only lockvar of scriptlevel variable from def
3810 lines =<< trim END
3811 vim9script
3812
3813 class C
3814 this.val3: number
3815 endclass
3816 var o = C.new(3)
3817 def Lock()
3818 lockvar o.val3
3819 enddef
3820 Lock()
3821 END
3822 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3823
3824 # read-only lockvar of def argument variable
3825 lines =<< trim END
3826 vim9script
3827
3828 class C
3829 this.val4: number
3830 endclass
3831 def Lock(o: C)
3832 lockvar o.val4
3833 enddef
3834 Lock(C.new(3))
3835 END
3836 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3837
3838 # TODO: the following tests use type "any" for argument. Need a run time
3839 # check for access. Probably OK as is for now.
3840
3841 # read-only lockvar from object method arg
3842 lines =<< trim END
3843 vim9script
3844
3845 class C
3846 this.val5: number
3847 def Lock(o_any: any)
3848 lockvar o_any.val5
3849 enddef
3850 endclass
3851 var o = C.new(3)
3852 o.Lock(C.new(5))
3853 END
Ernie Rael64885642023-10-04 20:16:22 +02003854 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003855
3856 # read-only lockvar from class method arg
3857 lines =<< trim END
3858 vim9script
3859
3860 class C
3861 this.val6: number
3862 static def Lock(o_any: any)
3863 lockvar o_any.val6
3864 enddef
3865 endclass
3866 var o = C.new(3)
3867 C.Lock(o)
3868 END
Ernie Rael64885642023-10-04 20:16:22 +02003869 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003870
3871 #
3872 # lockvar of public object variable
3873 #
3874
3875 # lockvar from object method
3876 lines =<< trim END
3877 vim9script
3878
3879 class C
3880 public this.val1: number
3881 def Lock()
3882 lockvar this.val1
3883 enddef
3884 endclass
3885 var o = C.new(3)
3886 o.Lock()
3887 END
3888 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3889
3890 # lockvar from scriptlevel
3891 lines =<< trim END
3892 vim9script
3893
3894 class C
3895 public this.val2: number
3896 endclass
3897 var o = C.new(3)
3898 lockvar o.val2
3899 END
3900 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3901
3902 # lockvar of scriptlevel variable from def
3903 lines =<< trim END
3904 vim9script
3905
3906 class C
3907 public this.val3: number
3908 endclass
3909 var o = C.new(3)
3910 def Lock()
3911 lockvar o.val3
3912 enddef
3913 Lock()
3914 END
3915 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3916
3917 # lockvar of def argument variable
3918 lines =<< trim END
3919 vim9script
3920
3921 class C
3922 public this.val4: number
3923 endclass
3924 def Lock(o: C)
3925 lockvar o.val4
3926 enddef
3927 Lock(C.new(3))
3928 END
3929 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3930
3931 # lockvar from object method arg
3932 lines =<< trim END
3933 vim9script
3934
3935 class C
3936 public this.val5: number
3937 def Lock(o_any: any)
3938 lockvar o_any.val5
3939 enddef
3940 endclass
3941 var o = C.new(3)
3942 o.Lock(C.new(5))
3943 END
3944 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3945
3946 # lockvar from class method arg
3947 lines =<< trim END
3948 vim9script
3949
3950 class C
3951 public this.val6: number
3952 static def Lock(o_any: any)
3953 lockvar o_any.val6
3954 enddef
3955 endclass
3956 var o = C.new(3)
3957 C.Lock(o)
3958 END
3959 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3960enddef
3961
3962" Test trying to lock a class variable from various places
3963def Test_lockvar_class_variable()
3964
3965 # lockvar bare static from object method
3966 var lines =<< trim END
3967 vim9script
3968
3969 class C
3970 public static sval1: number
3971 def Lock()
3972 lockvar sval1
3973 enddef
3974 endclass
3975 var o = C.new()
3976 o.Lock()
3977 END
3978 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3979
3980 # lockvar C.static from object method
3981 lines =<< trim END
3982 vim9script
3983
3984 class C
3985 public static sval2: number
3986 def Lock()
3987 lockvar C.sval2
3988 enddef
3989 endclass
3990 var o = C.new()
3991 o.Lock()
3992 END
3993 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3994
3995 # lockvar bare static from class method
3996 lines =<< trim END
3997 vim9script
3998
3999 class C
4000 public static sval3: number
4001 static def Lock()
4002 lockvar sval3
4003 enddef
4004 endclass
4005 C.Lock()
4006 END
4007 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4008
4009 # lockvar C.static from class method
4010 lines =<< trim END
4011 vim9script
4012
4013 class C
4014 public static sval4: number
4015 static def Lock()
4016 lockvar C.sval4
4017 enddef
4018 endclass
4019 C.Lock()
4020 END
4021 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4022
4023 # lockvar C.static from script level
4024 lines =<< trim END
4025 vim9script
4026
4027 class C
4028 public static sval5: number
4029 endclass
4030 lockvar C.sval5
4031 END
4032 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4033
4034 # lockvar o.static from script level
4035 lines =<< trim END
4036 vim9script
4037
4038 class C
4039 public static sval6: number
4040 endclass
4041 var o = C.new()
4042 lockvar o.sval6
4043 END
4044 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4045enddef
4046
4047" Test locking an argument to :def
4048def Test_lockvar_argument()
4049 # Lockvar a function arg
4050 var lines =<< trim END
4051 vim9script
4052
4053 def Lock(val: any)
4054 lockvar val
4055 enddef
4056
4057 var d = {a: 1, b: 2}
4058 Lock(d)
4059
4060 d->extend({c: 3})
4061 END
4062 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4063
4064 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4065 # class member in "C". This tests lval_root_is_arg.
4066 lines =<< trim END
4067 vim9script
4068
4069 class C
4070 public static sval: list<number>
4071 endclass
4072
4073 def Lock2(sval: any)
4074 lockvar sval
4075 enddef
4076
4077 var o = C.new()
4078 Lock2(o)
4079 END
4080 v9.CheckSourceSuccess(lines)
4081
4082 # Lock a class.
4083 lines =<< trim END
4084 vim9script
4085
4086 class C
4087 public static sval: list<number>
4088 endclass
4089
4090 def Lock2(sval: any)
4091 lockvar sval
4092 enddef
4093
4094 Lock2(C)
4095 END
4096 v9.CheckSourceSuccess(lines)
4097
4098 # Lock an object.
4099 lines =<< trim END
4100 vim9script
4101
4102 class C
4103 public static sval: list<number>
4104 endclass
4105
4106 def Lock2(sval: any)
4107 lockvar sval
4108 enddef
4109
4110 Lock2(C.new())
4111 END
4112 v9.CheckSourceSuccess(lines)
4113
4114 # In this case (unlike previous) "lockvar sval" is a class member.
4115 lines =<< trim END
4116 vim9script
4117
4118 class C
4119 public static sval: list<number>
4120 def Lock2()
4121 lockvar sval
4122 enddef
4123 endclass
4124
4125
4126 var o = C.new()
4127 o.Lock2()
4128 END
4129 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4130enddef
4131
4132" Test that this can be locked without error
4133def Test_lockvar_this()
4134 # lockvar this
4135 var lines =<< trim END
4136 vim9script
4137 class C
4138 def TLock()
4139 lockvar this
4140 enddef
4141 endclass
4142 var o = C.new()
4143 o.TLock()
4144 END
4145 v9.CheckSourceSuccess(lines)
4146
4147 # lockvar four (four letter word, but not this)
4148 lines =<< trim END
4149 vim9script
4150 class C
4151 def TLock4()
4152 var four: number
4153 lockvar four
4154 enddef
4155 endclass
4156 var o = C.new()
4157 o.TLock4()
4158 END
4159 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4160
4161 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4162 lines =<< trim END
4163 vim9script
4164 class C
4165 def TLock5()
4166 var this5: number
4167 lockvar this5
4168 enddef
4169 endclass
4170 var o = C.new()
4171 o.TLock5()
4172 END
4173 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4174enddef
4175
4176" Test some general lockvar cases
4177def Test_lockvar_general()
4178 # lockvar an object and a class. It does nothing
4179 var lines =<< trim END
4180 vim9script
4181 class C
4182 endclass
4183 var o = C.new()
4184 lockvar o
4185 lockvar C
4186 END
4187 v9.CheckSourceSuccess(lines)
4188
4189 # Lock a list element that's nested in an object variable from a :def
4190 lines =<< trim END
4191 vim9script
4192
4193 class C
4194 public this.val: list<list<number>> = [ [1], [2], [3] ]
4195 endclass
4196 def Lock2(obj: any)
4197 lockvar obj.val[1]
4198 enddef
4199
4200 var o = C.new()
4201 Lock2(o)
4202 o.val[0] = [9]
4203 assert_equal([ [9], [2], [3] ], o.val)
4204 try
4205 o.val[1] = [999]
4206 call assert_false(true, 'assign should have failed')
4207 catch
4208 assert_exception('E741:')
4209 endtry
4210 o.val[2] = [8]
4211 assert_equal([ [9], [2], [8] ], o.val)
4212 END
4213 v9.CheckSourceSuccess(lines)
4214
4215 # Lock a list element that's nested in an object variable from scriptlevel
4216 lines =<< trim END
4217 vim9script
4218
4219 class C
4220 public this.val: list<list<number>> = [ [1], [2], [3] ]
4221 endclass
4222
4223 var o = C.new()
4224 lockvar o.val[1]
4225 o.val[0] = [9]
4226 assert_equal([ [9], [2], [3] ], o.val)
4227 try
4228 o.val[1] = [999]
4229 call assert_false(true, 'assign should have failed')
4230 catch
4231 assert_exception('E741:')
4232 endtry
4233 o.val[2] = [8]
4234 assert_equal([ [9], [2], [8] ], o.val)
4235 END
4236 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004237
4238 # lock a script level variable from an object method
4239 lines =<< trim END
4240 vim9script
4241
4242 class C
4243 def Lock()
4244 lockvar l
4245 enddef
4246 endclass
4247
4248 var l = [1]
4249 C.new().Lock()
4250 l[0] = 11
4251 END
4252 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4253
Ernie Rael03042a22023-11-11 08:53:32 +01004254 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004255 # in an object fetched via a script level list
4256 lines =<< trim END
4257 vim9script
4258
4259 class C
4260 this._v1: list<list<number>>
4261 def Lock()
4262 lockvar lc[0]._v1[1]
4263 enddef
4264 endclass
4265
4266 var l = [[1], [2], [3]]
4267 var o = C.new(l)
4268 var lc: list<C> = [ o ]
4269
4270 o.Lock()
4271 l[0] = [22]
4272 l[1] = [33]
4273 END
4274 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4275
4276 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004277 # in a class that does not own the protected variable.
4278 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004279 # the same name.
4280 lines =<< trim END
4281 vim9script
4282
4283 class C2
4284 this._v1: list<list<number>>
4285 def Lock(obj: any)
4286 lockvar lc[0]._v1[1]
4287 enddef
4288 endclass
4289
4290 class C
4291 this._v1: list<list<number>>
4292 endclass
4293
4294 var l = [[1], [2], [3]]
4295 var o = C.new(l)
4296 var lc: list<C> = [ o ]
4297
4298 var o2 = C2.new()
4299 o2.Lock(o)
4300 END
Ernie Rael03042a22023-11-11 08:53:32 +01004301 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004302enddef
4303
Ernie Rael9771b2a2023-10-07 22:05:40 +02004304" Test builtin islocked()
4305def Test_lockvar_islocked()
4306 # Can't lock class/object variable
4307 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004308 # Lock item of variable's value (a list item)
4309 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004310 var lines =<< trim END
4311 vim9script
4312
4313 class C
4314 this.o0: list<list<number>> = [ [0], [1], [2]]
4315 this.o1: list<list<number>> = [[10], [11], [12]]
4316 static c0: list<list<number>> = [[20], [21], [22]]
4317 static c1: list<list<number>> = [[30], [31], [32]]
4318 endclass
4319
4320 def LockIt(arg: any)
4321 lockvar arg
4322 enddef
4323
4324 def UnlockIt(arg: any)
4325 unlockvar arg
4326 enddef
4327
4328 var obj = C.new()
4329 #lockvar obj.o1 # can't lock something you can't write to
4330
4331 try
4332 lockvar obj.o1 # can't lock something you can't write to
4333 call assert_false(1, '"lockvar obj.o1" should have failed')
4334 catch
4335 call assert_exception('E1335:')
4336 endtry
4337
4338 LockIt(obj.o1) # but can lock it's value
4339 assert_equal(1, islocked("obj.o1"))
4340 assert_equal(1, islocked("obj.o1[0]"))
4341 assert_equal(1, islocked("obj.o1[1]"))
4342 UnlockIt(obj.o1)
4343 assert_equal(0, islocked("obj.o1"))
4344 assert_equal(0, islocked("obj.o1[0]"))
4345
4346 lockvar obj.o1[0]
4347 assert_equal(0, islocked("obj.o1"))
4348 assert_equal(1, islocked("obj.o1[0]"))
4349 assert_equal(0, islocked("obj.o1[1]"))
4350 unlockvar obj.o1[0]
4351 assert_equal(0, islocked("obj.o1"))
4352 assert_equal(0, islocked("obj.o1[0]"))
4353
4354 # Same thing, but with a static
4355
4356 try
4357 lockvar C.c1 # can't lock something you can't write to
4358 call assert_false(1, '"lockvar C.c1" should have failed')
4359 catch
4360 call assert_exception('E1335:')
4361 endtry
4362
4363 LockIt(C.c1) # but can lock it's value
4364 assert_equal(1, islocked("C.c1"))
4365 assert_equal(1, islocked("C.c1[0]"))
4366 assert_equal(1, islocked("C.c1[1]"))
4367 UnlockIt(C.c1)
4368 assert_equal(0, islocked("C.c1"))
4369 assert_equal(0, islocked("C.c1[0]"))
4370
4371 lockvar C.c1[0]
4372 assert_equal(0, islocked("C.c1"))
4373 assert_equal(1, islocked("C.c1[0]"))
4374 assert_equal(0, islocked("C.c1[1]"))
4375 unlockvar C.c1[0]
4376 assert_equal(0, islocked("C.c1"))
4377 assert_equal(0, islocked("C.c1[0]"))
4378 END
4379 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004380
4381 # Do islocked() from an object method
4382 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004383 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004384 vim9script
4385
4386 var l0o0 = [ [0], [1], [2]]
4387 var l0o1 = [ [10], [11], [12]]
4388 var l0c0 = [[120], [121], [122]]
4389 var l0c1 = [[130], [131], [132]]
4390
4391 class C0
4392 this.o0: list<list<number>> = l0o0
4393 this.o1: list<list<number>> = l0o1
4394 static c0: list<list<number>> = l0c0
4395 static c1: list<list<number>> = l0c1
4396 def Islocked(arg: string): number
4397 return islocked(arg)
4398 enddef
4399 static def SIslocked(arg: string): number
4400 return islocked(arg)
4401 enddef
4402 endclass
4403
4404 var l2o0 = [[20000], [20001], [20002]]
4405 var l2o1 = [[20010], [20011], [20012]]
4406 var l2c0 = [[20120], [20121], [20122]]
4407 var l2c1 = [[20130], [20131], [20132]]
4408
4409 class C2
4410 this.o0: list<list<number>> = l2o0
4411 this.o1: list<list<number>> = l2o1
4412 static c0: list<list<number>> = l2c0
4413 static c1: list<list<number>> = l2c1
4414 def Islocked(arg: string): number
4415 return islocked(arg)
4416 enddef
4417 static def SIslocked(arg: string): number
4418 return islocked(arg)
4419 enddef
4420 endclass
4421
4422 var obj0 = C0.new()
4423 var obj2 = C2.new()
4424
4425 var l = [ obj0, null_object, obj2 ]
4426
4427 # lock list, object func access through script var expr
4428 assert_equal(0, obj0.Islocked("l[0].o0"))
4429 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4430 lockvar l0o0
4431 assert_equal(1, obj0.Islocked("l[0].o0"))
4432 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4433
4434 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4435
4436 # lock list element, object func access through script var expr
4437 lockvar l0o1[1]
4438 assert_equal(0, obj0.Islocked("this.o1[0]"))
4439 assert_equal(1, obj0.Islocked("this.o1[1]"))
4440
4441 assert_equal(0, obj0.Islocked("this.o1"))
4442 lockvar l0o1
4443 assert_equal(1, obj0.Islocked("this.o1"))
4444 unlockvar l0o1
4445
4446 lockvar l0c1[1]
4447
4448 # static by class name member expr from same class
4449 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4450 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4451 # static by bare name member expr from same class
4452 assert_equal(0, obj0.Islocked("c1[0]"))
4453 assert_equal(1, obj0.Islocked("c1[1]"))
4454
4455 # static by class name member expr from other class
4456 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4457 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4458 # static by bare name member expr from other class
4459 assert_equal(0, obj2.Islocked("c1[0]"))
4460 assert_equal(0, obj2.Islocked("c1[1]"))
4461
4462
4463 # static by bare name in same class
4464 assert_equal(0, obj0.Islocked("c0"))
4465 lockvar l0c0
4466 assert_equal(1, obj0.Islocked("c0"))
4467
4468 #
4469 # similar stuff, but use static method
4470 #
4471
4472 unlockvar l0o0
4473
4474 # lock list, object func access through script var expr
4475 assert_equal(0, C0.SIslocked("l[0].o0"))
4476 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4477 lockvar l0o0
4478 assert_equal(1, C0.SIslocked("l[0].o0"))
4479 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4480
4481 unlockvar l0o1
4482
4483 # can't access "this" from class method
4484 try
4485 C0.SIslocked("this.o1[0]")
4486 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4487 catch
4488 call assert_exception('E121: Undefined variable: this')
4489 endtry
4490
4491 lockvar l0c1[1]
4492
4493 # static by class name member expr from same class
4494 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4495 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4496 # static by bare name member expr from same class
4497 assert_equal(0, C0.SIslocked("c1[0]"))
4498 assert_equal(1, C0.SIslocked("c1[1]"))
4499
4500 # static by class name member expr from other class
4501 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4502 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4503 # static by bare name member expr from other class
4504 assert_equal(0, C2.SIslocked("c1[0]"))
4505 assert_equal(0, C2.SIslocked("c1[1]"))
4506
4507
4508 # static by bare name in same class
4509 unlockvar l0c0
4510 assert_equal(0, C0.SIslocked("c0"))
4511 lockvar l0c0
4512 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004513 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004514 v9.CheckSourceSuccess(lines)
4515
4516 # Check islocked class/object from various places.
4517 lines =<< trim END
4518 vim9script
4519
4520 class C
4521 def Islocked(arg: string): number
4522 return islocked(arg)
4523 enddef
4524 static def SIslocked(arg: string): number
4525 return islocked(arg)
4526 enddef
4527 endclass
4528 var obj = C.new()
4529
4530 # object method
4531 assert_equal(0, obj.Islocked("this"))
4532 assert_equal(0, obj.Islocked("C"))
4533
4534 # class method
4535 ### assert_equal(0, C.SIslocked("this"))
4536 assert_equal(0, C.SIslocked("C"))
4537
4538 #script level
4539 var v: number
4540 v = islocked("C")
4541 assert_equal(0, v)
4542 v = islocked("obj")
4543 assert_equal(0, v)
4544 END
4545 v9.CheckSourceSuccess(lines)
4546enddef
4547
4548def Test_lockvar_islocked_notfound()
4549 # Try non-existent things
4550 var lines =<< trim END
4551 vim9script
4552
4553 class C
4554 def Islocked(arg: string): number
4555 return islocked(arg)
4556 enddef
4557 static def SIslocked(arg: string): number
4558 return islocked(arg)
4559 enddef
4560 endclass
4561 var obj = C.new()
4562 assert_equal(-1, obj.Islocked("anywhere"))
4563 assert_equal(-1, C.SIslocked("notanywhere"))
4564 END
4565 v9.CheckSourceSuccess(lines)
4566
4567 # Something not found of the form "name1.name2" is an error
4568 lines =<< trim END
4569 vim9script
4570
4571 islocked("one.two")
4572 END
4573 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4574
4575 lines =<< trim END
4576 vim9script
4577
4578 class C
4579 this.val = { key: "value" }
4580 def Islocked(arg: string): number
4581 return islocked(arg)
4582 enddef
4583 endclass
4584 var obj = C.new()
4585 obj.Islocked("this.val.not_there"))
4586 END
4587 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4588
4589 lines =<< trim END
4590 vim9script
4591
4592 class C
4593 def Islocked(arg: string): number
4594 return islocked(arg)
4595 enddef
4596 endclass
4597 var obj = C.new()
4598 obj.Islocked("this.notobjmember")
4599 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004600 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004601
4602 # access a script variable through methods
4603 lines =<< trim END
4604 vim9script
4605
4606 var l = [1]
4607 class C
4608 def Islocked(arg: string): number
4609 return islocked(arg)
4610 enddef
4611 static def SIslocked(arg: string): number
4612 return islocked(arg)
4613 enddef
4614 endclass
4615 var obj = C.new()
4616 assert_equal(0, obj.Islocked("l"))
4617 assert_equal(0, C.SIslocked("l"))
4618 lockvar l
4619 assert_equal(1, obj.Islocked("l"))
4620 assert_equal(1, C.SIslocked("l"))
4621 END
4622 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004623enddef
4624
Ernie Rael03042a22023-11-11 08:53:32 +01004625" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004626def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004627 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004628 var lines =<< trim END
4629 vim9script
4630
4631 class A
4632 def _Foo(): number
4633 return 1234
4634 enddef
4635 endclass
4636 var a = A.new()
4637 a._Foo()
4638 END
Ernie Rael03042a22023-11-11 08:53:32 +01004639 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004640
Ernie Rael03042a22023-11-11 08:53:32 +01004641 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004642 lines =<< trim END
4643 vim9script
4644
4645 class A
4646 def _Foo(): number
4647 return 1234
4648 enddef
4649 endclass
4650 def T()
4651 var a = A.new()
4652 a._Foo()
4653 enddef
4654 T()
4655 END
Ernie Rael03042a22023-11-11 08:53:32 +01004656 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004657
Ernie Rael03042a22023-11-11 08:53:32 +01004658 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004659 lines =<< trim END
4660 vim9script
4661
4662 class A
4663 def _Foo(): number
4664 return 1234
4665 enddef
4666 def Bar(): number
4667 return this._Foo()
4668 enddef
4669 endclass
4670 var a = A.new()
4671 assert_equal(1234, a.Bar())
4672 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004673 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004674
Ernie Rael03042a22023-11-11 08:53:32 +01004675 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004676 lines =<< trim END
4677 vim9script
4678
4679 class A
4680 def _Foo(): number
4681 return 1234
4682 enddef
4683 def Bar(): number
4684 return this._Foo()
4685 enddef
4686 endclass
4687 def T()
4688 var a = A.new()
4689 assert_equal(1234, a.Bar())
4690 enddef
4691 T()
4692 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004693 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004694
Ernie Rael03042a22023-11-11 08:53:32 +01004695 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004696 lines =<< trim END
4697 vim9script
4698
4699 class A
4700 def _Foo(): number
4701 return 1234
4702 enddef
4703 def Bar(): number
4704 return _Foo()
4705 enddef
4706 endclass
4707 var a = A.new()
4708 a.Bar()
4709 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004710 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004711
Ernie Rael03042a22023-11-11 08:53:32 +01004712 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004713 lines =<< trim END
4714 vim9script
4715
4716 class A
4717 def _Foo(): number
4718 return 1234
4719 enddef
4720 endclass
4721 A._Foo()
4722 END
Ernie Rael03042a22023-11-11 08:53:32 +01004723 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004724
Ernie Rael03042a22023-11-11 08:53:32 +01004725 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004726 lines =<< trim END
4727 vim9script
4728
4729 class A
4730 def _Foo()
4731 enddef
4732 def _Foo()
4733 enddef
4734 endclass
4735 var a = A.new()
4736 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004737 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004738
Ernie Rael03042a22023-11-11 08:53:32 +01004739 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004740 lines =<< trim END
4741 vim9script
4742
4743 class A
4744 def _Foo()
4745 enddef
4746 def Foo()
4747 enddef
4748 endclass
4749 var a = A.new()
4750 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004751 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004752
Ernie Rael03042a22023-11-11 08:53:32 +01004753 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004754 lines =<< trim END
4755 vim9script
4756
4757 class A
4758 def Foo()
4759 enddef
4760 def _Foo()
4761 enddef
4762 endclass
4763 var a = A.new()
4764 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004765 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004766
Ernie Rael03042a22023-11-11 08:53:32 +01004767 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004768 lines =<< trim END
4769 vim9script
4770
4771 class A
4772 def Foo(): number
4773 return 100
4774 enddef
4775 def _Bar(): number
4776 return 200
4777 enddef
4778 def _Baz()
4779 assert_equal(100, this.Foo())
4780 assert_equal(200, this._Bar())
4781 enddef
4782 def T()
4783 this._Baz()
4784 enddef
4785 endclass
4786 var a = A.new()
4787 a.T()
4788 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004789 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004790
Ernie Rael03042a22023-11-11 08:53:32 +01004791 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004792 lines =<< trim END
4793 vim9script
4794
4795 class A
4796 def _Foo(): number
4797 return 100
4798 enddef
4799 endclass
4800 class B
4801 def Foo(): number
4802 var a = A.new()
4803 a._Foo()
4804 enddef
4805 endclass
4806 var b = B.new()
4807 b.Foo()
4808 END
Ernie Rael03042a22023-11-11 08:53:32 +01004809 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004810
Ernie Rael03042a22023-11-11 08:53:32 +01004811 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004812 lines =<< trim END
4813 vim9script
4814 class A
4815 def _Foo(): number
4816 return 1234
4817 enddef
4818 endclass
4819 class B extends A
4820 def Bar()
4821 enddef
4822 endclass
4823 class C extends B
4824 def Baz(): number
4825 return this._Foo()
4826 enddef
4827 endclass
4828 var c = C.new()
4829 assert_equal(1234, c.Baz())
4830 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004831 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004832
Ernie Rael03042a22023-11-11 08:53:32 +01004833 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004834 lines =<< trim END
4835 vim9script
4836 class A
4837 def _Foo(): number
4838 return 1234
4839 enddef
4840 endclass
4841 class B extends A
4842 def Bar()
4843 enddef
4844 endclass
4845 class C extends B
4846 def Baz(): number
4847 enddef
4848 endclass
4849 var c = C.new()
4850 assert_equal(1234, c._Foo())
4851 END
Ernie Rael03042a22023-11-11 08:53:32 +01004852 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004853
4854 # Using "_" prefix in a method name should fail outside of a class
4855 lines =<< trim END
4856 vim9script
4857 def _Foo(): number
4858 return 1234
4859 enddef
4860 var a = _Foo()
4861 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004862 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004863enddef
4864
Ernie Rael03042a22023-11-11 08:53:32 +01004865" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004866def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004867 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004868 var lines =<< trim END
4869 vim9script
4870
4871 class A
4872 static def _Foo(): number
4873 return 1234
4874 enddef
4875 endclass
4876 A._Foo()
4877 END
Ernie Rael03042a22023-11-11 08:53:32 +01004878 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004879
Ernie Rael03042a22023-11-11 08:53:32 +01004880 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004881 lines =<< trim END
4882 vim9script
4883
4884 class A
4885 static def _Foo(): number
4886 return 1234
4887 enddef
4888 endclass
4889 def T()
4890 A._Foo()
4891 enddef
4892 T()
4893 END
Ernie Rael03042a22023-11-11 08:53:32 +01004894 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004895
Ernie Rael03042a22023-11-11 08:53:32 +01004896 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004897 lines =<< trim END
4898 vim9script
4899
4900 class A
4901 static def _Foo(): number
4902 return 1234
4903 enddef
4904 endclass
4905 var a = A.new()
4906 a._Foo()
4907 END
Ernie Rael03042a22023-11-11 08:53:32 +01004908 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004909
Ernie Rael03042a22023-11-11 08:53:32 +01004910 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004911 lines =<< trim END
4912 vim9script
4913
4914 class A
4915 static def _Foo(): number
4916 return 1234
4917 enddef
4918 endclass
4919 def T()
4920 var a = A.new()
4921 a._Foo()
4922 enddef
4923 T()
4924 END
Ernie Rael03042a22023-11-11 08:53:32 +01004925 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004926
Ernie Rael03042a22023-11-11 08:53:32 +01004927 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004928 lines =<< trim END
4929 vim9script
4930
4931 class A
4932 static def _Foo(): number
4933 return 1234
4934 enddef
4935 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004936 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004937 enddef
4938 endclass
4939 var a = A.new()
4940 a.Bar()
4941 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004942 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004943
Ernie Rael03042a22023-11-11 08:53:32 +01004944 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004945 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004946 lines =<< trim END
4947 vim9script
4948
4949 class A
4950 static def _Foo1(): number
4951 return 1234
4952 enddef
4953 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004954 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004955 enddef
4956 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004957 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004958 enddef
4959 endclass
4960 var a = A.new()
4961 a.Bar()
4962 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004963 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004964
Ernie Rael03042a22023-11-11 08:53:32 +01004965 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004966 lines =<< trim END
4967 vim9script
4968
4969 class A
4970 static def _Foo()
4971 enddef
4972 static def Foo()
4973 enddef
4974 endclass
4975 var a = A.new()
4976 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004977 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004978
Ernie Rael03042a22023-11-11 08:53:32 +01004979 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004980 lines =<< trim END
4981 vim9script
4982
4983 class A
4984 static def _Foo(): number
4985 return 1234
4986 enddef
4987 endclass
4988 class B
4989 def Foo(): number
4990 return A._Foo()
4991 enddef
4992 endclass
4993 var b = B.new()
4994 assert_equal(1234, b.Foo())
4995 END
Ernie Rael03042a22023-11-11 08:53:32 +01004996 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004997
Ernie Rael03042a22023-11-11 08:53:32 +01004998 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004999 lines =<< trim END
5000 vim9script
5001 class A
5002 static def _Foo(): number
5003 return 1234
5004 enddef
5005 endclass
5006 class B extends A
5007 def Bar()
5008 enddef
5009 endclass
5010 class C extends B
5011 def Baz(): number
5012 return A._Foo()
5013 enddef
5014 endclass
5015 var c = C.new()
5016 assert_equal(1234, c.Baz())
5017 END
Ernie Rael03042a22023-11-11 08:53:32 +01005018 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005019
Ernie Rael03042a22023-11-11 08:53:32 +01005020 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005021 lines =<< trim END
5022 vim9script
5023 class A
5024 static def _Foo(): number
5025 return 1234
5026 enddef
5027 endclass
5028 class B extends A
5029 def Bar()
5030 enddef
5031 endclass
5032 class C extends B
5033 static def Baz(): number
5034 return A._Foo()
5035 enddef
5036 endclass
5037 assert_equal(1234, C.Baz())
5038 END
Ernie Rael03042a22023-11-11 08:53:32 +01005039 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005040
Ernie Rael03042a22023-11-11 08:53:32 +01005041 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005042 lines =<< trim END
5043 vim9script
5044 class A
5045 static def _Foo(): number
5046 return 1234
5047 enddef
5048 endclass
5049 class B extends A
5050 def Bar()
5051 enddef
5052 endclass
5053 class C extends B
5054 def Baz(): number
5055 enddef
5056 endclass
5057 var c = C.new()
5058 assert_equal(1234, C._Foo())
5059 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005060 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005061enddef
5062
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005063" Test for using the return value of a class/object method as a function
5064" argument.
5065def Test_objmethod_funcarg()
5066 var lines =<< trim END
5067 vim9script
5068
5069 class C
5070 def Foo(): string
5071 return 'foo'
5072 enddef
5073 endclass
5074
5075 def Bar(a: number, s: string): string
5076 return s
5077 enddef
5078
5079 def Baz(c: C)
5080 assert_equal('foo', Bar(10, c.Foo()))
5081 enddef
5082
5083 var t = C.new()
5084 Baz(t)
5085 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005086 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005087
5088 lines =<< trim END
5089 vim9script
5090
5091 class C
5092 static def Foo(): string
5093 return 'foo'
5094 enddef
5095 endclass
5096
5097 def Bar(a: number, s: string): string
5098 return s
5099 enddef
5100
5101 def Baz()
5102 assert_equal('foo', Bar(10, C.Foo()))
5103 enddef
5104
5105 Baz()
5106 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005107 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005108enddef
5109
Ernie Raelcf138d42023-09-06 20:45:03 +02005110def Test_static_inheritence()
5111 # subclasses get their own static copy
5112 var lines =<< trim END
5113 vim9script
5114
5115 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005116 static _svar: number
5117 this._mvar: number
5118 def new()
5119 _svar = 1
5120 this._mvar = 101
5121 enddef
5122 def AccessObject(): number
5123 return this._mvar
5124 enddef
5125 def AccessStaticThroughObject(): number
5126 return _svar
5127 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005128 endclass
5129
5130 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005131 def new()
5132 this._mvar = 102
5133 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005134 endclass
5135
5136 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005137 def new()
5138 this._mvar = 103
5139 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005141 def AccessPrivateStaticThroughClassName(): number
5142 assert_equal(1, A._svar)
5143 return 444
5144 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005145 endclass
5146
5147 var oa = A.new()
5148 var ob = B.new()
5149 var oc = C.new()
5150 assert_equal(101, oa.AccessObject())
5151 assert_equal(102, ob.AccessObject())
5152 assert_equal(103, oc.AccessObject())
5153
Ernie Rael03042a22023-11-11 08:53:32 +01005154 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005155
5156 # verify object properly resolves to correct static
5157 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005158 assert_equal(1, ob.AccessStaticThroughObject())
5159 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005160 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005161 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005162enddef
5163
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005164" Test for declaring duplicate object and class members
5165def Test_dup_member_variable()
5166 # Duplicate member variable
5167 var lines =<< trim END
5168 vim9script
5169 class C
5170 this.val = 10
5171 this.val = 20
5172 endclass
5173 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005174 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005175
Ernie Rael03042a22023-11-11 08:53:32 +01005176 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005177 lines =<< trim END
5178 vim9script
5179 class C
5180 this._val = 10
5181 this._val = 20
5182 endclass
5183 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005184 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005185
5186 # Duplicate public member variable
5187 lines =<< trim END
5188 vim9script
5189 class C
5190 public this.val = 10
5191 public this.val = 20
5192 endclass
5193 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005194 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005195
Ernie Rael03042a22023-11-11 08:53:32 +01005196 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005197 lines =<< trim END
5198 vim9script
5199 class C
5200 this.val = 10
5201 this._val = 20
5202 endclass
5203 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005204 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005205
Ernie Rael03042a22023-11-11 08:53:32 +01005206 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005207 lines =<< trim END
5208 vim9script
5209 class C
5210 this._val = 20
5211 public this.val = 10
5212 endclass
5213 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005214 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005215
5216 # Duplicate class member variable
5217 lines =<< trim END
5218 vim9script
5219 class C
5220 static s: string = "abc"
5221 static _s: string = "def"
5222 endclass
5223 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005224 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005225
Ernie Rael03042a22023-11-11 08:53:32 +01005226 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005227 lines =<< trim END
5228 vim9script
5229 class C
5230 public static s: string = "abc"
5231 static _s: string = "def"
5232 endclass
5233 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005234 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005235
5236 # Duplicate class and object member variable
5237 lines =<< trim END
5238 vim9script
5239 class C
5240 static val = 10
5241 this.val = 20
5242 def new()
5243 enddef
5244 endclass
5245 var c = C.new()
5246 assert_equal(10, C.val)
5247 assert_equal(20, c.val)
5248 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005249 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005250
5251 # Duplicate object member variable in a derived class
5252 lines =<< trim END
5253 vim9script
5254 class A
5255 this.val = 10
5256 endclass
5257 class B extends A
5258 endclass
5259 class C extends B
5260 this.val = 20
5261 endclass
5262 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005263 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005264
Ernie Rael03042a22023-11-11 08:53:32 +01005265 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005266 lines =<< trim END
5267 vim9script
5268 class A
5269 this._val = 10
5270 endclass
5271 class B extends A
5272 endclass
5273 class C extends B
5274 this._val = 20
5275 endclass
5276 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005277 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005278
Ernie Rael03042a22023-11-11 08:53:32 +01005279 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005280 lines =<< trim END
5281 vim9script
5282 class A
5283 this.val = 10
5284 endclass
5285 class B extends A
5286 endclass
5287 class C extends B
5288 this._val = 20
5289 endclass
5290 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005291 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005292
5293 # Duplicate object member variable in a derived class
5294 lines =<< trim END
5295 vim9script
5296 class A
5297 this._val = 10
5298 endclass
5299 class B extends A
5300 endclass
5301 class C extends B
5302 this.val = 20
5303 endclass
5304 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005305 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005306
5307 # Two member variables with a common prefix
5308 lines =<< trim END
5309 vim9script
5310 class A
5311 public static svar2: number
5312 public static svar: number
5313 endclass
5314 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005315 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005316enddef
5317
Ernie Rael03042a22023-11-11 08:53:32 +01005318" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005319def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005320 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005321 var lines =<< trim END
5322 vim9script
5323 class A
5324 this._val = 10
5325 def GetVal(): number
5326 return this._val
5327 enddef
5328 endclass
5329 def T()
5330 var a = A.new()
5331 a._val = 20
5332 enddef
5333 T()
5334 END
Ernie Rael03042a22023-11-11 08:53:32 +01005335 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005336
Ernie Rael03042a22023-11-11 08:53:32 +01005337 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005338 lines =<< trim END
5339 vim9script
5340 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005341 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005342 endclass
5343 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005344 var a = A.new()
5345 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005346 enddef
5347 T()
5348 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005349 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005350
Ernie Rael03042a22023-11-11 08:53:32 +01005351 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005352 lines =<< trim END
5353 vim9script
5354 class A
5355 static _val = 10
5356 endclass
5357 def T()
5358 var a = A.new()
5359 var x = a._val
5360 enddef
5361 T()
5362 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005363 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005364
Ernie Rael03042a22023-11-11 08:53:32 +01005365 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005366 lines =<< trim END
5367 vim9script
5368 class A
5369 static _val = 10
5370 endclass
5371 def T()
5372 var a = A.new()
5373 a._val = 3
5374 enddef
5375 T()
5376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005377 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005378
Ernie Rael03042a22023-11-11 08:53:32 +01005379 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005380 lines =<< trim END
5381 vim9script
5382 class A
5383 static _val = 10
5384 endclass
5385 def T()
5386 var x = A._val
5387 enddef
5388 T()
5389 END
Ernie Rael03042a22023-11-11 08:53:32 +01005390 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005391
Ernie Rael03042a22023-11-11 08:53:32 +01005392 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005393 lines =<< trim END
5394 vim9script
5395 class A
5396 static _val = 10
5397 endclass
5398 def T()
5399 A._val = 3
5400 enddef
5401 T()
5402 END
Ernie Rael03042a22023-11-11 08:53:32 +01005403 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005404enddef
5405
5406" Test for changing the member access of an interface in a implementation class
5407def Test_change_interface_member_access()
5408 var lines =<< trim END
5409 vim9script
5410 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005411 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005412 endinterface
5413 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005414 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005415 endclass
5416 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005417 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005418
5419 lines =<< trim END
5420 vim9script
5421 interface A
5422 this.val: number
5423 endinterface
5424 class B implements A
5425 public this.val = 10
5426 endclass
5427 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005428 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005429enddef
5430
5431" Test for trying to change a readonly member from a def function
5432def Test_readonly_member_change_in_def_func()
5433 var lines =<< trim END
5434 vim9script
5435 class A
5436 this.val: number
5437 endclass
5438 def T()
5439 var a = A.new()
5440 a.val = 20
5441 enddef
5442 T()
5443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005444 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005445enddef
5446
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005447" Test for reading and writing a class member from a def function
5448def Test_modify_class_member_from_def_function()
5449 var lines =<< trim END
5450 vim9script
5451 class A
5452 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005453 public static var2: list<number> = [1, 2]
5454 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005455 static _priv_var4: number = 40
5456 endclass
5457 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005458 assert_equal([1, 2], A.var2)
5459 assert_equal({a: 1, b: 2}, A.var3)
5460 A.var2 = [3, 4]
5461 A.var3 = {c: 3, d: 4}
5462 assert_equal([3, 4], A.var2)
5463 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005464 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005465 enddef
5466 T()
5467 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005468 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005469enddef
5470
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005471" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005472def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005473 var lines =<< trim END
5474 vim9script
5475 class A
5476 public static svar1: list<number> = [1]
5477 public static svar2: list<number> = [2]
5478 endclass
5479
5480 A.svar1->add(3)
5481 A.svar2->add(4)
5482 assert_equal([1, 3], A.svar1)
5483 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005484
5485 def Foo()
5486 A.svar1->add(7)
5487 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005488 assert_equal([1, 3, 7], A.svar1)
5489 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005490 enddef
5491 Foo()
5492 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005493 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005494
5495 # Cannot read from a class variable using an object in script context
5496 lines =<< trim END
5497 vim9script
5498 class A
5499 public this.var1: number
5500 public static svar2: list<number> = [1]
5501 endclass
5502
5503 var a = A.new()
5504 echo a.svar2
5505 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005506 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005507
5508 # Cannot write to a class variable using an object in script context
5509 lines =<< trim END
5510 vim9script
5511 class A
5512 public this.var1: number
5513 public static svar2: list<number> = [1]
5514 endclass
5515
5516 var a = A.new()
5517 a.svar2 = [2]
5518 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005519 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005520
5521 # Cannot read from a class variable using an object in def method context
5522 lines =<< trim END
5523 vim9script
5524 class A
5525 public this.var1: number
5526 public static svar2: list<number> = [1]
5527 endclass
5528
5529 def T()
5530 var a = A.new()
5531 echo a.svar2
5532 enddef
5533 T()
5534 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005535 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005536
5537 # Cannot write to a class variable using an object in def method context
5538 lines =<< trim END
5539 vim9script
5540 class A
5541 public this.var1: number
5542 public static svar2: list<number> = [1]
5543 endclass
5544
5545 def T()
5546 var a = A.new()
5547 a.svar2 = [2]
5548 enddef
5549 T()
5550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005551 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005552enddef
5553
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005554" Test for using a interface method using a child object
5555def Test_interface_method_from_child()
5556 var lines =<< trim END
5557 vim9script
5558
5559 interface A
5560 def Foo(): string
5561 endinterface
5562
5563 class B implements A
5564 def Foo(): string
5565 return 'foo'
5566 enddef
5567 endclass
5568
5569 class C extends B
5570 def Bar(): string
5571 return 'bar'
5572 enddef
5573 endclass
5574
5575 def T1(a: A)
5576 assert_equal('foo', a.Foo())
5577 enddef
5578
5579 def T2(b: B)
5580 assert_equal('foo', b.Foo())
5581 enddef
5582
5583 var c = C.new()
5584 T1(c)
5585 T2(c)
5586 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005587 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005588enddef
5589
5590" Test for using an interface method using a child object when it is overridden
5591" by the child class.
5592" FIXME: This test fails.
5593" def Test_interface_overridden_method_from_child()
5594" var lines =<< trim END
5595" vim9script
5596"
5597" interface A
5598" def Foo(): string
5599" endinterface
5600"
5601" class B implements A
5602" def Foo(): string
5603" return 'b-foo'
5604" enddef
5605" endclass
5606"
5607" class C extends B
5608" def Bar(): string
5609" return 'bar'
5610" enddef
5611" def Foo(): string
5612" return 'c-foo'
5613" enddef
5614" endclass
5615"
5616" def T1(a: A)
5617" assert_equal('c-foo', a.Foo())
5618" enddef
5619"
5620" def T2(b: B)
5621" assert_equal('c-foo', b.Foo())
5622" enddef
5623"
5624" var c = C.new()
5625" T1(c)
5626" T2(c)
5627" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005628" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005629" enddef
5630
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005631" Test for abstract methods
5632def Test_abstract_method()
5633 # Use two abstract methods
5634 var lines =<< trim END
5635 vim9script
5636 abstract class A
5637 def M1(): number
5638 return 10
5639 enddef
5640 abstract def M2(): number
5641 abstract def M3(): number
5642 endclass
5643 class B extends A
5644 def M2(): number
5645 return 20
5646 enddef
5647 def M3(): number
5648 return 30
5649 enddef
5650 endclass
5651 var b = B.new()
5652 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5653 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005654 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005655
5656 # Don't define an abstract method
5657 lines =<< trim END
5658 vim9script
5659 abstract class A
5660 abstract def Foo()
5661 endclass
5662 class B extends A
5663 endclass
5664 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005665 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005666
5667 # Use abstract method in a concrete class
5668 lines =<< trim END
5669 vim9script
5670 class A
5671 abstract def Foo()
5672 endclass
5673 class B extends A
5674 endclass
5675 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005676 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005677
5678 # Use abstract method in an interface
5679 lines =<< trim END
5680 vim9script
5681 interface A
5682 abstract def Foo()
5683 endinterface
5684 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005685 def Foo()
5686 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005687 endclass
5688 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005689 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5690
5691 # Use abstract static method in an interface
5692 lines =<< trim END
5693 vim9script
5694 interface A
5695 abstract static def Foo()
5696 enddef
5697 endinterface
5698 END
5699 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5700
5701 # Use abstract static variable in an interface
5702 lines =<< trim END
5703 vim9script
5704 interface A
5705 abstract static foo: number = 10
5706 endinterface
5707 END
5708 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005709
5710 # Abbreviate the "abstract" keyword
5711 lines =<< trim END
5712 vim9script
5713 class A
5714 abs def Foo()
5715 endclass
5716 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005717 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005718
5719 # Use "abstract" with a member variable
5720 lines =<< trim END
5721 vim9script
5722 abstract class A
5723 abstract this.val = 10
5724 endclass
5725 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005726 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005727
5728 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005729 lines =<< trim END
5730 vim9script
5731 abstract class A
5732 abstract static def Foo(): number
5733 endclass
5734 END
5735 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005736
5737 # Type mismatch between abstract method and concrete method
5738 lines =<< trim END
5739 vim9script
5740 abstract class A
5741 abstract def Foo(a: string, b: number): list<number>
5742 endclass
5743 class B extends A
5744 def Foo(a: number, b: string): list<string>
5745 return []
5746 enddef
5747 endclass
5748 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005749 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 +02005750
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005751 # Invoke an abstract method from a def function
5752 lines =<< trim END
5753 vim9script
5754 abstract class A
5755 abstract def Foo(): list<number>
5756 endclass
5757 class B extends A
5758 def Foo(): list<number>
5759 return [3, 5]
5760 enddef
5761 endclass
5762 def Bar(c: B)
5763 assert_equal([3, 5], c.Foo())
5764 enddef
5765 var b = B.new()
5766 Bar(b)
5767 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005768 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005769
5770 # Use a static method in an abstract class
5771 lines =<< trim END
5772 vim9script
5773 abstract class A
5774 static def Foo(): string
5775 return 'foo'
5776 enddef
5777 endclass
5778 assert_equal('foo', A.Foo())
5779 END
5780 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005781enddef
5782
5783" Test for calling a class method from a subclass
5784def Test_class_method_call_from_subclass()
5785 # class method call from a subclass
5786 var lines =<< trim END
5787 vim9script
5788
5789 class A
5790 static def Foo()
5791 echo "foo"
5792 enddef
5793 endclass
5794
5795 class B extends A
5796 def Bar()
5797 Foo()
5798 enddef
5799 endclass
5800
5801 var b = B.new()
5802 b.Bar()
5803 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005804 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005805enddef
5806
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005807" Test for calling a class method using an object in a def function context and
5808" script context.
5809def Test_class_method_call_using_object()
5810 # script context
5811 var lines =<< trim END
5812 vim9script
5813 class A
5814 static def Foo(): list<string>
5815 return ['a', 'b']
5816 enddef
5817 def Bar()
5818 assert_equal(['a', 'b'], A.Foo())
5819 assert_equal(['a', 'b'], Foo())
5820 enddef
5821 endclass
5822
5823 def T()
5824 assert_equal(['a', 'b'], A.Foo())
5825 var t_a = A.new()
5826 t_a.Bar()
5827 enddef
5828
5829 assert_equal(['a', 'b'], A.Foo())
5830 var a = A.new()
5831 a.Bar()
5832 T()
5833 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005834 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005835
5836 # script context
5837 lines =<< trim END
5838 vim9script
5839 class A
5840 static def Foo(): string
5841 return 'foo'
5842 enddef
5843 endclass
5844
5845 var a = A.new()
5846 assert_equal('foo', a.Foo())
5847 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005848 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005849
5850 # def function context
5851 lines =<< trim END
5852 vim9script
5853 class A
5854 static def Foo(): string
5855 return 'foo'
5856 enddef
5857 endclass
5858
5859 def T()
5860 var a = A.new()
5861 assert_equal('foo', a.Foo())
5862 enddef
5863 T()
5864 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005865 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005866enddef
5867
5868def Test_class_variable()
5869 var lines =<< trim END
5870 vim9script
5871
5872 class A
5873 public static val: number = 10
5874 static def ClassFunc()
5875 assert_equal(10, val)
5876 enddef
5877 def ObjFunc()
5878 assert_equal(10, val)
5879 enddef
5880 endclass
5881
5882 class B extends A
5883 endclass
5884
5885 assert_equal(10, A.val)
5886 A.ClassFunc()
5887 var a = A.new()
5888 a.ObjFunc()
5889 var b = B.new()
5890 b.ObjFunc()
5891
5892 def T1(a1: A)
5893 a1.ObjFunc()
5894 A.ClassFunc()
5895 enddef
5896 T1(b)
5897
5898 A.val = 20
5899 assert_equal(20, A.val)
5900 END
5901 v9.CheckSourceSuccess(lines)
5902
5903 # Modifying a parent class variable from a child class method
5904 lines =<< trim END
5905 vim9script
5906
5907 class A
5908 static val: number = 10
5909 endclass
5910
5911 class B extends A
5912 static def ClassFunc()
5913 val = 20
5914 enddef
5915 endclass
5916 B.ClassFunc()
5917 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005918 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005919
5920 # Reading a parent class variable from a child class method
5921 lines =<< trim END
5922 vim9script
5923
5924 class A
5925 static val: number = 10
5926 endclass
5927
5928 class B extends A
5929 static def ClassFunc()
5930 var i = val
5931 enddef
5932 endclass
5933 B.ClassFunc()
5934 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005935 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005936
5937 # Modifying a parent class variable from a child object method
5938 lines =<< trim END
5939 vim9script
5940
5941 class A
5942 static val: number = 10
5943 endclass
5944
5945 class B extends A
5946 def ObjFunc()
5947 val = 20
5948 enddef
5949 endclass
5950 var b = B.new()
5951 b.ObjFunc()
5952 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005953 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005954
5955 # Reading a parent class variable from a child object method
5956 lines =<< trim END
5957 vim9script
5958
5959 class A
5960 static val: number = 10
5961 endclass
5962
5963 class B extends A
5964 def ObjFunc()
5965 var i = val
5966 enddef
5967 endclass
5968 var b = B.new()
5969 b.ObjFunc()
5970 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005971 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005972
5973 # Modifying a class variable using an object at script level
5974 lines =<< trim END
5975 vim9script
5976
5977 class A
5978 static val: number = 10
5979 endclass
5980 var a = A.new()
5981 a.val = 20
5982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005983 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005984
5985 # Reading a class variable using an object at script level
5986 lines =<< trim END
5987 vim9script
5988
5989 class A
5990 static val: number = 10
5991 endclass
5992 var a = A.new()
5993 var i = a.val
5994 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005995 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005996
5997 # Modifying a class variable using an object at function level
5998 lines =<< trim END
5999 vim9script
6000
6001 class A
6002 static val: number = 10
6003 endclass
6004
6005 def T()
6006 var a = A.new()
6007 a.val = 20
6008 enddef
6009 T()
6010 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006011 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006012
6013 # Reading a class variable using an object at function level
6014 lines =<< trim END
6015 vim9script
6016
6017 class A
6018 static val: number = 10
6019 endclass
6020 def T()
6021 var a = A.new()
6022 var i = a.val
6023 enddef
6024 T()
6025 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006026 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006027enddef
6028
6029" Test for using a duplicate class method and class variable in a child class
6030def Test_dup_class_member()
6031 # duplicate class variable, class method and overridden object method
6032 var lines =<< trim END
6033 vim9script
6034 class A
6035 static sval = 100
6036 static def Check()
6037 assert_equal(100, sval)
6038 enddef
6039 def GetVal(): number
6040 return sval
6041 enddef
6042 endclass
6043
6044 class B extends A
6045 static sval = 200
6046 static def Check()
6047 assert_equal(200, sval)
6048 enddef
6049 def GetVal(): number
6050 return sval
6051 enddef
6052 endclass
6053
6054 def T1(aa: A): number
6055 return aa.GetVal()
6056 enddef
6057
6058 def T2(bb: B): number
6059 return bb.GetVal()
6060 enddef
6061
6062 assert_equal(100, A.sval)
6063 assert_equal(200, B.sval)
6064 var a = A.new()
6065 assert_equal(100, a.GetVal())
6066 var b = B.new()
6067 assert_equal(200, b.GetVal())
6068 assert_equal(200, T1(b))
6069 assert_equal(200, T2(b))
6070 END
6071 v9.CheckSourceSuccess(lines)
6072
6073 # duplicate class variable and class method
6074 lines =<< trim END
6075 vim9script
6076 class A
6077 static sval = 100
6078 static def Check()
6079 assert_equal(100, sval)
6080 enddef
6081 def GetVal(): number
6082 return sval
6083 enddef
6084 endclass
6085
6086 class B extends A
6087 static sval = 200
6088 static def Check()
6089 assert_equal(200, sval)
6090 enddef
6091 endclass
6092
6093 def T1(aa: A): number
6094 return aa.GetVal()
6095 enddef
6096
6097 def T2(bb: B): number
6098 return bb.GetVal()
6099 enddef
6100
6101 assert_equal(100, A.sval)
6102 assert_equal(200, B.sval)
6103 var a = A.new()
6104 assert_equal(100, a.GetVal())
6105 var b = B.new()
6106 assert_equal(100, b.GetVal())
6107 assert_equal(100, T1(b))
6108 assert_equal(100, T2(b))
6109 END
6110 v9.CheckSourceSuccess(lines)
6111enddef
6112
6113" Test for calling an instance method using the class
6114def Test_instance_method_call_using_class()
6115 # Invoke an object method using a class in script context
6116 var lines =<< trim END
6117 vim9script
6118 class A
6119 def Foo()
6120 echo "foo"
6121 enddef
6122 endclass
6123 A.Foo()
6124 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006125 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006126
6127 # Invoke an object method using a class in def function context
6128 lines =<< trim END
6129 vim9script
6130 class A
6131 def Foo()
6132 echo "foo"
6133 enddef
6134 endclass
6135 def T()
6136 A.Foo()
6137 enddef
6138 T()
6139 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006140 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006141enddef
6142
6143" Test for duplicate class method and instance method
6144def Test_dup_classmethod_objmethod()
6145 # Duplicate instance method
6146 var lines =<< trim END
6147 vim9script
6148 class A
6149 static def Foo()
6150 enddef
6151 def Foo()
6152 enddef
6153 endclass
6154 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006155 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006156
Ernie Rael03042a22023-11-11 08:53:32 +01006157 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006158 lines =<< trim END
6159 vim9script
6160 class A
6161 static def Foo()
6162 enddef
6163 def _Foo()
6164 enddef
6165 endclass
6166 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006167 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006168
6169 # Duplicate class method
6170 lines =<< trim END
6171 vim9script
6172 class A
6173 def Foo()
6174 enddef
6175 static def Foo()
6176 enddef
6177 endclass
6178 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006179 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006180
Ernie Rael03042a22023-11-11 08:53:32 +01006181 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006182 lines =<< trim END
6183 vim9script
6184 class A
6185 def Foo()
6186 enddef
6187 static def _Foo()
6188 enddef
6189 endclass
6190 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006191 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006192
Ernie Rael03042a22023-11-11 08:53:32 +01006193 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006194 lines =<< trim END
6195 vim9script
6196 class A
6197 def _Foo()
6198 enddef
6199 static def _Foo()
6200 enddef
6201 endclass
6202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006203 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006204enddef
6205
6206" Test for an instance method access level comparison with parent instance
6207" methods.
6208def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006209 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006210 var lines =<< trim END
6211 vim9script
6212 class A
6213 def Foo()
6214 enddef
6215 endclass
6216 class B extends A
6217 endclass
6218 class C extends B
6219 def _Foo()
6220 enddef
6221 endclass
6222 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006223 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006224
6225 # Public method in subclass
6226 lines =<< trim END
6227 vim9script
6228 class A
6229 def _Foo()
6230 enddef
6231 endclass
6232 class B extends A
6233 endclass
6234 class C extends B
6235 def Foo()
6236 enddef
6237 endclass
6238 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006239 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006240enddef
6241
6242def Test_extend_empty_class()
6243 var lines =<< trim END
6244 vim9script
6245 class A
6246 endclass
6247 class B extends A
6248 endclass
6249 class C extends B
6250 public static rw_class_var = 1
6251 public this.rw_obj_var = 2
6252 static def ClassMethod(): number
6253 return 3
6254 enddef
6255 def ObjMethod(): number
6256 return 4
6257 enddef
6258 endclass
6259 assert_equal(1, C.rw_class_var)
6260 assert_equal(3, C.ClassMethod())
6261 var c = C.new()
6262 assert_equal(2, c.rw_obj_var)
6263 assert_equal(4, c.ObjMethod())
6264 END
6265 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006266enddef
6267
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006268" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006269" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006270def Test_interface_with_unsupported_members()
6271 var lines =<< trim END
6272 vim9script
6273 interface A
6274 static num: number
6275 endinterface
6276 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006277 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006278
6279 lines =<< trim END
6280 vim9script
6281 interface A
6282 static _num: number
6283 endinterface
6284 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006285 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006286
6287 lines =<< trim END
6288 vim9script
6289 interface A
6290 public static num: number
6291 endinterface
6292 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006293 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006294
6295 lines =<< trim END
6296 vim9script
6297 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006298 public static num: number
6299 endinterface
6300 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006301 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006302
6303 lines =<< trim END
6304 vim9script
6305 interface A
6306 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006307 endinterface
6308 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006309 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006310
6311 lines =<< trim END
6312 vim9script
6313 interface A
6314 static def Foo(d: dict<any>): list<string>
6315 endinterface
6316 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006317 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006318
6319 lines =<< trim END
6320 vim9script
6321 interface A
6322 static def _Foo(d: dict<any>): list<string>
6323 endinterface
6324 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006325 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006326
6327 lines =<< trim END
6328 vim9script
6329 interface A
6330 this._Foo: list<string>
6331 endinterface
6332 END
Ernie Rael03042a22023-11-11 08:53:32 +01006333 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006334
6335 lines =<< trim END
6336 vim9script
6337 interface A
6338 def _Foo(d: dict<any>): list<string>
6339 endinterface
6340 END
Ernie Rael03042a22023-11-11 08:53:32 +01006341 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006342enddef
6343
6344" Test for extending an interface
6345def Test_extend_interface()
6346 var lines =<< trim END
6347 vim9script
6348 interface A
6349 this.var1: list<string>
6350 def Foo()
6351 endinterface
6352 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006353 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006354 def Bar()
6355 endinterface
6356 class C implements A, B
6357 this.var1 = [1, 2]
6358 def Foo()
6359 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006360 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006361 def Bar()
6362 enddef
6363 endclass
6364 END
6365 v9.CheckSourceSuccess(lines)
6366
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006367 # extending empty interface
6368 lines =<< trim END
6369 vim9script
6370 interface A
6371 endinterface
6372 interface B extends A
6373 endinterface
6374 class C implements B
6375 endclass
6376 END
6377 v9.CheckSourceSuccess(lines)
6378
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006379 lines =<< trim END
6380 vim9script
6381 interface A
6382 def Foo()
6383 endinterface
6384 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006385 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006386 endinterface
6387 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006388 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006389 endclass
6390 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006391 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006392
6393 lines =<< trim END
6394 vim9script
6395 interface A
6396 def Foo()
6397 endinterface
6398 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006399 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006400 endinterface
6401 class C implements A, B
6402 def Foo()
6403 enddef
6404 endclass
6405 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006406 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006407
6408 # interface cannot extend a class
6409 lines =<< trim END
6410 vim9script
6411 class A
6412 endclass
6413 interface B extends A
6414 endinterface
6415 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006416 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006417
6418 # class cannot extend an interface
6419 lines =<< trim END
6420 vim9script
6421 interface A
6422 endinterface
6423 class B extends A
6424 endclass
6425 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006426 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006427
6428 # interface cannot implement another interface
6429 lines =<< trim END
6430 vim9script
6431 interface A
6432 endinterface
6433 interface B implements A
6434 endinterface
6435 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006436 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006437
6438 # interface cannot extend multiple interfaces
6439 lines =<< trim END
6440 vim9script
6441 interface A
6442 endinterface
6443 interface B
6444 endinterface
6445 interface C extends A, B
6446 endinterface
6447 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006448 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006449
6450 # Variable type in an extended interface is of different type
6451 lines =<< trim END
6452 vim9script
6453 interface A
6454 this.val1: number
6455 endinterface
6456 interface B extends A
6457 this.val2: string
6458 endinterface
6459 interface C extends B
6460 this.val1: string
6461 this.val2: number
6462 endinterface
6463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006464 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006465enddef
6466
6467" Test for a child class implementing an interface when some of the methods are
6468" defined in the parent class.
6469def Test_child_class_implements_interface()
6470 var lines =<< trim END
6471 vim9script
6472
6473 interface Intf
6474 def F1(): list<list<number>>
6475 def F2(): list<list<number>>
6476 def F3(): list<list<number>>
6477 this.var1: list<dict<number>>
6478 this.var2: list<dict<number>>
6479 this.var3: list<dict<number>>
6480 endinterface
6481
6482 class A
6483 def A1()
6484 enddef
6485 def F3(): list<list<number>>
6486 return [[3]]
6487 enddef
6488 this.v1: list<list<number>> = [[0]]
6489 this.var3 = [{c: 30}]
6490 endclass
6491
6492 class B extends A
6493 def B1()
6494 enddef
6495 def F2(): list<list<number>>
6496 return [[2]]
6497 enddef
6498 this.v2: list<list<number>> = [[0]]
6499 this.var2 = [{b: 20}]
6500 endclass
6501
6502 class C extends B implements Intf
6503 def C1()
6504 enddef
6505 def F1(): list<list<number>>
6506 return [[1]]
6507 enddef
6508 this.v3: list<list<number>> = [[0]]
6509 this.var1 = [{a: 10}]
6510 endclass
6511
6512 def T(if: Intf)
6513 assert_equal([[1]], if.F1())
6514 assert_equal([[2]], if.F2())
6515 assert_equal([[3]], if.F3())
6516 assert_equal([{a: 10}], if.var1)
6517 assert_equal([{b: 20}], if.var2)
6518 assert_equal([{c: 30}], if.var3)
6519 enddef
6520
6521 var c = C.new()
6522 T(c)
6523 assert_equal([[1]], c.F1())
6524 assert_equal([[2]], c.F2())
6525 assert_equal([[3]], c.F3())
6526 assert_equal([{a: 10}], c.var1)
6527 assert_equal([{b: 20}], c.var2)
6528 assert_equal([{c: 30}], c.var3)
6529 END
6530 v9.CheckSourceSuccess(lines)
6531
6532 # One of the interface methods is not found
6533 lines =<< trim END
6534 vim9script
6535
6536 interface Intf
6537 def F1()
6538 def F2()
6539 def F3()
6540 endinterface
6541
6542 class A
6543 def A1()
6544 enddef
6545 endclass
6546
6547 class B extends A
6548 def B1()
6549 enddef
6550 def F2()
6551 enddef
6552 endclass
6553
6554 class C extends B implements Intf
6555 def C1()
6556 enddef
6557 def F1()
6558 enddef
6559 endclass
6560 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006561 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006562
6563 # One of the interface methods is of different type
6564 lines =<< trim END
6565 vim9script
6566
6567 interface Intf
6568 def F1()
6569 def F2()
6570 def F3()
6571 endinterface
6572
6573 class A
6574 def F3(): number
6575 return 0
6576 enddef
6577 def A1()
6578 enddef
6579 endclass
6580
6581 class B extends A
6582 def B1()
6583 enddef
6584 def F2()
6585 enddef
6586 endclass
6587
6588 class C extends B implements Intf
6589 def C1()
6590 enddef
6591 def F1()
6592 enddef
6593 endclass
6594 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006595 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006596
6597 # One of the interface variables is not present
6598 lines =<< trim END
6599 vim9script
6600
6601 interface Intf
6602 this.var1: list<dict<number>>
6603 this.var2: list<dict<number>>
6604 this.var3: list<dict<number>>
6605 endinterface
6606
6607 class A
6608 this.v1: list<list<number>> = [[0]]
6609 endclass
6610
6611 class B extends A
6612 this.v2: list<list<number>> = [[0]]
6613 this.var2 = [{b: 20}]
6614 endclass
6615
6616 class C extends B implements Intf
6617 this.v3: list<list<number>> = [[0]]
6618 this.var1 = [{a: 10}]
6619 endclass
6620 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006621 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006622
6623 # One of the interface variables is of different type
6624 lines =<< trim END
6625 vim9script
6626
6627 interface Intf
6628 this.var1: list<dict<number>>
6629 this.var2: list<dict<number>>
6630 this.var3: list<dict<number>>
6631 endinterface
6632
6633 class A
6634 this.v1: list<list<number>> = [[0]]
6635 this.var3: list<dict<string>>
6636 endclass
6637
6638 class B extends A
6639 this.v2: list<list<number>> = [[0]]
6640 this.var2 = [{b: 20}]
6641 endclass
6642
6643 class C extends B implements Intf
6644 this.v3: list<list<number>> = [[0]]
6645 this.var1 = [{a: 10}]
6646 endclass
6647 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006648 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 +02006649enddef
6650
6651" Test for extending an interface with duplicate variables and methods
6652def Test_interface_extends_with_dup_members()
6653 var lines =<< trim END
6654 vim9script
6655 interface A
6656 this.n1: number
6657 def Foo1(): number
6658 endinterface
6659 interface B extends A
6660 this.n2: number
6661 this.n1: number
6662 def Foo2(): number
6663 def Foo1(): number
6664 endinterface
6665 class C implements B
6666 this.n1 = 10
6667 this.n2 = 20
6668 def Foo1(): number
6669 return 30
6670 enddef
6671 def Foo2(): number
6672 return 40
6673 enddef
6674 endclass
6675 def T1(a: A)
6676 assert_equal(10, a.n1)
6677 assert_equal(30, a.Foo1())
6678 enddef
6679 def T2(b: B)
6680 assert_equal(10, b.n1)
6681 assert_equal(20, b.n2)
6682 assert_equal(30, b.Foo1())
6683 assert_equal(40, b.Foo2())
6684 enddef
6685 var c = C.new()
6686 T1(c)
6687 T2(c)
6688 END
6689 v9.CheckSourceSuccess(lines)
6690enddef
6691
6692" Test for using "any" type for a variable in a sub-class while it has a
6693" concrete type in the interface
6694def Test_implements_using_var_type_any()
6695 var lines =<< trim END
6696 vim9script
6697 interface A
6698 this.val: list<dict<string>>
6699 endinterface
6700 class B implements A
6701 this.val = [{a: '1'}, {b: '2'}]
6702 endclass
6703 var b = B.new()
6704 assert_equal([{a: '1'}, {b: '2'}], b.val)
6705 END
6706 v9.CheckSourceSuccess(lines)
6707
6708 # initialize instance variable using a different type
6709 lines =<< trim END
6710 vim9script
6711 interface A
6712 this.val: list<dict<string>>
6713 endinterface
6714 class B implements A
6715 this.val = {a: 1, b: 2}
6716 endclass
6717 var b = B.new()
6718 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006719 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006720enddef
6721
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006722" Test for assigning to a member variable in a nested class
6723def Test_nested_object_assignment()
6724 var lines =<< trim END
6725 vim9script
6726
6727 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006728 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006729 endclass
6730
6731 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006732 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006733 endclass
6734
6735 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006736 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006737 endclass
6738
6739 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006740 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006741 endclass
6742
6743 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006744 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006745 enddef
6746
6747 var d = D.new()
6748 T(d)
6749 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006750 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006751enddef
6752
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006753" Test for calling methods using a null object
6754def Test_null_object_method_call()
6755 # Calling a object method using a null object in script context
6756 var lines =<< trim END
6757 vim9script
6758
6759 class C
6760 def Foo()
6761 assert_report('This method should not be executed')
6762 enddef
6763 endclass
6764
6765 var o: C
6766 o.Foo()
6767 END
6768 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6769
6770 # Calling a object method using a null object in def function context
6771 lines =<< trim END
6772 vim9script
6773
6774 class C
6775 def Foo()
6776 assert_report('This method should not be executed')
6777 enddef
6778 endclass
6779
6780 def T()
6781 var o: C
6782 o.Foo()
6783 enddef
6784 T()
6785 END
6786 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6787
6788 # Calling a object method through another class method using a null object in
6789 # script context
6790 lines =<< trim END
6791 vim9script
6792
6793 class C
6794 def Foo()
6795 assert_report('This method should not be executed')
6796 enddef
6797
6798 static def Bar(o_any: any)
6799 var o_typed: C = o_any
6800 o_typed.Foo()
6801 enddef
6802 endclass
6803
6804 var o: C
6805 C.Bar(o)
6806 END
6807 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6808
6809 # Calling a object method through another class method using a null object in
6810 # def function context
6811 lines =<< trim END
6812 vim9script
6813
6814 class C
6815 def Foo()
6816 assert_report('This method should not be executed')
6817 enddef
6818
6819 static def Bar(o_any: any)
6820 var o_typed: C = o_any
6821 o_typed.Foo()
6822 enddef
6823 endclass
6824
6825 def T()
6826 var o: C
6827 C.Bar(o)
6828 enddef
6829 T()
6830 END
6831 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6832enddef
6833
6834" Test for using a dict as an object member
6835def Test_dict_object_member()
6836 var lines =<< trim END
6837 vim9script
6838
6839 class Context
6840 public this.state: dict<number> = {}
6841 def GetState(): dict<number>
6842 return this.state
6843 enddef
6844 endclass
6845
6846 var ctx = Context.new()
6847 ctx.state->extend({a: 1})
6848 ctx.state['b'] = 2
6849 assert_equal({a: 1, b: 2}, ctx.GetState())
6850
6851 def F()
6852 ctx.state['c'] = 3
6853 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6854 enddef
6855 F()
6856 assert_equal(3, ctx.state.c)
6857 ctx.state.c = 4
6858 assert_equal(4, ctx.state.c)
6859 END
6860 v9.CheckSourceSuccess(lines)
6861enddef
6862
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006863" The following test was failing after 9.0.1914. This was caused by using a
6864" freed object from a previous method call.
6865def Test_freed_object_from_previous_method_call()
6866 var lines =<< trim END
6867 vim9script
6868
6869 class Context
6870 endclass
6871
6872 class Result
6873 endclass
6874
6875 def Failure(): Result
6876 return Result.new()
6877 enddef
6878
6879 def GetResult(ctx: Context): Result
6880 return Failure()
6881 enddef
6882
6883 def Test_GetResult()
6884 var ctx = Context.new()
6885 var result = GetResult(ctx)
6886 enddef
6887
6888 Test_GetResult()
6889 END
6890 v9.CheckSourceSuccess(lines)
6891enddef
6892
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006893" Test for duplicate object and class variable
6894def Test_duplicate_variable()
6895 # Object variable name is same as the class variable name
6896 var lines =<< trim END
6897 vim9script
6898 class A
6899 public static sval: number
6900 public this.sval: number
6901 endclass
6902 var a = A.new()
6903 END
6904 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6905
6906 # Duplicate variable name and calling a class method
6907 lines =<< trim END
6908 vim9script
6909 class A
6910 public static sval: number
6911 public this.sval: number
6912 def F1()
6913 echo this.sval
6914 enddef
6915 static def F2()
6916 echo sval
6917 enddef
6918 endclass
6919 A.F2()
6920 END
6921 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6922
6923 # Duplicate variable with an empty constructor
6924 lines =<< trim END
6925 vim9script
6926 class A
6927 public static sval: number
6928 public this.sval: number
6929 def new()
6930 enddef
6931 endclass
6932 var a = A.new()
6933 END
6934 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6935enddef
6936
6937" Test for using a reserved keyword as a variable name
6938def Test_reserved_varname()
6939 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6940 'null_function', 'null_list', 'null_partial', 'null_string',
6941 'null_channel', 'null_job', 'super', 'this']
6942
6943 var lines =<< trim eval END
6944 vim9script
6945 class C
6946 public this.{kword}: list<number> = [1, 2, 3]
6947 endclass
6948 var o = C.new()
6949 END
6950 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6951
6952 lines =<< trim eval END
6953 vim9script
6954 class C
6955 public this.{kword}: list<number> = [1, 2, 3]
6956 def new()
6957 enddef
6958 endclass
6959 var o = C.new()
6960 END
6961 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6962
6963 lines =<< trim eval END
6964 vim9script
6965 class C
6966 public this.{kword}: list<number> = [1, 2, 3]
6967 def new()
6968 enddef
6969 def F()
6970 echo this.{kword}
6971 enddef
6972 endclass
6973 var o = C.new()
6974 o.F()
6975 END
6976 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006977
6978 # class variable name
6979 if kword != 'this'
6980 lines =<< trim eval END
6981 vim9script
6982 class C
6983 public static {kword}: list<number> = [1, 2, 3]
6984 endclass
6985 END
6986 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6987 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006988 endfor
6989enddef
6990
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006991" Test for checking the type of the arguments and the return value of a object
6992" method in an extended class.
6993def Test_extended_obj_method_type_check()
6994 var lines =<< trim END
6995 vim9script
6996
6997 class A
6998 endclass
6999 class B extends A
7000 endclass
7001 class C extends B
7002 endclass
7003
7004 class Foo
7005 def Doit(p: B): B
7006 return B.new()
7007 enddef
7008 endclass
7009
7010 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007011 def Doit(p: C): B
7012 return B.new()
7013 enddef
7014 endclass
7015 END
7016 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7017
7018 lines =<< trim END
7019 vim9script
7020
7021 class A
7022 endclass
7023 class B extends A
7024 endclass
7025 class C extends B
7026 endclass
7027
7028 class Foo
7029 def Doit(p: B): B
7030 return B.new()
7031 enddef
7032 endclass
7033
7034 class Bar extends Foo
7035 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007036 return C.new()
7037 enddef
7038 endclass
7039 END
7040 v9.CheckSourceSuccess(lines)
7041
7042 lines =<< trim END
7043 vim9script
7044
7045 class A
7046 endclass
7047 class B extends A
7048 endclass
7049 class C extends B
7050 endclass
7051
7052 class Foo
7053 def Doit(p: B): B
7054 return B.new()
7055 enddef
7056 endclass
7057
7058 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007059 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007060 return B.new()
7061 enddef
7062 endclass
7063 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007064 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 +02007065
7066 lines =<< trim END
7067 vim9script
7068
7069 class A
7070 endclass
7071 class B extends A
7072 endclass
7073 class C extends B
7074 endclass
7075
7076 class Foo
7077 def Doit(p: B): B
7078 return B.new()
7079 enddef
7080 endclass
7081
7082 class Bar extends Foo
7083 def Doit(p: B): A
7084 return A.new()
7085 enddef
7086 endclass
7087 END
7088 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 +02007089
7090 # check varargs type mismatch
7091 lines =<< trim END
7092 vim9script
7093
7094 class B
7095 def F(...xxx: list<any>)
7096 enddef
7097 endclass
7098 class C extends B
7099 def F(xxx: list<any>)
7100 enddef
7101 endclass
7102 END
7103 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 +02007104enddef
7105
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007106" Test type checking for class variable in assignments
7107func Test_class_variable_complex_type_check()
7108 " class variable with a specific type. Try assigning a different type at
7109 " script 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
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007116 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007117 endclass
7118 test_garbagecollect_now()
7119 A.Fn = "abc"
7120 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007121 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 +02007122
7123 " class variable with a specific type. Try assigning a different type at
7124 " class def method level.
7125 let lines =<< trim END
7126 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007127 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007128 return {}
7129 enddef
7130 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007131 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007132 def Bar()
7133 Fn = "abc"
7134 enddef
7135 endclass
7136 var a = A.new()
7137 test_garbagecollect_now()
7138 a.Bar()
7139 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007140 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 +02007141
7142 " class variable with a specific type. Try assigning a different type at
7143 " script def method level.
7144 let lines =<< trim END
7145 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007146 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007147 return {}
7148 enddef
7149 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007150 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007151 endclass
7152 def Bar()
7153 A.Fn = "abc"
7154 enddef
7155 test_garbagecollect_now()
7156 Bar()
7157 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007158 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 +02007159
7160 " class variable without any type. Should be set to the initialization
7161 " expression type. Try assigning a different type from script level.
7162 let lines =<< trim END
7163 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007164 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007165 return {}
7166 enddef
7167 class A
7168 public static Fn = Foo
7169 endclass
7170 test_garbagecollect_now()
7171 A.Fn = "abc"
7172 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007173 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 +02007174
7175 " class variable without any type. Should be set to the initialization
7176 " expression type. Try assigning a different type at class def level.
7177 let lines =<< trim END
7178 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007179 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007180 return {}
7181 enddef
7182 class A
7183 public static Fn = Foo
7184 def Bar()
7185 Fn = "abc"
7186 enddef
7187 endclass
7188 var a = A.new()
7189 test_garbagecollect_now()
7190 a.Bar()
7191 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007192 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 +02007193
7194 " class variable without any type. Should be set to the initialization
7195 " expression type. Try assigning a different type at script def level.
7196 let lines =<< trim END
7197 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007198 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007199 return {}
7200 enddef
7201 class A
7202 public static Fn = Foo
7203 endclass
7204 def Bar()
7205 A.Fn = "abc"
7206 enddef
7207 test_garbagecollect_now()
7208 Bar()
7209 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007210 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 +02007211
7212 " class variable with 'any" type. Can be assigned different types.
7213 let lines =<< trim END
7214 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007215 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007216 return {}
7217 enddef
7218 class A
7219 public static Fn: any = Foo
7220 public static Fn2: any
7221 endclass
7222 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007223 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007224 A.Fn = "abc"
7225 test_garbagecollect_now()
7226 assert_equal('string', typename(A.Fn))
7227 A.Fn2 = Foo
7228 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007229 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007230 A.Fn2 = "xyz"
7231 test_garbagecollect_now()
7232 assert_equal('string', typename(A.Fn2))
7233 END
7234 call v9.CheckSourceSuccess(lines)
7235
7236 " class variable with 'any" type. Can be assigned different types.
7237 let lines =<< trim END
7238 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007239 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007240 return {}
7241 enddef
7242 class A
7243 public static Fn: any = Foo
7244 public static Fn2: any
7245
7246 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007247 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007248 Fn = "abc"
7249 assert_equal('string', typename(Fn))
7250 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007251 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007252 Fn2 = "xyz"
7253 assert_equal('string', typename(Fn2))
7254 enddef
7255 endclass
7256 var a = A.new()
7257 test_garbagecollect_now()
7258 a.Bar()
7259 test_garbagecollect_now()
7260 A.Fn = Foo
7261 a.Bar()
7262 END
7263 call v9.CheckSourceSuccess(lines)
7264
7265 " class variable with 'any" type. Can be assigned different types.
7266 let lines =<< trim END
7267 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007268 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007269 return {}
7270 enddef
7271 class A
7272 public static Fn: any = Foo
7273 public static Fn2: any
7274 endclass
7275
7276 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007277 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007278 A.Fn = "abc"
7279 assert_equal('string', typename(A.Fn))
7280 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007281 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007282 A.Fn2 = "xyz"
7283 assert_equal('string', typename(A.Fn2))
7284 enddef
7285 Bar()
7286 test_garbagecollect_now()
7287 A.Fn = Foo
7288 Bar()
7289 END
7290 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007291
7292 let lines =<< trim END
7293 vim9script
7294 class A
7295 public static foo = [0z10, 0z20]
7296 endclass
7297 assert_equal([0z10, 0z20], A.foo)
7298 A.foo = [0z30]
7299 assert_equal([0z30], A.foo)
7300 var a = A.foo
7301 assert_equal([0z30], a)
7302 END
7303 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007304endfunc
7305
7306" Test type checking for object variable in assignments
7307func Test_object_variable_complex_type_check()
7308 " object variable with a specific type. Try assigning a different type at
7309 " script level.
7310 let lines =<< trim END
7311 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007312 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007313 return {}
7314 enddef
7315 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007316 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007317 endclass
7318 var a = A.new()
7319 test_garbagecollect_now()
7320 a.Fn = "abc"
7321 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007322 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 +02007323
7324 " object variable with a specific type. Try assigning a different type at
7325 " object def method level.
7326 let lines =<< trim END
7327 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007328 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007329 return {}
7330 enddef
7331 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007332 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007333 def Bar()
7334 this.Fn = "abc"
7335 this.Fn = Foo
7336 enddef
7337 endclass
7338 var a = A.new()
7339 test_garbagecollect_now()
7340 a.Bar()
7341 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007342 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 +02007343
7344 " object variable with a specific type. Try assigning a different type at
7345 " script def method level.
7346 let lines =<< trim END
7347 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007348 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007349 return {}
7350 enddef
7351 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007352 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007353 endclass
7354 def Bar()
7355 var a = A.new()
7356 a.Fn = "abc"
7357 a.Fn = Foo
7358 enddef
7359 test_garbagecollect_now()
7360 Bar()
7361 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007362 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 +02007363
7364 " object variable without any type. Should be set to the initialization
7365 " expression type. Try assigning a different type from script level.
7366 let lines =<< trim END
7367 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007368 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007369 return {}
7370 enddef
7371 class A
7372 public this.Fn = Foo
7373 endclass
7374 var a = A.new()
7375 test_garbagecollect_now()
7376 a.Fn = "abc"
7377 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007378 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 +02007379
7380 " object variable without any type. Should be set to the initialization
7381 " expression type. Try assigning a different type at object def level.
7382 let lines =<< trim END
7383 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007384 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007385 return {}
7386 enddef
7387 class A
7388 public this.Fn = Foo
7389 def Bar()
7390 this.Fn = "abc"
7391 this.Fn = Foo
7392 enddef
7393 endclass
7394 var a = A.new()
7395 test_garbagecollect_now()
7396 a.Bar()
7397 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007398 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 +02007399
7400 " object variable without any type. Should be set to the initialization
7401 " expression type. Try assigning a different type at script def level.
7402 let lines =<< trim END
7403 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007404 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007405 return {}
7406 enddef
7407 class A
7408 public this.Fn = Foo
7409 endclass
7410 def Bar()
7411 var a = A.new()
7412 a.Fn = "abc"
7413 a.Fn = Foo
7414 enddef
7415 test_garbagecollect_now()
7416 Bar()
7417 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007418 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 +02007419
7420 " object variable with 'any" type. Can be assigned different types.
7421 let lines =<< trim END
7422 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007423 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007424 return {}
7425 enddef
7426 class A
7427 public this.Fn: any = Foo
7428 public this.Fn2: any
7429 endclass
7430
7431 var a = A.new()
7432 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007433 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007434 a.Fn = "abc"
7435 test_garbagecollect_now()
7436 assert_equal('string', typename(a.Fn))
7437 a.Fn2 = Foo
7438 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007439 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007440 a.Fn2 = "xyz"
7441 test_garbagecollect_now()
7442 assert_equal('string', typename(a.Fn2))
7443 END
7444 call v9.CheckSourceSuccess(lines)
7445
7446 " object variable with 'any" type. Can be assigned different types.
7447 let lines =<< trim END
7448 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007449 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007450 return {}
7451 enddef
7452 class A
7453 public this.Fn: any = Foo
7454 public this.Fn2: any
7455
7456 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007457 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007458 this.Fn = "abc"
7459 assert_equal('string', typename(this.Fn))
7460 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007461 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007462 this.Fn2 = "xyz"
7463 assert_equal('string', typename(this.Fn2))
7464 enddef
7465 endclass
7466
7467 var a = A.new()
7468 test_garbagecollect_now()
7469 a.Bar()
7470 test_garbagecollect_now()
7471 a.Fn = Foo
7472 a.Bar()
7473 END
7474 call v9.CheckSourceSuccess(lines)
7475
7476 " object variable with 'any" type. Can be assigned different types.
7477 let lines =<< trim END
7478 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007479 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007480 return {}
7481 enddef
7482 class A
7483 public this.Fn: any = Foo
7484 public this.Fn2: any
7485 endclass
7486
7487 def Bar()
7488 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007489 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007490 a.Fn = "abc"
7491 assert_equal('string', typename(a.Fn))
7492 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007493 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007494 a.Fn2 = "xyz"
7495 assert_equal('string', typename(a.Fn2))
7496 enddef
7497 test_garbagecollect_now()
7498 Bar()
7499 test_garbagecollect_now()
7500 Bar()
7501 END
7502 call v9.CheckSourceSuccess(lines)
7503endfunc
7504
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007505" Test for recursively calling an object method. This used to cause an
7506" use-after-free error.
7507def Test_recursive_object_method_call()
7508 var lines =<< trim END
7509 vim9script
7510 class A
7511 this.val: number = 0
7512 def Foo(): number
7513 if this.val >= 90
7514 return this.val
7515 endif
7516 this.val += 1
7517 return this.Foo()
7518 enddef
7519 endclass
7520 var a = A.new()
7521 assert_equal(90, a.Foo())
7522 END
7523 v9.CheckSourceSuccess(lines)
7524enddef
7525
7526" Test for recursively calling a class method.
7527def Test_recursive_class_method_call()
7528 var lines =<< trim END
7529 vim9script
7530 class A
7531 static val: number = 0
7532 static def Foo(): number
7533 if val >= 90
7534 return val
7535 endif
7536 val += 1
7537 return Foo()
7538 enddef
7539 endclass
7540 assert_equal(90, A.Foo())
7541 END
7542 v9.CheckSourceSuccess(lines)
7543enddef
7544
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007545" Test for checking the argument types and the return type when assigning a
7546" funcref to make sure the invariant class type is used.
7547def Test_funcref_argtype_returntype_check()
7548 var lines =<< trim END
7549 vim9script
7550 class A
7551 endclass
7552 class B extends A
7553 endclass
7554
7555 def Foo(p: B): B
7556 return B.new()
7557 enddef
7558
7559 var Bar: func(A): A = Foo
7560 END
7561 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7562
7563 lines =<< trim END
7564 vim9script
7565 class A
7566 endclass
7567 class B extends A
7568 endclass
7569
7570 def Foo(p: B): B
7571 return B.new()
7572 enddef
7573
7574 def Baz()
7575 var Bar: func(A): A = Foo
7576 enddef
7577 Baz()
7578 END
7579 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7580enddef
7581
Ernie Rael96952b22023-10-17 18:15:01 +02007582def Test_funcref_argtype_invariance_check()
7583 var lines =<< trim END
7584 vim9script
7585
7586 class A
7587 endclass
7588 class B extends A
7589 endclass
7590 class C extends B
7591 endclass
7592
7593 var Func: func(B): number
7594 Func = (o: B): number => 3
7595 assert_equal(3, Func(B.new()))
7596 END
7597 v9.CheckSourceSuccess(lines)
7598
7599 lines =<< trim END
7600 vim9script
7601
7602 class A
7603 endclass
7604 class B extends A
7605 endclass
7606 class C extends B
7607 endclass
7608
7609 var Func: func(B): number
7610 Func = (o: A): number => 3
7611 END
7612 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7613
7614 lines =<< trim END
7615 vim9script
7616
7617 class A
7618 endclass
7619 class B extends A
7620 endclass
7621 class C extends B
7622 endclass
7623
7624 var Func: func(B): number
7625 Func = (o: C): number => 3
7626 END
7627 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7628enddef
7629
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007630" Test for using an operator (e.g. +) with an assignment
7631def Test_op_and_assignment()
7632 # Using += with a class variable
7633 var lines =<< trim END
7634 vim9script
7635 class A
7636 public static val: list<number> = []
7637 static def Foo(): list<number>
7638 val += [1]
7639 return val
7640 enddef
7641 endclass
7642 def Bar(): list<number>
7643 A.val += [2]
7644 return A.val
7645 enddef
7646 assert_equal([1], A.Foo())
7647 assert_equal([1, 2], Bar())
7648 A.val += [3]
7649 assert_equal([1, 2, 3], A.val)
7650 END
7651 v9.CheckSourceSuccess(lines)
7652
7653 # Using += with an object variable
7654 lines =<< trim END
7655 vim9script
7656 class A
7657 public this.val: list<number> = []
7658 def Foo(): list<number>
7659 this.val += [1]
7660 return this.val
7661 enddef
7662 endclass
7663 def Bar(bar_a: A): list<number>
7664 bar_a.val += [2]
7665 return bar_a.val
7666 enddef
7667 var a = A.new()
7668 assert_equal([1], a.Foo())
7669 assert_equal([1, 2], Bar(a))
7670 a.val += [3]
7671 assert_equal([1, 2, 3], a.val)
7672 END
7673 v9.CheckSourceSuccess(lines)
7674enddef
7675
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007676" Test for using an object method as a funcref
7677def Test_object_funcref()
7678 # Using object method funcref from a def function
7679 var lines =<< trim END
7680 vim9script
7681 class A
7682 def Foo(): list<number>
7683 return [3, 2, 1]
7684 enddef
7685 endclass
7686 def Bar()
7687 var a = A.new()
7688 var Fn = a.Foo
7689 assert_equal([3, 2, 1], Fn())
7690 enddef
7691 Bar()
7692 END
7693 v9.CheckSourceSuccess(lines)
7694
7695 # Using object method funcref at the script level
7696 lines =<< trim END
7697 vim9script
7698 class A
7699 def Foo(): dict<number>
7700 return {a: 1, b: 2}
7701 enddef
7702 endclass
7703 var a = A.new()
7704 var Fn = a.Foo
7705 assert_equal({a: 1, b: 2}, Fn())
7706 END
7707 v9.CheckSourceSuccess(lines)
7708
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007709 # Using object method funcref at the script level
7710 lines =<< trim END
7711 vim9script
7712 class A
7713 this.val: number
7714 def Foo(): number
7715 return this.val
7716 enddef
7717 endclass
7718 var a = A.new(345)
7719 var Fn = a.Foo
7720 assert_equal(345, Fn())
7721 END
7722 v9.CheckSourceSuccess(lines)
7723
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007724 # Using object method funcref from another object method
7725 lines =<< trim END
7726 vim9script
7727 class A
7728 def Foo(): list<number>
7729 return [3, 2, 1]
7730 enddef
7731 def Bar()
7732 var Fn = this.Foo
7733 assert_equal([3, 2, 1], Fn())
7734 enddef
7735 endclass
7736 var a = A.new()
7737 a.Bar()
7738 END
7739 v9.CheckSourceSuccess(lines)
7740
7741 # Using function() to get a object method funcref
7742 lines =<< trim END
7743 vim9script
7744 class A
7745 def Foo(l: list<any>): list<any>
7746 return l
7747 enddef
7748 endclass
7749 var a = A.new()
7750 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7751 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7752 END
7753 v9.CheckSourceSuccess(lines)
7754
7755 # Use an object method with a function returning a funcref and then call the
7756 # funcref.
7757 lines =<< trim END
7758 vim9script
7759
7760 def Map(F: func(number): number): func(number): number
7761 return (n: number) => F(n)
7762 enddef
7763
7764 class Math
7765 def Double(n: number): number
7766 return 2 * n
7767 enddef
7768 endclass
7769
7770 const math = Math.new()
7771 assert_equal(48, Map(math.Double)(24))
7772 END
7773 v9.CheckSourceSuccess(lines)
7774
Ernie Rael03042a22023-11-11 08:53:32 +01007775 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007776 lines =<< trim END
7777 vim9script
7778 class A
7779 def _Foo()
7780 enddef
7781 endclass
7782 def Bar()
7783 var a = A.new()
7784 var Fn = a._Foo
7785 enddef
7786 Bar()
7787 END
Ernie Rael03042a22023-11-11 08:53:32 +01007788 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007789
Ernie Rael03042a22023-11-11 08:53:32 +01007790 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007791 lines =<< trim END
7792 vim9script
7793 class A
7794 def _Foo()
7795 enddef
7796 endclass
7797 var a = A.new()
7798 var Fn = a._Foo
7799 END
Ernie Rael03042a22023-11-11 08:53:32 +01007800 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007801
Ernie Rael03042a22023-11-11 08:53:32 +01007802 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007803 lines =<< trim END
7804 vim9script
7805 class A
7806 def _Foo(): list<number>
7807 return [3, 2, 1]
7808 enddef
7809 def Bar()
7810 var Fn = this._Foo
7811 assert_equal([3, 2, 1], Fn())
7812 enddef
7813 endclass
7814 var a = A.new()
7815 a.Bar()
7816 END
7817 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007818
7819 # Using object method funcref using call()
7820 lines =<< trim END
7821 vim9script
7822 class A
7823 this.val: number
7824 def Foo(): number
7825 return this.val
7826 enddef
7827 endclass
7828
7829 def Bar(obj: A)
7830 assert_equal(123, call(obj.Foo, []))
7831 enddef
7832
7833 var a = A.new(123)
7834 Bar(a)
7835 assert_equal(123, call(a.Foo, []))
7836 END
7837 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007838enddef
7839
7840" Test for using a class method as a funcref
7841def Test_class_funcref()
7842 # Using class method funcref in a def function
7843 var lines =<< trim END
7844 vim9script
7845 class A
7846 static def Foo(): list<number>
7847 return [3, 2, 1]
7848 enddef
7849 endclass
7850 def Bar()
7851 var Fn = A.Foo
7852 assert_equal([3, 2, 1], Fn())
7853 enddef
7854 Bar()
7855 END
7856 v9.CheckSourceSuccess(lines)
7857
7858 # Using class method funcref at script level
7859 lines =<< trim END
7860 vim9script
7861 class A
7862 static def Foo(): dict<number>
7863 return {a: 1, b: 2}
7864 enddef
7865 endclass
7866 var Fn = A.Foo
7867 assert_equal({a: 1, b: 2}, Fn())
7868 END
7869 v9.CheckSourceSuccess(lines)
7870
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007871 # Using class method funcref at the script level
7872 lines =<< trim END
7873 vim9script
7874 class A
7875 public static val: number
7876 static def Foo(): number
7877 return val
7878 enddef
7879 endclass
7880 A.val = 567
7881 var Fn = A.Foo
7882 assert_equal(567, Fn())
7883 END
7884 v9.CheckSourceSuccess(lines)
7885
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007886 # Using function() to get a class method funcref
7887 lines =<< trim END
7888 vim9script
7889 class A
7890 static def Foo(l: list<any>): list<any>
7891 return l
7892 enddef
7893 endclass
7894 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
7895 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7896 END
7897 v9.CheckSourceSuccess(lines)
7898
7899 # Using a class method funcref from another class method
7900 lines =<< trim END
7901 vim9script
7902 class A
7903 static def Foo(): list<number>
7904 return [3, 2, 1]
7905 enddef
7906 static def Bar()
7907 var Fn = Foo
7908 assert_equal([3, 2, 1], Fn())
7909 enddef
7910 endclass
7911 A.Bar()
7912 END
7913 v9.CheckSourceSuccess(lines)
7914
7915 # Use a class method with a function returning a funcref and then call the
7916 # funcref.
7917 lines =<< trim END
7918 vim9script
7919
7920 def Map(F: func(number): number): func(number): number
7921 return (n: number) => F(n)
7922 enddef
7923
7924 class Math
7925 static def StaticDouble(n: number): number
7926 return 2 * n
7927 enddef
7928 endclass
7929
7930 assert_equal(48, Map(Math.StaticDouble)(24))
7931 END
7932 v9.CheckSourceSuccess(lines)
7933
Ernie Rael03042a22023-11-11 08:53:32 +01007934 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007935 lines =<< trim END
7936 vim9script
7937 class A
7938 static def _Foo()
7939 enddef
7940 endclass
7941 def Bar()
7942 var Fn = A._Foo
7943 enddef
7944 Bar()
7945 END
Ernie Rael03042a22023-11-11 08:53:32 +01007946 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007947
Ernie Rael03042a22023-11-11 08:53:32 +01007948 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007949 lines =<< trim END
7950 vim9script
7951 class A
7952 static def _Foo()
7953 enddef
7954 endclass
7955 var Fn = A._Foo
7956 END
Ernie Rael03042a22023-11-11 08:53:32 +01007957 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007958
Ernie Rael03042a22023-11-11 08:53:32 +01007959 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007960 lines =<< trim END
7961 vim9script
7962 class A
7963 static def _Foo(): list<number>
7964 return [3, 2, 1]
7965 enddef
7966 static def Bar()
7967 var Fn = _Foo
7968 assert_equal([3, 2, 1], Fn())
7969 enddef
7970 endclass
7971 A.Bar()
7972 END
7973 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007974
7975 # Using class method funcref using call()
7976 lines =<< trim END
7977 vim9script
7978 class A
7979 public static val: number
7980 static def Foo(): number
7981 return val
7982 enddef
7983 endclass
7984
7985 def Bar()
7986 A.val = 468
7987 assert_equal(468, call(A.Foo, []))
7988 enddef
7989 Bar()
7990 assert_equal(468, call(A.Foo, []))
7991 END
7992 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007993enddef
7994
7995" Test for using an object member as a funcref
7996def Test_object_member_funcref()
7997 # Using a funcref object variable in an object method
7998 var lines =<< trim END
7999 vim9script
8000 def Foo(n: number): number
8001 return n * 10
8002 enddef
8003
8004 class A
8005 this.Cb: func(number): number = Foo
8006 def Bar()
8007 assert_equal(200, this.Cb(20))
8008 enddef
8009 endclass
8010
8011 var a = A.new()
8012 a.Bar()
8013 END
8014 v9.CheckSourceSuccess(lines)
8015
8016 # Using a funcref object variable in a def method
8017 lines =<< trim END
8018 vim9script
8019 def Foo(n: number): number
8020 return n * 10
8021 enddef
8022
8023 class A
8024 this.Cb: func(number): number = Foo
8025 endclass
8026
8027 def Bar()
8028 var a = A.new()
8029 assert_equal(200, a.Cb(20))
8030 enddef
8031 Bar()
8032 END
8033 v9.CheckSourceSuccess(lines)
8034
8035 # Using a funcref object variable at script level
8036 lines =<< trim END
8037 vim9script
8038 def Foo(n: number): number
8039 return n * 10
8040 enddef
8041
8042 class A
8043 this.Cb: func(number): number = Foo
8044 endclass
8045
8046 var a = A.new()
8047 assert_equal(200, a.Cb(20))
8048 END
8049 v9.CheckSourceSuccess(lines)
8050
8051 # Using a funcref object variable pointing to an object method in an object
8052 # method.
8053 lines =<< trim END
8054 vim9script
8055 class A
8056 this.Cb: func(number): number = this.Foo
8057 def Foo(n: number): number
8058 return n * 10
8059 enddef
8060 def Bar()
8061 assert_equal(200, this.Cb(20))
8062 enddef
8063 endclass
8064
8065 var a = A.new()
8066 a.Bar()
8067 END
8068 v9.CheckSourceSuccess(lines)
8069
8070 # Using a funcref object variable pointing to an object method in a def
8071 # method.
8072 lines =<< trim END
8073 vim9script
8074 class A
8075 this.Cb: func(number): number = this.Foo
8076 def Foo(n: number): number
8077 return n * 10
8078 enddef
8079 endclass
8080
8081 def Bar()
8082 var a = A.new()
8083 assert_equal(200, a.Cb(20))
8084 enddef
8085 Bar()
8086 END
8087 v9.CheckSourceSuccess(lines)
8088
8089 # Using a funcref object variable pointing to an object method at script
8090 # level.
8091 lines =<< trim END
8092 vim9script
8093 class A
8094 this.Cb = this.Foo
8095 def Foo(n: number): number
8096 return n * 10
8097 enddef
8098 endclass
8099
8100 var a = A.new()
8101 assert_equal(200, a.Cb(20))
8102 END
8103 v9.CheckSourceSuccess(lines)
8104enddef
8105
8106" Test for using a class member as a funcref
8107def Test_class_member_funcref()
8108 # Using a funcref class variable in a class method
8109 var lines =<< trim END
8110 vim9script
8111 def Foo(n: number): number
8112 return n * 10
8113 enddef
8114
8115 class A
8116 static Cb = Foo
8117 static def Bar()
8118 assert_equal(200, Cb(20))
8119 enddef
8120 endclass
8121
8122 A.Bar()
8123 END
8124 v9.CheckSourceSuccess(lines)
8125
8126 # Using a funcref class variable in a def method
8127 lines =<< trim END
8128 vim9script
8129 def Foo(n: number): number
8130 return n * 10
8131 enddef
8132
8133 class A
8134 public static Cb = Foo
8135 endclass
8136
8137 def Bar()
8138 assert_equal(200, A.Cb(20))
8139 enddef
8140 Bar()
8141 END
8142 v9.CheckSourceSuccess(lines)
8143
8144 # Using a funcref class variable at script level
8145 lines =<< trim END
8146 vim9script
8147 def Foo(n: number): number
8148 return n * 10
8149 enddef
8150
8151 class A
8152 public static Cb = Foo
8153 endclass
8154
8155 assert_equal(200, A.Cb(20))
8156 END
8157 v9.CheckSourceSuccess(lines)
8158
8159 # Using a funcref class variable pointing to a class method in a class
8160 # method.
8161 lines =<< trim END
8162 vim9script
8163 class A
8164 static Cb: func(number): number
8165 static def Foo(n: number): number
8166 return n * 10
8167 enddef
8168 static def Init()
8169 Cb = Foo
8170 enddef
8171 static def Bar()
8172 assert_equal(200, Cb(20))
8173 enddef
8174 endclass
8175
8176 A.Init()
8177 A.Bar()
8178 END
8179 v9.CheckSourceSuccess(lines)
8180
8181 # Using a funcref class variable pointing to a class method in a def method.
8182 lines =<< trim END
8183 vim9script
8184 class A
8185 static Cb: func(number): number
8186 static def Foo(n: number): number
8187 return n * 10
8188 enddef
8189 static def Init()
8190 Cb = Foo
8191 enddef
8192 endclass
8193
8194 def Bar()
8195 A.Init()
8196 assert_equal(200, A.Cb(20))
8197 enddef
8198 Bar()
8199 END
8200 v9.CheckSourceSuccess(lines)
8201
8202 # Using a funcref class variable pointing to a class method at script level.
8203 lines =<< trim END
8204 vim9script
8205 class A
8206 static Cb: func(number): number
8207 static def Foo(n: number): number
8208 return n * 10
8209 enddef
8210 static def Init()
8211 Cb = Foo
8212 enddef
8213 endclass
8214
8215 A.Init()
8216 assert_equal(200, A.Cb(20))
8217 END
8218 v9.CheckSourceSuccess(lines)
8219enddef
8220
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008221" Test for using object methods as popup callback functions
8222def Test_objmethod_popup_callback()
8223 # Use the popup from the script level
8224 var lines =<< trim END
8225 vim9script
8226
8227 class A
8228 this.selection: number = -1
8229 this.filterkeys: list<string> = []
8230
8231 def PopupFilter(id: number, key: string): bool
8232 add(this.filterkeys, key)
8233 return popup_filter_yesno(id, key)
8234 enddef
8235
8236 def PopupCb(id: number, result: number)
8237 this.selection = result ? 100 : 200
8238 enddef
8239 endclass
8240
8241 var a = A.new()
8242 feedkeys('', 'xt')
8243 var winid = popup_create('Y/N?',
8244 {filter: a.PopupFilter, callback: a.PopupCb})
8245 feedkeys('y', 'xt')
8246 popup_close(winid)
8247 assert_equal(100, a.selection)
8248 assert_equal(['y'], a.filterkeys)
8249 feedkeys('', 'xt')
8250 winid = popup_create('Y/N?',
8251 {filter: a.PopupFilter, callback: a.PopupCb})
8252 feedkeys('n', 'xt')
8253 popup_close(winid)
8254 assert_equal(200, a.selection)
8255 assert_equal(['y', 'n'], a.filterkeys)
8256 END
8257 v9.CheckSourceSuccess(lines)
8258
8259 # Use the popup from a def function
8260 lines =<< trim END
8261 vim9script
8262
8263 class A
8264 this.selection: number = -1
8265 this.filterkeys: list<string> = []
8266
8267 def PopupFilter(id: number, key: string): bool
8268 add(this.filterkeys, key)
8269 return popup_filter_yesno(id, key)
8270 enddef
8271
8272 def PopupCb(id: number, result: number)
8273 this.selection = result ? 100 : 200
8274 enddef
8275 endclass
8276
8277 def Foo()
8278 var a = A.new()
8279 feedkeys('', 'xt')
8280 var winid = popup_create('Y/N?',
8281 {filter: a.PopupFilter, callback: a.PopupCb})
8282 feedkeys('y', 'xt')
8283 popup_close(winid)
8284 assert_equal(100, a.selection)
8285 assert_equal(['y'], a.filterkeys)
8286 feedkeys('', 'xt')
8287 winid = popup_create('Y/N?',
8288 {filter: a.PopupFilter, callback: a.PopupCb})
8289 feedkeys('n', 'xt')
8290 popup_close(winid)
8291 assert_equal(200, a.selection)
8292 assert_equal(['y', 'n'], a.filterkeys)
8293 enddef
8294 Foo()
8295 END
8296 v9.CheckSourceSuccess(lines)
8297enddef
8298
8299" Test for using class methods as popup callback functions
8300def Test_classmethod_popup_callback()
8301 # Use the popup from the script level
8302 var lines =<< trim END
8303 vim9script
8304
8305 class A
8306 static selection: number = -1
8307 static filterkeys: list<string> = []
8308
8309 static def PopupFilter(id: number, key: string): bool
8310 add(filterkeys, key)
8311 return popup_filter_yesno(id, key)
8312 enddef
8313
8314 static def PopupCb(id: number, result: number)
8315 selection = result ? 100 : 200
8316 enddef
8317 endclass
8318
8319 feedkeys('', 'xt')
8320 var winid = popup_create('Y/N?',
8321 {filter: A.PopupFilter, callback: A.PopupCb})
8322 feedkeys('y', 'xt')
8323 popup_close(winid)
8324 assert_equal(100, A.selection)
8325 assert_equal(['y'], A.filterkeys)
8326 feedkeys('', 'xt')
8327 winid = popup_create('Y/N?',
8328 {filter: A.PopupFilter, callback: A.PopupCb})
8329 feedkeys('n', 'xt')
8330 popup_close(winid)
8331 assert_equal(200, A.selection)
8332 assert_equal(['y', 'n'], A.filterkeys)
8333 END
8334 v9.CheckSourceSuccess(lines)
8335
8336 # Use the popup from a def function
8337 lines =<< trim END
8338 vim9script
8339
8340 class A
8341 static selection: number = -1
8342 static filterkeys: list<string> = []
8343
8344 static def PopupFilter(id: number, key: string): bool
8345 add(filterkeys, key)
8346 return popup_filter_yesno(id, key)
8347 enddef
8348
8349 static def PopupCb(id: number, result: number)
8350 selection = result ? 100 : 200
8351 enddef
8352 endclass
8353
8354 def Foo()
8355 feedkeys('', 'xt')
8356 var winid = popup_create('Y/N?',
8357 {filter: A.PopupFilter, callback: A.PopupCb})
8358 feedkeys('y', 'xt')
8359 popup_close(winid)
8360 assert_equal(100, A.selection)
8361 assert_equal(['y'], A.filterkeys)
8362 feedkeys('', 'xt')
8363 winid = popup_create('Y/N?',
8364 {filter: A.PopupFilter, callback: A.PopupCb})
8365 feedkeys('n', 'xt')
8366 popup_close(winid)
8367 assert_equal(200, A.selection)
8368 assert_equal(['y', 'n'], A.filterkeys)
8369 enddef
8370 Foo()
8371 END
8372 v9.CheckSourceSuccess(lines)
8373enddef
8374
8375" Test for using an object method as a timer callback function
8376def Test_objmethod_timer_callback()
8377 # Use the timer callback from script level
8378 var lines =<< trim END
8379 vim9script
8380
8381 class A
8382 this.timerTick: number = -1
8383 def TimerCb(timerID: number)
8384 this.timerTick = 6
8385 enddef
8386 endclass
8387
8388 var a = A.new()
8389 timer_start(0, a.TimerCb)
8390 var maxWait = 5
8391 while maxWait > 0 && a.timerTick == -1
8392 :sleep 10m
8393 maxWait -= 1
8394 endwhile
8395 assert_equal(6, a.timerTick)
8396 END
8397 v9.CheckSourceSuccess(lines)
8398
8399 # Use the timer callback from a def function
8400 lines =<< trim END
8401 vim9script
8402
8403 class A
8404 this.timerTick: number = -1
8405 def TimerCb(timerID: number)
8406 this.timerTick = 6
8407 enddef
8408 endclass
8409
8410 def Foo()
8411 var a = A.new()
8412 timer_start(0, a.TimerCb)
8413 var maxWait = 5
8414 while maxWait > 0 && a.timerTick == -1
8415 :sleep 10m
8416 maxWait -= 1
8417 endwhile
8418 assert_equal(6, a.timerTick)
8419 enddef
8420 Foo()
8421 END
8422 v9.CheckSourceSuccess(lines)
8423enddef
8424
8425" Test for using a class method as a timer callback function
8426def Test_classmethod_timer_callback()
8427 # Use the timer callback from script level
8428 var lines =<< trim END
8429 vim9script
8430
8431 class A
8432 static timerTick: number = -1
8433 static def TimerCb(timerID: number)
8434 timerTick = 6
8435 enddef
8436 endclass
8437
8438 timer_start(0, A.TimerCb)
8439 var maxWait = 5
8440 while maxWait > 0 && A.timerTick == -1
8441 :sleep 10m
8442 maxWait -= 1
8443 endwhile
8444 assert_equal(6, A.timerTick)
8445 END
8446 v9.CheckSourceSuccess(lines)
8447
8448 # Use the timer callback from a def function
8449 lines =<< trim END
8450 vim9script
8451
8452 class A
8453 static timerTick: number = -1
8454 static def TimerCb(timerID: number)
8455 timerTick = 6
8456 enddef
8457 endclass
8458
8459 def Foo()
8460 timer_start(0, A.TimerCb)
8461 var maxWait = 5
8462 while maxWait > 0 && A.timerTick == -1
8463 :sleep 10m
8464 maxWait -= 1
8465 endwhile
8466 assert_equal(6, A.timerTick)
8467 enddef
8468 Foo()
8469 END
8470 v9.CheckSourceSuccess(lines)
8471enddef
8472
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008473" Test for using a class variable as the first and/or second operand of a binary
8474" operator.
8475def Test_class_variable_as_operands()
8476 var lines =<< trim END
8477 vim9script
8478 class Tests
8479 static truthy: bool = true
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008480 public static TruthyFn: func
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008481 static list: list<any> = []
8482 static four: number = 4
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008483 static str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008484
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008485 static def Str(): string
8486 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008487 enddef
8488
8489 static def Four(): number
8490 return four
8491 enddef
8492
8493 static def List(): list<any>
8494 return list
8495 enddef
8496
8497 static def Truthy(): bool
8498 return truthy
8499 enddef
8500
8501 def TestOps()
8502 assert_true(Tests.truthy == truthy)
8503 assert_true(truthy == Tests.truthy)
8504 assert_true(Tests.list isnot [])
8505 assert_true([] isnot Tests.list)
8506 assert_equal(2, Tests.four >> 1)
8507 assert_equal(16, 1 << Tests.four)
8508 assert_equal(8, Tests.four + four)
8509 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008510 assert_equal('hellohello', Tests.str .. str)
8511 assert_equal('hellohello', str .. Tests.str)
8512
8513 # Using class variable for list indexing
8514 var l = range(10)
8515 assert_equal(4, l[Tests.four])
8516 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8517
8518 # Using class variable for Dict key
8519 var d = {hello: 'abc'}
8520 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008521 enddef
8522 endclass
8523
8524 def TestOps2()
8525 assert_true(Tests.truthy == Tests.Truthy())
8526 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008527 assert_true(Tests.truthy == Tests.TruthyFn())
8528 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008529 assert_true(Tests.list is Tests.List())
8530 assert_true(Tests.List() is Tests.list)
8531 assert_equal(2, Tests.four >> 1)
8532 assert_equal(16, 1 << Tests.four)
8533 assert_equal(8, Tests.four + Tests.Four())
8534 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008535 assert_equal('hellohello', Tests.str .. Tests.Str())
8536 assert_equal('hellohello', Tests.Str() .. Tests.str)
8537
8538 # Using class variable for list indexing
8539 var l = range(10)
8540 assert_equal(4, l[Tests.four])
8541 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8542
8543 # Using class variable for Dict key
8544 var d = {hello: 'abc'}
8545 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008546 enddef
8547
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008548 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008549 var t = Tests.new()
8550 t.TestOps()
8551 TestOps2()
8552
8553 assert_true(Tests.truthy == Tests.Truthy())
8554 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008555 assert_true(Tests.truthy == Tests.TruthyFn())
8556 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008557 assert_true(Tests.list is Tests.List())
8558 assert_true(Tests.List() is Tests.list)
8559 assert_equal(2, Tests.four >> 1)
8560 assert_equal(16, 1 << Tests.four)
8561 assert_equal(8, Tests.four + Tests.Four())
8562 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008563 assert_equal('hellohello', Tests.str .. Tests.Str())
8564 assert_equal('hellohello', Tests.Str() .. Tests.str)
8565
8566 # Using class variable for list indexing
8567 var l = range(10)
8568 assert_equal(4, l[Tests.four])
8569 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8570
8571 # Using class variable for Dict key
8572 var d = {hello: 'abc'}
8573 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008574 END
8575 v9.CheckSourceSuccess(lines)
8576enddef
8577
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008578" Test for checking the type of the key used to access an object dict member.
8579def Test_dict_member_key_type_check()
8580 var lines =<< trim END
8581 vim9script
8582
8583 abstract class State
8584 this.numbers: dict<string> = {0: 'nil', 1: 'unity'}
8585 endclass
8586
8587 class Test extends State
8588 def ObjMethodTests()
8589 var cursor: number = 0
8590 var z: number = 0
8591 [this.numbers[cursor]] = ['zero.1']
8592 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8593 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8594 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8595 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8596 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8597 [this.numbers[cursor], z] = ['zero.4', 1]
8598 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8599 [z, this.numbers[cursor]] = [1, 'zero.5']
8600 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8601 enddef
8602
8603 static def ClassMethodTests(that: State)
8604 var cursor: number = 0
8605 var z: number = 0
8606 [that.numbers[cursor]] = ['zero.1']
8607 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8608 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8609 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8610 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8611 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8612 [that.numbers[cursor], z] = ['zero.4', 1]
8613 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8614 [z, that.numbers[cursor]] = [1, 'zero.5']
8615 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8616 enddef
8617
8618 def new()
8619 enddef
8620
8621 def newMethodTests()
8622 var cursor: number = 0
8623 var z: number
8624 [this.numbers[cursor]] = ['zero.1']
8625 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8626 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8627 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8628 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8629 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8630 [this.numbers[cursor], z] = ['zero.4', 1]
8631 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8632 [z, this.numbers[cursor]] = [1, 'zero.5']
8633 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8634 enddef
8635 endclass
8636
8637 def DefFuncTests(that: Test)
8638 var cursor: number = 0
8639 var z: number
8640 [that.numbers[cursor]] = ['zero.1']
8641 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8642 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8643 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8644 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8645 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8646 [that.numbers[cursor], z] = ['zero.4', 1]
8647 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8648 [z, that.numbers[cursor]] = [1, 'zero.5']
8649 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8650 enddef
8651
8652 Test.newMethodTests()
8653 Test.new().ObjMethodTests()
8654 Test.ClassMethodTests(Test.new())
8655 DefFuncTests(Test.new())
8656
8657 const test: Test = Test.new()
8658 var cursor: number = 0
8659 [test.numbers[cursor], cursor] = ['zero', 1]
8660 [cursor, test.numbers[cursor]] = [1, 'one']
8661 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8662 END
8663 v9.CheckSourceSuccess(lines)
8664
8665 lines =<< trim END
8666 vim9script
8667
8668 class A
8669 this.numbers: dict<string> = {a: '1', b: '2'}
8670
8671 def new()
8672 enddef
8673
8674 def Foo()
8675 var z: number
8676 [this.numbers.a, z] = [{}, 10]
8677 enddef
8678 endclass
8679
8680 var a = A.new()
8681 a.Foo()
8682 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008683 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008684
8685 lines =<< trim END
8686 vim9script
8687
8688 class A
8689 this.numbers: dict<number> = {a: 1, b: 2}
8690
8691 def new()
8692 enddef
8693
8694 def Foo()
8695 var x: string = 'a'
8696 var y: number
8697 [this.numbers[x], y] = [{}, 10]
8698 enddef
8699 endclass
8700
8701 var a = A.new()
8702 a.Foo()
8703 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008704 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008705enddef
8706
mityua5550692023-11-25 15:41:20 +01008707def Test_compile_many_def_functions_in_funcref_instr()
8708 # This used to crash Vim. This is reproducible only when run on new instance
8709 # of Vim.
8710 var lines =<< trim END
8711 vim9script
8712
8713 class A
8714 def new()
8715 this.TakeFunc(this.F00)
8716 enddef
8717
8718 def TakeFunc(F: func)
8719 enddef
8720
8721 def F00()
8722 this.F01()
8723 this.F02()
8724 this.F03()
8725 this.F04()
8726 this.F05()
8727 this.F06()
8728 this.F07()
8729 this.F08()
8730 this.F09()
8731 this.F10()
8732 this.F11()
8733 this.F12()
8734 this.F13()
8735 this.F14()
8736 this.F15()
8737 this.F16()
8738 this.F17()
8739 this.F18()
8740 this.F19()
8741 this.F20()
8742 this.F21()
8743 this.F22()
8744 this.F23()
8745 this.F24()
8746 this.F25()
8747 this.F26()
8748 this.F27()
8749 this.F28()
8750 this.F29()
8751 this.F30()
8752 this.F31()
8753 this.F32()
8754 this.F33()
8755 this.F34()
8756 this.F35()
8757 this.F36()
8758 this.F37()
8759 this.F38()
8760 this.F39()
8761 this.F40()
8762 this.F41()
8763 this.F42()
8764 this.F43()
8765 this.F44()
8766 this.F45()
8767 this.F46()
8768 this.F47()
8769 enddef
8770
8771 def F01()
8772 enddef
8773 def F02()
8774 enddef
8775 def F03()
8776 enddef
8777 def F04()
8778 enddef
8779 def F05()
8780 enddef
8781 def F06()
8782 enddef
8783 def F07()
8784 enddef
8785 def F08()
8786 enddef
8787 def F09()
8788 enddef
8789 def F10()
8790 enddef
8791 def F11()
8792 enddef
8793 def F12()
8794 enddef
8795 def F13()
8796 enddef
8797 def F14()
8798 enddef
8799 def F15()
8800 enddef
8801 def F16()
8802 enddef
8803 def F17()
8804 enddef
8805 def F18()
8806 enddef
8807 def F19()
8808 enddef
8809 def F20()
8810 enddef
8811 def F21()
8812 enddef
8813 def F22()
8814 enddef
8815 def F23()
8816 enddef
8817 def F24()
8818 enddef
8819 def F25()
8820 enddef
8821 def F26()
8822 enddef
8823 def F27()
8824 enddef
8825 def F28()
8826 enddef
8827 def F29()
8828 enddef
8829 def F30()
8830 enddef
8831 def F31()
8832 enddef
8833 def F32()
8834 enddef
8835 def F33()
8836 enddef
8837 def F34()
8838 enddef
8839 def F35()
8840 enddef
8841 def F36()
8842 enddef
8843 def F37()
8844 enddef
8845 def F38()
8846 enddef
8847 def F39()
8848 enddef
8849 def F40()
8850 enddef
8851 def F41()
8852 enddef
8853 def F42()
8854 enddef
8855 def F43()
8856 enddef
8857 def F44()
8858 enddef
8859 def F45()
8860 enddef
8861 def F46()
8862 enddef
8863 def F47()
8864 enddef
8865 endclass
8866
8867 A.new()
8868 END
8869 writefile(lines, 'Xscript', 'D')
8870 g:RunVim([], [], '-u NONE -S Xscript -c qa')
8871 assert_equal(0, v:shell_error)
8872enddef
8873
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008874" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker