blob: 6f9723dfae033001e1545b4703db9e7f1534d3b1 [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
Ernie Raelfa831102023-12-14 20:06:39 +0100193 v9.CheckSourceFailure(lines, 'E1405: Class "A" cannot be used as a value', 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
Yegappan Lakshmanand2e1c832023-12-14 19:59:45 +01003033" Test for implementing an imported interface
3034def Test_implement_imported_interface()
3035 var lines =<< trim END
3036 vim9script
3037 export interface Imp_Intf1
3038 def Fn1(): number
3039 endinterface
3040 export interface Imp_Intf2
3041 def Fn2(): number
3042 endinterface
3043 END
3044 writefile(lines, 'Ximportinterface.vim', 'D')
3045
3046 lines =<< trim END
3047 vim9script
3048 import './Ximportinterface.vim' as Xintf
3049
3050 class A implements Xintf.Imp_Intf1, Xintf.Imp_Intf2
3051 def Fn1(): number
3052 return 10
3053 enddef
3054 def Fn2(): number
3055 return 20
3056 enddef
3057 endclass
3058 var a = A.new()
3059 assert_equal(10, a.Fn1())
3060 assert_equal(20, a.Fn2())
3061 END
3062 v9.CheckScriptSuccess(lines)
3063enddef
3064
3065" Test for extending an imported class
3066def Test_extend_imported_class()
3067 var lines =<< trim END
3068 vim9script
3069 export class Imp_C1
3070 def Fn1(): number
3071 return 5
3072 enddef
3073 endclass
3074 END
3075 writefile(lines, 'Xextendimportclass.vim', 'D')
3076
3077 lines =<< trim END
3078 vim9script
3079 import './Xextendimportclass.vim' as XClass
3080
3081 class A extends XClass.Imp_C1
3082 endclass
3083 var a = A.new()
3084 assert_equal(5, a.Fn1())
3085 END
3086 v9.CheckScriptSuccess(lines)
3087enddef
3088
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003089def Test_abstract_class()
3090 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003091 vim9script
3092 abstract class Base
3093 this.name: string
3094 endclass
3095 class Person extends Base
3096 this.age: number
3097 endclass
3098 var p: Base = Person.new('Peter', 42)
3099 assert_equal('Peter', p.name)
3100 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003101 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003102 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003103
3104 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003105 vim9script
3106 abstract class Base
3107 this.name: string
3108 endclass
3109 class Person extends Base
3110 this.age: number
3111 endclass
3112 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003113 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02003114 v9.CheckSourceFailure(lines, 'E1325: Method "new" not found in class "Base"', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003115
3116 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003117 abstract class Base
3118 this.name: string
3119 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003120 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003121 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003122
3123 # Abstract class cannot have a "new" function
3124 lines =<< trim END
3125 vim9script
3126 abstract class Base
3127 def new()
3128 enddef
3129 endclass
3130 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003131 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00003132enddef
3133
Bram Moolenaar486fc252023-01-18 14:51:07 +00003134def Test_closure_in_class()
3135 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003136 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00003137
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003138 class Foo
3139 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00003140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003141 def new()
3142 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
3143 enddef
3144 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00003145
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003146 Foo.new()
3147 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003148 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003149 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00003150enddef
3151
Ernie Rael9ed53752023-12-11 17:40:46 +01003152def Test_construct_object_from_legacy()
3153 # Cannot directly invoke constructor from legacy
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003154 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003155 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003156
Ernie Rael9ed53752023-12-11 17:40:46 +01003157 var newCalled = false
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003158
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003159 class A
Ernie Rael9ed53752023-12-11 17:40:46 +01003160 def new(arg: string)
3161 newCalled = true
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003162 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003163 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003164
Ernie Rael9ed53752023-12-11 17:40:46 +01003165 export def CreateA(...args: list<any>): A
3166 return call(A.new, args)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003167 enddef
3168
Ernie Rael9ed53752023-12-11 17:40:46 +01003169 g:P = CreateA
3170 legacy call g:P('some_arg')
3171 assert_equal(true, newCalled)
3172 unlet g:P
3173 END
3174 v9.CheckSourceSuccess(lines)
3175
3176 lines =<< trim END
3177 vim9script
3178
3179 var newCalled = false
3180
3181 class A
3182 static def CreateA(options = {}): any
3183 return A.new()
3184 enddef
3185 def new()
3186 newCalled = true
3187 enddef
3188 endclass
3189
3190 g:P = A.CreateA
3191 legacy call g:P()
3192 assert_equal(true, newCalled)
3193 unlet g:P
3194 END
3195 v9.CheckSourceSuccess(lines)
3196
3197 # This also tests invoking "new()" with "call"
3198 lines =<< trim END
3199 vim9script
3200
3201 var createdObject: any
3202
3203 class A
3204 this.val1: number
3205 this.val2: number
3206 static def CreateA(...args: list<any>): any
3207 createdObject = call(A.new, args)
3208 return createdObject
3209 enddef
3210 endclass
3211
3212 g:P = A.CreateA
3213 legacy call g:P(3, 5)
3214 assert_equal(3, createdObject.val1)
3215 assert_equal(5, createdObject.val2)
3216 legacy call g:P()
3217 assert_equal(0, createdObject.val1)
3218 assert_equal(0, createdObject.val2)
3219 legacy call g:P(7)
3220 assert_equal(7, createdObject.val1)
3221 assert_equal(0, createdObject.val2)
3222 unlet g:P
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003223 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003224 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01003225enddef
3226
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003227def Test_defer_with_object()
3228 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003229 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003230
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003231 class CWithEE
3232 def Enter()
3233 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003234 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003235 def Exit()
3236 g:result ..= "exited"
3237 enddef
3238 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003240 def With(ee: CWithEE, F: func)
3241 ee.Enter()
3242 defer ee.Exit()
3243 F()
3244 enddef
3245
3246 g:result = ''
3247 var obj = CWithEE.new()
3248 obj->With(() => {
3249 g:result ..= "called/"
3250 })
3251 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003252 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003253 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003254 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003255
3256 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003257 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003258
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003259 class BaseWithEE
3260 def Enter()
3261 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003262 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003263 def Exit()
3264 g:result ..= "exited-base"
3265 enddef
3266 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003267
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003268 class CWithEE extends BaseWithEE
3269 def Enter()
3270 g:result ..= "entered-child/"
3271 enddef
3272 def Exit()
3273 g:result ..= "exited-child"
3274 enddef
3275 endclass
3276
3277 def With(ee: BaseWithEE, F: func)
3278 ee.Enter()
3279 defer ee.Exit()
3280 F()
3281 enddef
3282
3283 g:result = ''
3284 var obj = CWithEE.new()
3285 obj->With(() => {
3286 g:result ..= "called/"
3287 })
3288 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003289 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003290 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003291 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003292enddef
3293
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003294" The following test used to crash Vim (Github issue #12676)
3295def Test_extends_method_crashes_vim()
3296 var lines =<< trim END
3297 vim9script
3298
3299 class Observer
3300 endclass
3301
3302 class Property
3303 this.value: any
3304
3305 def Set(v: any)
3306 if v != this.value
3307 this.value = v
3308 endif
3309 enddef
3310
3311 def Register(observer: Observer)
3312 enddef
3313 endclass
3314
3315 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003316 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003317 endclass
3318
3319 def Observe(obj: Property, who: Observer)
3320 obj.Register(who)
3321 enddef
3322
3323 var p = Bool.new(false)
3324 var myObserver = Observer.new()
3325
3326 Observe(p, myObserver)
3327
3328 p.Set(true)
3329 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003330 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003331enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003332
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003333" Test for calling a method in a class that is extended
3334def Test_call_method_in_extended_class()
3335 var lines =<< trim END
3336 vim9script
3337
3338 var prop_init_called = false
3339 var prop_register_called = false
3340
3341 class Property
3342 def Init()
3343 prop_init_called = true
3344 enddef
3345
3346 def Register()
3347 prop_register_called = true
3348 enddef
3349 endclass
3350
3351 class Bool extends Property
3352 endclass
3353
3354 def Observe(obj: Property)
3355 obj.Register()
3356 enddef
3357
3358 var p = Property.new()
3359 Observe(p)
3360
3361 p.Init()
3362 assert_true(prop_init_called)
3363 assert_true(prop_register_called)
3364 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003365 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003366enddef
3367
LemonBoyafe04662023-08-23 21:08:11 +02003368def Test_instanceof()
3369 var lines =<< trim END
3370 vim9script
3371
3372 class Base1
3373 endclass
3374
3375 class Base2 extends Base1
3376 endclass
3377
3378 interface Intf1
3379 endinterface
3380
3381 class Mix1 implements Intf1
3382 endclass
3383
3384 class Base3 extends Mix1
3385 endclass
3386
Ernie Rael2025af12023-12-12 16:58:00 +01003387 type AliasBase1 = Base1
3388 type AliasBase2 = Base2
3389 type AliasIntf1 = Intf1
3390 type AliasMix1 = Mix1
3391
LemonBoyafe04662023-08-23 21:08:11 +02003392 var b1 = Base1.new()
3393 var b2 = Base2.new()
3394 var b3 = Base3.new()
3395
3396 assert_true(instanceof(b1, Base1))
3397 assert_true(instanceof(b2, Base1))
3398 assert_false(instanceof(b1, Base2))
3399 assert_true(instanceof(b3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003400 assert_true(instanceof(b3, Base1, Base2, Intf1))
3401
3402 assert_true(instanceof(b1, AliasBase1))
3403 assert_true(instanceof(b2, AliasBase1))
3404 assert_false(instanceof(b1, AliasBase2))
3405 assert_true(instanceof(b3, AliasMix1))
3406 assert_true(instanceof(b3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003407
3408 def Foo()
3409 var a1 = Base1.new()
3410 var a2 = Base2.new()
3411 var a3 = Base3.new()
3412
3413 assert_true(instanceof(a1, Base1))
3414 assert_true(instanceof(a2, Base1))
3415 assert_false(instanceof(a1, Base2))
3416 assert_true(instanceof(a3, Mix1))
Ernie Rael2025af12023-12-12 16:58:00 +01003417 assert_true(instanceof(a3, Base1, Base2, Intf1))
3418
3419 assert_true(instanceof(a1, AliasBase1))
3420 assert_true(instanceof(a2, AliasBase1))
3421 assert_false(instanceof(a1, AliasBase2))
3422 assert_true(instanceof(a3, AliasMix1))
3423 assert_true(instanceof(a3, AliasBase1, AliasBase2, AliasIntf1))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003424 enddef
3425 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003426
3427 var o_null: Base1
3428 assert_false(instanceof(o_null, Base1))
3429
LemonBoyafe04662023-08-23 21:08:11 +02003430 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003431 v9.CheckSourceSuccess(lines)
Ernie Rael2025af12023-12-12 16:58:00 +01003432
3433 lines =<< trim END
3434 vim9script
3435
3436 class Base1
3437 endclass
3438 instanceof(Base1.new())
3439 END
3440 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3441
3442 lines =<< trim END
3443 vim9script
3444
3445 class Base1
3446 endclass
3447 def F()
3448 instanceof(Base1.new())
3449 enddef
3450 F()
3451 END
3452 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: instanceof')
3453
3454 lines =<< trim END
3455 vim9script
3456
3457 class Base1
3458 endclass
3459
3460 class Base2
3461 endclass
3462
3463 var o = Base2.new()
3464 instanceof(o, Base1, Base2, 3)
3465 END
3466 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4', 10)
3467
3468 lines =<< trim END
3469 vim9script
3470
3471 class Base1
3472 endclass
3473
3474 class Base2
3475 endclass
3476
3477 def F()
3478 var o = Base2.new()
3479 instanceof(o, Base1, Base2, 3)
3480 enddef
3481 F()
3482 END
3483 v9.CheckSourceFailure(lines, 'E693: Class or class typealias required for argument 4')
LemonBoyafe04662023-08-23 21:08:11 +02003484enddef
3485
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003486" Test for calling a method in the parent class that is extended partially.
3487" This used to fail with the 'E118: Too many arguments for function: Text' error
3488" message (Github issue #12524).
3489def Test_call_method_in_parent_class()
3490 var lines =<< trim END
3491 vim9script
3492
3493 class Widget
3494 this._lnum: number = 1
3495
3496 def SetY(lnum: number)
3497 this._lnum = lnum
3498 enddef
3499
3500 def Text(): string
3501 return ''
3502 enddef
3503 endclass
3504
3505 class Foo extends Widget
3506 def Text(): string
3507 return '<Foo>'
3508 enddef
3509 endclass
3510
3511 def Stack(w1: Widget, w2: Widget): list<Widget>
3512 w1.SetY(1)
3513 w2.SetY(2)
3514 return [w1, w2]
3515 enddef
3516
3517 var foo1 = Foo.new()
3518 var foo2 = Foo.new()
3519 var l = Stack(foo1, foo2)
3520 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003521 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003522enddef
3523
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003524" Test for calling methods from three levels of classes
3525def Test_multi_level_method_call()
3526 var lines =<< trim END
3527 vim9script
3528
3529 var A_func1: number = 0
3530 var A_func2: number = 0
3531 var A_func3: number = 0
3532 var B_func2: number = 0
3533 var B_func3: number = 0
3534 var C_func3: number = 0
3535
3536 class A
3537 def Func1()
3538 A_func1 += 1
3539 enddef
3540
3541 def Func2()
3542 A_func2 += 1
3543 enddef
3544
3545 def Func3()
3546 A_func3 += 1
3547 enddef
3548 endclass
3549
3550 class B extends A
3551 def Func2()
3552 B_func2 += 1
3553 enddef
3554
3555 def Func3()
3556 B_func3 += 1
3557 enddef
3558 endclass
3559
3560 class C extends B
3561 def Func3()
3562 C_func3 += 1
3563 enddef
3564 endclass
3565
3566 def A_CallFuncs(a: A)
3567 a.Func1()
3568 a.Func2()
3569 a.Func3()
3570 enddef
3571
3572 def B_CallFuncs(b: B)
3573 b.Func1()
3574 b.Func2()
3575 b.Func3()
3576 enddef
3577
3578 def C_CallFuncs(c: C)
3579 c.Func1()
3580 c.Func2()
3581 c.Func3()
3582 enddef
3583
3584 var cobj = C.new()
3585 A_CallFuncs(cobj)
3586 B_CallFuncs(cobj)
3587 C_CallFuncs(cobj)
3588 assert_equal(3, A_func1)
3589 assert_equal(0, A_func2)
3590 assert_equal(0, A_func3)
3591 assert_equal(3, B_func2)
3592 assert_equal(0, B_func3)
3593 assert_equal(3, C_func3)
3594 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003595 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003596enddef
3597
3598" Test for using members from three levels of classes
3599def Test_multi_level_member_access()
3600 var lines =<< trim END
3601 vim9script
3602
3603 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003604 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003605 endclass
3606
3607 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003608 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003609 endclass
3610
3611 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003612 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003613 endclass
3614
3615 def A_members(a: A)
3616 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003617 enddef
3618
3619 def B_members(b: B)
3620 b.val1 += 1
3621 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003622 enddef
3623
3624 def C_members(c: C)
3625 c.val1 += 1
3626 c.val2 += 1
3627 c.val3 += 1
3628 enddef
3629
3630 var cobj = C.new()
3631 A_members(cobj)
3632 B_members(cobj)
3633 C_members(cobj)
3634 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003635 assert_equal(2, cobj.val2)
3636 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003637 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003638 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003639enddef
3640
LemonBoy0ffc17a2023-08-20 18:09:11 +02003641" Test expansion of <stack> with class methods.
3642def Test_stack_expansion_with_methods()
3643 var lines =<< trim END
3644 vim9script
3645
3646 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003647 def M1()
3648 F0()
3649 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003650 endclass
3651
3652 def F0()
3653 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3654 enddef
3655
3656 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003657 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003658 enddef
3659
3660 F()
3661 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003662 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003663enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003664
3665" Test the return type of the new() constructor
3666def Test_new_return_type()
3667 # new() uses the default return type and there is no return statement
3668 var lines =<< trim END
3669 vim9script
3670
3671 class C
3672 this._bufnr: number
3673
3674 def new(this._bufnr)
3675 if !bufexists(this._bufnr)
3676 this._bufnr = -1
3677 endif
3678 enddef
3679 endclass
3680
3681 var c = C.new(12345)
3682 assert_equal('object<C>', typename(c))
3683
3684 var v1: C
3685 v1 = C.new(12345)
3686 assert_equal('object<C>', typename(v1))
3687
3688 def F()
3689 var v2: C
3690 v2 = C.new(12345)
3691 assert_equal('object<C>', typename(v2))
3692 enddef
3693 F()
3694 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003695 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003696
3697 # new() uses the default return type and an empty 'return' statement
3698 lines =<< trim END
3699 vim9script
3700
3701 class C
3702 this._bufnr: number
3703
3704 def new(this._bufnr)
3705 if !bufexists(this._bufnr)
3706 this._bufnr = -1
3707 return
3708 endif
3709 enddef
3710 endclass
3711
3712 var c = C.new(12345)
3713 assert_equal('object<C>', typename(c))
3714
3715 var v1: C
3716 v1 = C.new(12345)
3717 assert_equal('object<C>', typename(v1))
3718
3719 def F()
3720 var v2: C
3721 v2 = C.new(12345)
3722 assert_equal('object<C>', typename(v2))
3723 enddef
3724 F()
3725 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003726 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003727
3728 # new() uses "any" return type and returns "this"
3729 lines =<< trim END
3730 vim9script
3731
3732 class C
3733 this._bufnr: number
3734
3735 def new(this._bufnr): any
3736 if !bufexists(this._bufnr)
3737 this._bufnr = -1
3738 return this
3739 endif
3740 enddef
3741 endclass
3742 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003743 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003744
3745 # new() uses 'Dict' return type and returns a Dict
3746 lines =<< trim END
3747 vim9script
3748
3749 class C
3750 this._state: dict<any>
3751
3752 def new(): dict<any>
3753 this._state = {}
3754 return this._state
3755 enddef
3756 endclass
3757
3758 var c = C.new()
3759 assert_equal('object<C>', typename(c))
3760 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003761 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003762enddef
3763
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003764" Test for checking a member initialization type at run time.
3765def Test_runtime_type_check_for_member_init()
3766 var lines =<< trim END
3767 vim9script
3768
3769 var retnum: bool = false
3770
3771 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003772 retnum = !retnum
3773 if retnum
3774 return 1
3775 else
3776 return "hello"
3777 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003778 enddef
3779
3780 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003781 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003782 endclass
3783
3784 var c1 = C.new()
3785 var c2 = C.new()
3786 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003787 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003788enddef
3789
3790" Test for locking a variable referring to an object and reassigning to another
3791" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003792def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003793 var lines =<< trim END
3794 vim9script
3795
3796 class C
3797 this.val: number
3798 def new(this.val)
3799 enddef
3800 endclass
3801
3802 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3803 lockvar 2 some_dict
3804
3805 var current: C
3806 current = some_dict['c']
3807 assert_equal(3, current.val)
3808 current = some_dict['b']
3809 assert_equal(2, current.val)
3810
3811 def F()
3812 current = some_dict['c']
3813 enddef
3814
3815 def G()
3816 current = some_dict['b']
3817 enddef
3818
3819 F()
3820 assert_equal(3, current.val)
3821 G()
3822 assert_equal(2, current.val)
3823 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003824 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003825enddef
3826
Ernie Raelee865f32023-09-29 19:53:55 +02003827" Test trying to lock an object variable from various places
3828def Test_lockvar_object_variable()
3829 # An object variable lockvar has several cases:
3830 # object method, scriptlevel, scriplevel from :def, :def arg
3831 # method arg, static method arg.
3832 # Also different depths
3833
Ernie Raelee865f32023-09-29 19:53:55 +02003834 #
3835 # lockvar of read-only object variable
3836 #
3837
3838 # read-only lockvar from object method
3839 var lines =<< trim END
3840 vim9script
3841
3842 class C
3843 this.val1: number
3844 def Lock()
3845 lockvar this.val1
3846 enddef
3847 endclass
3848 var o = C.new(3)
3849 o.Lock()
3850 END
Ernie Rael64885642023-10-04 20:16:22 +02003851 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003852
3853 # read-only lockvar from scriptlevel
3854 lines =<< trim END
3855 vim9script
3856
3857 class C
3858 this.val2: number
3859 endclass
3860 var o = C.new(3)
3861 lockvar o.val2
3862 END
3863 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3864
3865 # read-only lockvar of scriptlevel variable from def
3866 lines =<< trim END
3867 vim9script
3868
3869 class C
3870 this.val3: number
3871 endclass
3872 var o = C.new(3)
3873 def Lock()
3874 lockvar o.val3
3875 enddef
3876 Lock()
3877 END
3878 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3879
3880 # read-only lockvar of def argument variable
3881 lines =<< trim END
3882 vim9script
3883
3884 class C
3885 this.val4: number
3886 endclass
3887 def Lock(o: C)
3888 lockvar o.val4
3889 enddef
3890 Lock(C.new(3))
3891 END
3892 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3893
3894 # TODO: the following tests use type "any" for argument. Need a run time
3895 # check for access. Probably OK as is for now.
3896
3897 # read-only lockvar from object method arg
3898 lines =<< trim END
3899 vim9script
3900
3901 class C
3902 this.val5: number
3903 def Lock(o_any: any)
3904 lockvar o_any.val5
3905 enddef
3906 endclass
3907 var o = C.new(3)
3908 o.Lock(C.new(5))
3909 END
Ernie Rael64885642023-10-04 20:16:22 +02003910 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003911
3912 # read-only lockvar from class method arg
3913 lines =<< trim END
3914 vim9script
3915
3916 class C
3917 this.val6: number
3918 static def Lock(o_any: any)
3919 lockvar o_any.val6
3920 enddef
3921 endclass
3922 var o = C.new(3)
3923 C.Lock(o)
3924 END
Ernie Rael64885642023-10-04 20:16:22 +02003925 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02003926
3927 #
3928 # lockvar of public object variable
3929 #
3930
3931 # lockvar from object method
3932 lines =<< trim END
3933 vim9script
3934
3935 class C
3936 public this.val1: number
3937 def Lock()
3938 lockvar this.val1
3939 enddef
3940 endclass
3941 var o = C.new(3)
3942 o.Lock()
3943 END
3944 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3945
3946 # lockvar from scriptlevel
3947 lines =<< trim END
3948 vim9script
3949
3950 class C
3951 public this.val2: number
3952 endclass
3953 var o = C.new(3)
3954 lockvar o.val2
3955 END
3956 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3957
3958 # lockvar of scriptlevel variable from def
3959 lines =<< trim END
3960 vim9script
3961
3962 class C
3963 public this.val3: number
3964 endclass
3965 var o = C.new(3)
3966 def Lock()
3967 lockvar o.val3
3968 enddef
3969 Lock()
3970 END
3971 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3972
3973 # lockvar of def argument variable
3974 lines =<< trim END
3975 vim9script
3976
3977 class C
3978 public this.val4: number
3979 endclass
3980 def Lock(o: C)
3981 lockvar o.val4
3982 enddef
3983 Lock(C.new(3))
3984 END
3985 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3986
3987 # lockvar from object method arg
3988 lines =<< trim END
3989 vim9script
3990
3991 class C
3992 public this.val5: number
3993 def Lock(o_any: any)
3994 lockvar o_any.val5
3995 enddef
3996 endclass
3997 var o = C.new(3)
3998 o.Lock(C.new(5))
3999 END
4000 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
4001
4002 # lockvar from class method arg
4003 lines =<< trim END
4004 vim9script
4005
4006 class C
4007 public this.val6: number
4008 static def Lock(o_any: any)
4009 lockvar o_any.val6
4010 enddef
4011 endclass
4012 var o = C.new(3)
4013 C.Lock(o)
4014 END
4015 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
4016enddef
4017
4018" Test trying to lock a class variable from various places
4019def Test_lockvar_class_variable()
4020
4021 # lockvar bare static from object method
4022 var lines =<< trim END
4023 vim9script
4024
4025 class C
4026 public static sval1: number
4027 def Lock()
4028 lockvar sval1
4029 enddef
4030 endclass
4031 var o = C.new()
4032 o.Lock()
4033 END
4034 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
4035
4036 # lockvar C.static from object method
4037 lines =<< trim END
4038 vim9script
4039
4040 class C
4041 public static sval2: number
4042 def Lock()
4043 lockvar C.sval2
4044 enddef
4045 endclass
4046 var o = C.new()
4047 o.Lock()
4048 END
4049 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
4050
4051 # lockvar bare static from class method
4052 lines =<< trim END
4053 vim9script
4054
4055 class C
4056 public static sval3: number
4057 static def Lock()
4058 lockvar sval3
4059 enddef
4060 endclass
4061 C.Lock()
4062 END
4063 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
4064
4065 # lockvar C.static from class method
4066 lines =<< trim END
4067 vim9script
4068
4069 class C
4070 public static sval4: number
4071 static def Lock()
4072 lockvar C.sval4
4073 enddef
4074 endclass
4075 C.Lock()
4076 END
4077 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
4078
4079 # lockvar C.static from script level
4080 lines =<< trim END
4081 vim9script
4082
4083 class C
4084 public static sval5: number
4085 endclass
4086 lockvar C.sval5
4087 END
4088 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
4089
4090 # lockvar o.static from script level
4091 lines =<< trim END
4092 vim9script
4093
4094 class C
4095 public static sval6: number
4096 endclass
4097 var o = C.new()
4098 lockvar o.sval6
4099 END
4100 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
4101enddef
4102
4103" Test locking an argument to :def
4104def Test_lockvar_argument()
4105 # Lockvar a function arg
4106 var lines =<< trim END
4107 vim9script
4108
4109 def Lock(val: any)
4110 lockvar val
4111 enddef
4112
4113 var d = {a: 1, b: 2}
4114 Lock(d)
4115
4116 d->extend({c: 3})
4117 END
4118 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
4119
4120 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
4121 # class member in "C". This tests lval_root_is_arg.
4122 lines =<< trim END
4123 vim9script
4124
4125 class C
4126 public static sval: list<number>
4127 endclass
4128
4129 def Lock2(sval: any)
4130 lockvar sval
4131 enddef
4132
4133 var o = C.new()
4134 Lock2(o)
4135 END
4136 v9.CheckSourceSuccess(lines)
4137
4138 # Lock a class.
4139 lines =<< trim END
4140 vim9script
4141
4142 class C
4143 public static sval: list<number>
4144 endclass
4145
4146 def Lock2(sval: any)
4147 lockvar sval
4148 enddef
4149
4150 Lock2(C)
4151 END
Ernie Raelb077b582023-12-14 20:11:44 +01004152 v9.CheckSourceFailure(lines, 'E1405: Class "C" cannot be used as a value')
Ernie Raelee865f32023-09-29 19:53:55 +02004153
4154 # Lock an object.
4155 lines =<< trim END
4156 vim9script
4157
4158 class C
4159 public static sval: list<number>
4160 endclass
4161
4162 def Lock2(sval: any)
4163 lockvar sval
4164 enddef
4165
4166 Lock2(C.new())
4167 END
4168 v9.CheckSourceSuccess(lines)
4169
4170 # In this case (unlike previous) "lockvar sval" is a class member.
4171 lines =<< trim END
4172 vim9script
4173
4174 class C
4175 public static sval: list<number>
4176 def Lock2()
4177 lockvar sval
4178 enddef
4179 endclass
4180
4181
4182 var o = C.new()
4183 o.Lock2()
4184 END
4185 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
4186enddef
4187
4188" Test that this can be locked without error
4189def Test_lockvar_this()
4190 # lockvar this
4191 var lines =<< trim END
4192 vim9script
4193 class C
4194 def TLock()
4195 lockvar this
4196 enddef
4197 endclass
4198 var o = C.new()
4199 o.TLock()
4200 END
4201 v9.CheckSourceSuccess(lines)
4202
4203 # lockvar four (four letter word, but not this)
4204 lines =<< trim END
4205 vim9script
4206 class C
4207 def TLock4()
4208 var four: number
4209 lockvar four
4210 enddef
4211 endclass
4212 var o = C.new()
4213 o.TLock4()
4214 END
4215 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4216
4217 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
4218 lines =<< trim END
4219 vim9script
4220 class C
4221 def TLock5()
4222 var this5: number
4223 lockvar this5
4224 enddef
4225 endclass
4226 var o = C.new()
4227 o.TLock5()
4228 END
4229 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
4230enddef
4231
4232" Test some general lockvar cases
4233def Test_lockvar_general()
4234 # lockvar an object and a class. It does nothing
4235 var lines =<< trim END
4236 vim9script
4237 class C
4238 endclass
4239 var o = C.new()
4240 lockvar o
4241 lockvar C
4242 END
4243 v9.CheckSourceSuccess(lines)
4244
4245 # Lock a list element that's nested in an object variable from a :def
4246 lines =<< trim END
4247 vim9script
4248
4249 class C
4250 public this.val: list<list<number>> = [ [1], [2], [3] ]
4251 endclass
4252 def Lock2(obj: any)
4253 lockvar obj.val[1]
4254 enddef
4255
4256 var o = C.new()
4257 Lock2(o)
4258 o.val[0] = [9]
4259 assert_equal([ [9], [2], [3] ], o.val)
4260 try
4261 o.val[1] = [999]
4262 call assert_false(true, 'assign should have failed')
4263 catch
4264 assert_exception('E741:')
4265 endtry
4266 o.val[2] = [8]
4267 assert_equal([ [9], [2], [8] ], o.val)
4268 END
4269 v9.CheckSourceSuccess(lines)
4270
4271 # Lock a list element that's nested in an object variable from scriptlevel
4272 lines =<< trim END
4273 vim9script
4274
4275 class C
4276 public this.val: list<list<number>> = [ [1], [2], [3] ]
4277 endclass
4278
4279 var o = C.new()
4280 lockvar o.val[1]
4281 o.val[0] = [9]
4282 assert_equal([ [9], [2], [3] ], o.val)
4283 try
4284 o.val[1] = [999]
4285 call assert_false(true, 'assign should have failed')
4286 catch
4287 assert_exception('E741:')
4288 endtry
4289 o.val[2] = [8]
4290 assert_equal([ [9], [2], [8] ], o.val)
4291 END
4292 v9.CheckSourceSuccess(lines)
Ernie Rael64885642023-10-04 20:16:22 +02004293
4294 # lock a script level variable from an object method
4295 lines =<< trim END
4296 vim9script
4297
4298 class C
4299 def Lock()
4300 lockvar l
4301 enddef
4302 endclass
4303
4304 var l = [1]
4305 C.new().Lock()
4306 l[0] = 11
4307 END
4308 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[0] = 11', 11)
4309
Ernie Rael03042a22023-11-11 08:53:32 +01004310 # lock a list element referenced by a protected object variable
Ernie Rael64885642023-10-04 20:16:22 +02004311 # in an object fetched via a script level list
4312 lines =<< trim END
4313 vim9script
4314
4315 class C
4316 this._v1: list<list<number>>
4317 def Lock()
4318 lockvar lc[0]._v1[1]
4319 enddef
4320 endclass
4321
4322 var l = [[1], [2], [3]]
4323 var o = C.new(l)
4324 var lc: list<C> = [ o ]
4325
4326 o.Lock()
4327 l[0] = [22]
4328 l[1] = [33]
4329 END
4330 v9.CheckSourceFailure(lines, 'E741: Value is locked: l[1] = [33]', 16)
4331
4332 # similar to the previous test, except the locking code is executing
Ernie Rael03042a22023-11-11 08:53:32 +01004333 # in a class that does not own the protected variable.
4334 # Note that the locking code is in a class has a protected variable of
Ernie Rael64885642023-10-04 20:16:22 +02004335 # the same name.
4336 lines =<< trim END
4337 vim9script
4338
4339 class C2
4340 this._v1: list<list<number>>
4341 def Lock(obj: any)
4342 lockvar lc[0]._v1[1]
4343 enddef
4344 endclass
4345
4346 class C
4347 this._v1: list<list<number>>
4348 endclass
4349
4350 var l = [[1], [2], [3]]
4351 var o = C.new(l)
4352 var lc: list<C> = [ o ]
4353
4354 var o2 = C2.new()
4355 o2.Lock(o)
4356 END
Ernie Rael03042a22023-11-11 08:53:32 +01004357 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_v1" in class "C"')
Ernie Raelee865f32023-09-29 19:53:55 +02004358enddef
4359
Ernie Rael9771b2a2023-10-07 22:05:40 +02004360" Test builtin islocked()
4361def Test_lockvar_islocked()
4362 # Can't lock class/object variable
4363 # Lock class/object variable's value
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01004364 # Lock item of variable's value (a list item)
4365 # variable is at index 1 within class/object
Ernie Rael9771b2a2023-10-07 22:05:40 +02004366 var lines =<< trim END
4367 vim9script
4368
4369 class C
4370 this.o0: list<list<number>> = [ [0], [1], [2]]
4371 this.o1: list<list<number>> = [[10], [11], [12]]
4372 static c0: list<list<number>> = [[20], [21], [22]]
4373 static c1: list<list<number>> = [[30], [31], [32]]
4374 endclass
4375
4376 def LockIt(arg: any)
4377 lockvar arg
4378 enddef
4379
4380 def UnlockIt(arg: any)
4381 unlockvar arg
4382 enddef
4383
4384 var obj = C.new()
4385 #lockvar obj.o1 # can't lock something you can't write to
4386
4387 try
4388 lockvar obj.o1 # can't lock something you can't write to
4389 call assert_false(1, '"lockvar obj.o1" should have failed')
4390 catch
4391 call assert_exception('E1335:')
4392 endtry
4393
4394 LockIt(obj.o1) # but can lock it's value
4395 assert_equal(1, islocked("obj.o1"))
4396 assert_equal(1, islocked("obj.o1[0]"))
4397 assert_equal(1, islocked("obj.o1[1]"))
4398 UnlockIt(obj.o1)
4399 assert_equal(0, islocked("obj.o1"))
4400 assert_equal(0, islocked("obj.o1[0]"))
4401
4402 lockvar obj.o1[0]
4403 assert_equal(0, islocked("obj.o1"))
4404 assert_equal(1, islocked("obj.o1[0]"))
4405 assert_equal(0, islocked("obj.o1[1]"))
4406 unlockvar obj.o1[0]
4407 assert_equal(0, islocked("obj.o1"))
4408 assert_equal(0, islocked("obj.o1[0]"))
4409
4410 # Same thing, but with a static
4411
4412 try
4413 lockvar C.c1 # can't lock something you can't write to
4414 call assert_false(1, '"lockvar C.c1" should have failed')
4415 catch
4416 call assert_exception('E1335:')
4417 endtry
4418
4419 LockIt(C.c1) # but can lock it's value
4420 assert_equal(1, islocked("C.c1"))
4421 assert_equal(1, islocked("C.c1[0]"))
4422 assert_equal(1, islocked("C.c1[1]"))
4423 UnlockIt(C.c1)
4424 assert_equal(0, islocked("C.c1"))
4425 assert_equal(0, islocked("C.c1[0]"))
4426
4427 lockvar C.c1[0]
4428 assert_equal(0, islocked("C.c1"))
4429 assert_equal(1, islocked("C.c1[0]"))
4430 assert_equal(0, islocked("C.c1[1]"))
4431 unlockvar C.c1[0]
4432 assert_equal(0, islocked("C.c1"))
4433 assert_equal(0, islocked("C.c1[0]"))
4434 END
4435 v9.CheckSourceSuccess(lines)
Ernie Rael4c8da022023-10-11 21:35:11 +02004436
4437 # Do islocked() from an object method
4438 # and then from a class method
Ernie Rael9771b2a2023-10-07 22:05:40 +02004439 lines =<< trim END
Ernie Rael4c8da022023-10-11 21:35:11 +02004440 vim9script
4441
4442 var l0o0 = [ [0], [1], [2]]
4443 var l0o1 = [ [10], [11], [12]]
4444 var l0c0 = [[120], [121], [122]]
4445 var l0c1 = [[130], [131], [132]]
4446
4447 class C0
4448 this.o0: list<list<number>> = l0o0
4449 this.o1: list<list<number>> = l0o1
4450 static c0: list<list<number>> = l0c0
4451 static c1: list<list<number>> = l0c1
4452 def Islocked(arg: string): number
4453 return islocked(arg)
4454 enddef
4455 static def SIslocked(arg: string): number
4456 return islocked(arg)
4457 enddef
4458 endclass
4459
4460 var l2o0 = [[20000], [20001], [20002]]
4461 var l2o1 = [[20010], [20011], [20012]]
4462 var l2c0 = [[20120], [20121], [20122]]
4463 var l2c1 = [[20130], [20131], [20132]]
4464
4465 class C2
4466 this.o0: list<list<number>> = l2o0
4467 this.o1: list<list<number>> = l2o1
4468 static c0: list<list<number>> = l2c0
4469 static c1: list<list<number>> = l2c1
4470 def Islocked(arg: string): number
4471 return islocked(arg)
4472 enddef
4473 static def SIslocked(arg: string): number
4474 return islocked(arg)
4475 enddef
4476 endclass
4477
4478 var obj0 = C0.new()
4479 var obj2 = C2.new()
4480
4481 var l = [ obj0, null_object, obj2 ]
4482
4483 # lock list, object func access through script var expr
4484 assert_equal(0, obj0.Islocked("l[0].o0"))
4485 assert_equal(0, obj0.Islocked("l[0].o0[2]"))
4486 lockvar l0o0
4487 assert_equal(1, obj0.Islocked("l[0].o0"))
4488 assert_equal(1, obj0.Islocked("l[0].o0[2]"))
4489
4490 #echo "check-b" obj2.Islocked("l[1].o1") # NULL OBJECT
4491
4492 # lock list element, object func access through script var expr
4493 lockvar l0o1[1]
4494 assert_equal(0, obj0.Islocked("this.o1[0]"))
4495 assert_equal(1, obj0.Islocked("this.o1[1]"))
4496
4497 assert_equal(0, obj0.Islocked("this.o1"))
4498 lockvar l0o1
4499 assert_equal(1, obj0.Islocked("this.o1"))
4500 unlockvar l0o1
4501
4502 lockvar l0c1[1]
4503
4504 # static by class name member expr from same class
4505 assert_equal(0, obj0.Islocked("C0.c1[0]"))
4506 assert_equal(1, obj0.Islocked("C0.c1[1]"))
4507 # static by bare name member expr from same class
4508 assert_equal(0, obj0.Islocked("c1[0]"))
4509 assert_equal(1, obj0.Islocked("c1[1]"))
4510
4511 # static by class name member expr from other class
4512 assert_equal(0, obj2.Islocked("C0.c1[0]"))
4513 assert_equal(1, obj2.Islocked("C0.c1[1]"))
4514 # static by bare name member expr from other class
4515 assert_equal(0, obj2.Islocked("c1[0]"))
4516 assert_equal(0, obj2.Islocked("c1[1]"))
4517
4518
4519 # static by bare name in same class
4520 assert_equal(0, obj0.Islocked("c0"))
4521 lockvar l0c0
4522 assert_equal(1, obj0.Islocked("c0"))
4523
4524 #
4525 # similar stuff, but use static method
4526 #
4527
4528 unlockvar l0o0
4529
4530 # lock list, object func access through script var expr
4531 assert_equal(0, C0.SIslocked("l[0].o0"))
4532 assert_equal(0, C0.SIslocked("l[0].o0[2]"))
4533 lockvar l0o0
4534 assert_equal(1, C0.SIslocked("l[0].o0"))
4535 assert_equal(1, C0.SIslocked("l[0].o0[2]"))
4536
4537 unlockvar l0o1
4538
4539 # can't access "this" from class method
4540 try
4541 C0.SIslocked("this.o1[0]")
4542 call assert_0(1, '"C0.SIslocked("this.o1[0]")" should have failed')
4543 catch
4544 call assert_exception('E121: Undefined variable: this')
4545 endtry
4546
4547 lockvar l0c1[1]
4548
4549 # static by class name member expr from same class
4550 assert_equal(0, C0.SIslocked("C0.c1[0]"))
4551 assert_equal(1, C0.SIslocked("C0.c1[1]"))
4552 # static by bare name member expr from same class
4553 assert_equal(0, C0.SIslocked("c1[0]"))
4554 assert_equal(1, C0.SIslocked("c1[1]"))
4555
4556 # static by class name member expr from other class
4557 assert_equal(0, C2.SIslocked("C0.c1[0]"))
4558 assert_equal(1, C2.SIslocked("C0.c1[1]"))
4559 # static by bare name member expr from other class
4560 assert_equal(0, C2.SIslocked("c1[0]"))
4561 assert_equal(0, C2.SIslocked("c1[1]"))
4562
4563
4564 # static by bare name in same class
4565 unlockvar l0c0
4566 assert_equal(0, C0.SIslocked("c0"))
4567 lockvar l0c0
4568 assert_equal(1, C0.SIslocked("c0"))
Ernie Rael9771b2a2023-10-07 22:05:40 +02004569 END
Ernie Rael4c8da022023-10-11 21:35:11 +02004570 v9.CheckSourceSuccess(lines)
4571
4572 # Check islocked class/object from various places.
4573 lines =<< trim END
4574 vim9script
4575
4576 class C
4577 def Islocked(arg: string): number
4578 return islocked(arg)
4579 enddef
4580 static def SIslocked(arg: string): number
4581 return islocked(arg)
4582 enddef
4583 endclass
4584 var obj = C.new()
4585
4586 # object method
4587 assert_equal(0, obj.Islocked("this"))
4588 assert_equal(0, obj.Islocked("C"))
4589
4590 # class method
4591 ### assert_equal(0, C.SIslocked("this"))
4592 assert_equal(0, C.SIslocked("C"))
4593
4594 #script level
4595 var v: number
4596 v = islocked("C")
4597 assert_equal(0, v)
4598 v = islocked("obj")
4599 assert_equal(0, v)
4600 END
4601 v9.CheckSourceSuccess(lines)
4602enddef
4603
4604def Test_lockvar_islocked_notfound()
4605 # Try non-existent things
4606 var lines =<< trim END
4607 vim9script
4608
4609 class C
4610 def Islocked(arg: string): number
4611 return islocked(arg)
4612 enddef
4613 static def SIslocked(arg: string): number
4614 return islocked(arg)
4615 enddef
4616 endclass
4617 var obj = C.new()
4618 assert_equal(-1, obj.Islocked("anywhere"))
4619 assert_equal(-1, C.SIslocked("notanywhere"))
4620 END
4621 v9.CheckSourceSuccess(lines)
4622
4623 # Something not found of the form "name1.name2" is an error
4624 lines =<< trim END
4625 vim9script
4626
4627 islocked("one.two")
4628 END
4629 v9.CheckSourceFailure(lines, 'E121: Undefined variable: one')
4630
4631 lines =<< trim END
4632 vim9script
4633
4634 class C
4635 this.val = { key: "value" }
4636 def Islocked(arg: string): number
4637 return islocked(arg)
4638 enddef
4639 endclass
4640 var obj = C.new()
4641 obj.Islocked("this.val.not_there"))
4642 END
4643 v9.CheckSourceFailure(lines, 'E716: Key not present in Dictionary: "not_there"')
4644
4645 lines =<< trim END
4646 vim9script
4647
4648 class C
4649 def Islocked(arg: string): number
4650 return islocked(arg)
4651 enddef
4652 endclass
4653 var obj = C.new()
4654 obj.Islocked("this.notobjmember")
4655 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02004656 v9.CheckSourceFailure(lines, 'E1326: Variable "notobjmember" not found in object "C"')
Ernie Rael4c8da022023-10-11 21:35:11 +02004657
4658 # access a script variable through methods
4659 lines =<< trim END
4660 vim9script
4661
4662 var l = [1]
4663 class C
4664 def Islocked(arg: string): number
4665 return islocked(arg)
4666 enddef
4667 static def SIslocked(arg: string): number
4668 return islocked(arg)
4669 enddef
4670 endclass
4671 var obj = C.new()
4672 assert_equal(0, obj.Islocked("l"))
4673 assert_equal(0, C.SIslocked("l"))
4674 lockvar l
4675 assert_equal(1, obj.Islocked("l"))
4676 assert_equal(1, C.SIslocked("l"))
4677 END
4678 v9.CheckSourceSuccess(lines)
Ernie Rael9771b2a2023-10-07 22:05:40 +02004679enddef
4680
Ernie Rael03042a22023-11-11 08:53:32 +01004681" Test for a protected object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004682def Test_private_object_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004683 # Try calling a protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004684 var lines =<< trim END
4685 vim9script
4686
4687 class A
4688 def _Foo(): number
4689 return 1234
4690 enddef
4691 endclass
4692 var a = A.new()
4693 a._Foo()
4694 END
Ernie Rael03042a22023-11-11 08:53:32 +01004695 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004696
Ernie Rael03042a22023-11-11 08:53:32 +01004697 # Try calling a protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004698 lines =<< trim END
4699 vim9script
4700
4701 class A
4702 def _Foo(): number
4703 return 1234
4704 enddef
4705 endclass
4706 def T()
4707 var a = A.new()
4708 a._Foo()
4709 enddef
4710 T()
4711 END
Ernie Rael03042a22023-11-11 08:53:32 +01004712 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004713
Ernie Rael03042a22023-11-11 08:53:32 +01004714 # Use a protected method from another object method (in script context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004715 lines =<< trim END
4716 vim9script
4717
4718 class A
4719 def _Foo(): number
4720 return 1234
4721 enddef
4722 def Bar(): number
4723 return this._Foo()
4724 enddef
4725 endclass
4726 var a = A.new()
4727 assert_equal(1234, a.Bar())
4728 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004729 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004730
Ernie Rael03042a22023-11-11 08:53:32 +01004731 # Use a protected method from another object method (def function context)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004732 lines =<< trim END
4733 vim9script
4734
4735 class A
4736 def _Foo(): number
4737 return 1234
4738 enddef
4739 def Bar(): number
4740 return this._Foo()
4741 enddef
4742 endclass
4743 def T()
4744 var a = A.new()
4745 assert_equal(1234, a.Bar())
4746 enddef
4747 T()
4748 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004749 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004750
Ernie Rael03042a22023-11-11 08:53:32 +01004751 # Try calling a protected method without the "this" prefix
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004752 lines =<< trim END
4753 vim9script
4754
4755 class A
4756 def _Foo(): number
4757 return 1234
4758 enddef
4759 def Bar(): number
4760 return _Foo()
4761 enddef
4762 endclass
4763 var a = A.new()
4764 a.Bar()
4765 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004766 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004767
Ernie Rael03042a22023-11-11 08:53:32 +01004768 # Try calling a protected method using the class name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004769 lines =<< trim END
4770 vim9script
4771
4772 class A
4773 def _Foo(): number
4774 return 1234
4775 enddef
4776 endclass
4777 A._Foo()
4778 END
Ernie Rael03042a22023-11-11 08:53:32 +01004779 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004780
Ernie Rael03042a22023-11-11 08:53:32 +01004781 # Define two protected methods with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004782 lines =<< trim END
4783 vim9script
4784
4785 class A
4786 def _Foo()
4787 enddef
4788 def _Foo()
4789 enddef
4790 endclass
4791 var a = A.new()
4792 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004793 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004794
Ernie Rael03042a22023-11-11 08:53:32 +01004795 # Define a protected method and a object method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004796 lines =<< trim END
4797 vim9script
4798
4799 class A
4800 def _Foo()
4801 enddef
4802 def Foo()
4803 enddef
4804 endclass
4805 var a = A.new()
4806 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004807 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004808
Ernie Rael03042a22023-11-11 08:53:32 +01004809 # Define an object method and a protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004810 lines =<< trim END
4811 vim9script
4812
4813 class A
4814 def Foo()
4815 enddef
4816 def _Foo()
4817 enddef
4818 endclass
4819 var a = A.new()
4820 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004821 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004822
Ernie Rael03042a22023-11-11 08:53:32 +01004823 # Call a public method and a protected method from a protected method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004824 lines =<< trim END
4825 vim9script
4826
4827 class A
4828 def Foo(): number
4829 return 100
4830 enddef
4831 def _Bar(): number
4832 return 200
4833 enddef
4834 def _Baz()
4835 assert_equal(100, this.Foo())
4836 assert_equal(200, this._Bar())
4837 enddef
4838 def T()
4839 this._Baz()
4840 enddef
4841 endclass
4842 var a = A.new()
4843 a.T()
4844 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004845 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004846
Ernie Rael03042a22023-11-11 08:53:32 +01004847 # Try calling a protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004848 lines =<< trim END
4849 vim9script
4850
4851 class A
4852 def _Foo(): number
4853 return 100
4854 enddef
4855 endclass
4856 class B
4857 def Foo(): number
4858 var a = A.new()
4859 a._Foo()
4860 enddef
4861 endclass
4862 var b = B.new()
4863 b.Foo()
4864 END
Ernie Rael03042a22023-11-11 08:53:32 +01004865 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004866
Ernie Rael03042a22023-11-11 08:53:32 +01004867 # Call a protected object method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004868 lines =<< trim END
4869 vim9script
4870 class A
4871 def _Foo(): number
4872 return 1234
4873 enddef
4874 endclass
4875 class B extends A
4876 def Bar()
4877 enddef
4878 endclass
4879 class C extends B
4880 def Baz(): number
4881 return this._Foo()
4882 enddef
4883 endclass
4884 var c = C.new()
4885 assert_equal(1234, c.Baz())
4886 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004887 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004888
Ernie Rael03042a22023-11-11 08:53:32 +01004889 # Call a protected object method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004890 lines =<< trim END
4891 vim9script
4892 class A
4893 def _Foo(): number
4894 return 1234
4895 enddef
4896 endclass
4897 class B extends A
4898 def Bar()
4899 enddef
4900 endclass
4901 class C extends B
4902 def Baz(): number
4903 enddef
4904 endclass
4905 var c = C.new()
4906 assert_equal(1234, c._Foo())
4907 END
Ernie Rael03042a22023-11-11 08:53:32 +01004908 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004909
4910 # Using "_" prefix in a method name should fail outside of a class
4911 lines =<< trim END
4912 vim9script
4913 def _Foo(): number
4914 return 1234
4915 enddef
4916 var a = _Foo()
4917 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004918 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004919enddef
4920
Ernie Rael03042a22023-11-11 08:53:32 +01004921" Test for an protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004922def Test_private_class_method()
Ernie Rael03042a22023-11-11 08:53:32 +01004923 # Try calling a class protected method (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004924 var lines =<< trim END
4925 vim9script
4926
4927 class A
4928 static def _Foo(): number
4929 return 1234
4930 enddef
4931 endclass
4932 A._Foo()
4933 END
Ernie Rael03042a22023-11-11 08:53:32 +01004934 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004935
Ernie Rael03042a22023-11-11 08:53:32 +01004936 # Try calling a class protected method (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004937 lines =<< trim END
4938 vim9script
4939
4940 class A
4941 static def _Foo(): number
4942 return 1234
4943 enddef
4944 endclass
4945 def T()
4946 A._Foo()
4947 enddef
4948 T()
4949 END
Ernie Rael03042a22023-11-11 08:53:32 +01004950 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004951
Ernie Rael03042a22023-11-11 08:53:32 +01004952 # Try calling a class protected method using an object (at the script level)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004953 lines =<< trim END
4954 vim9script
4955
4956 class A
4957 static def _Foo(): number
4958 return 1234
4959 enddef
4960 endclass
4961 var a = A.new()
4962 a._Foo()
4963 END
Ernie Rael03042a22023-11-11 08:53:32 +01004964 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004965
Ernie Rael03042a22023-11-11 08:53:32 +01004966 # Try calling a class protected method using an object (from a def function)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004967 lines =<< trim END
4968 vim9script
4969
4970 class A
4971 static def _Foo(): number
4972 return 1234
4973 enddef
4974 endclass
4975 def T()
4976 var a = A.new()
4977 a._Foo()
4978 enddef
4979 T()
4980 END
Ernie Rael03042a22023-11-11 08:53:32 +01004981 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004982
Ernie Rael03042a22023-11-11 08:53:32 +01004983 # Use a class protected method from an object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004984 lines =<< trim END
4985 vim9script
4986
4987 class A
4988 static def _Foo(): number
4989 return 1234
4990 enddef
4991 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004992 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004993 enddef
4994 endclass
4995 var a = A.new()
4996 a.Bar()
4997 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004998 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004999
Ernie Rael03042a22023-11-11 08:53:32 +01005000 # Use a class protected method from another class protected method without the
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005001 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005002 lines =<< trim END
5003 vim9script
5004
5005 class A
5006 static def _Foo1(): number
5007 return 1234
5008 enddef
5009 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005010 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005011 enddef
5012 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005013 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005014 enddef
5015 endclass
5016 var a = A.new()
5017 a.Bar()
5018 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005019 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005020
Ernie Rael03042a22023-11-11 08:53:32 +01005021 # Declare a class method and a class protected method with the same name
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005022 lines =<< trim END
5023 vim9script
5024
5025 class A
5026 static def _Foo()
5027 enddef
5028 static def Foo()
5029 enddef
5030 endclass
5031 var a = A.new()
5032 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005033 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005034
Ernie Rael03042a22023-11-11 08:53:32 +01005035 # Try calling a class protected method from another class
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005036 lines =<< trim END
5037 vim9script
5038
5039 class A
5040 static def _Foo(): number
5041 return 1234
5042 enddef
5043 endclass
5044 class B
5045 def Foo(): number
5046 return A._Foo()
5047 enddef
5048 endclass
5049 var b = B.new()
5050 assert_equal(1234, b.Foo())
5051 END
Ernie Rael03042a22023-11-11 08:53:32 +01005052 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005053
Ernie Rael03042a22023-11-11 08:53:32 +01005054 # Call a protected class method from a child class object method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005055 lines =<< trim END
5056 vim9script
5057 class A
5058 static def _Foo(): number
5059 return 1234
5060 enddef
5061 endclass
5062 class B extends A
5063 def Bar()
5064 enddef
5065 endclass
5066 class C extends B
5067 def Baz(): number
5068 return A._Foo()
5069 enddef
5070 endclass
5071 var c = C.new()
5072 assert_equal(1234, c.Baz())
5073 END
Ernie Rael03042a22023-11-11 08:53:32 +01005074 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005075
Ernie Rael03042a22023-11-11 08:53:32 +01005076 # Call a protected class method from a child class protected class method
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005077 lines =<< trim END
5078 vim9script
5079 class A
5080 static def _Foo(): number
5081 return 1234
5082 enddef
5083 endclass
5084 class B extends A
5085 def Bar()
5086 enddef
5087 endclass
5088 class C extends B
5089 static def Baz(): number
5090 return A._Foo()
5091 enddef
5092 endclass
5093 assert_equal(1234, C.Baz())
5094 END
Ernie Rael03042a22023-11-11 08:53:32 +01005095 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005096
Ernie Rael03042a22023-11-11 08:53:32 +01005097 # Call a protected class method from a child class object
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005098 lines =<< trim END
5099 vim9script
5100 class A
5101 static def _Foo(): number
5102 return 1234
5103 enddef
5104 endclass
5105 class B extends A
5106 def Bar()
5107 enddef
5108 endclass
5109 class C extends B
5110 def Baz(): number
5111 enddef
5112 endclass
5113 var c = C.new()
5114 assert_equal(1234, C._Foo())
5115 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005116 v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02005117enddef
5118
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005119" Test for using the return value of a class/object method as a function
5120" argument.
5121def Test_objmethod_funcarg()
5122 var lines =<< trim END
5123 vim9script
5124
5125 class C
5126 def Foo(): string
5127 return 'foo'
5128 enddef
5129 endclass
5130
5131 def Bar(a: number, s: string): string
5132 return s
5133 enddef
5134
5135 def Baz(c: C)
5136 assert_equal('foo', Bar(10, c.Foo()))
5137 enddef
5138
5139 var t = C.new()
5140 Baz(t)
5141 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005142 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005143
5144 lines =<< trim END
5145 vim9script
5146
5147 class C
5148 static def Foo(): string
5149 return 'foo'
5150 enddef
5151 endclass
5152
5153 def Bar(a: number, s: string): string
5154 return s
5155 enddef
5156
5157 def Baz()
5158 assert_equal('foo', Bar(10, C.Foo()))
5159 enddef
5160
5161 Baz()
5162 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005163 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02005164enddef
5165
Ernie Raelcf138d42023-09-06 20:45:03 +02005166def Test_static_inheritence()
5167 # subclasses get their own static copy
5168 var lines =<< trim END
5169 vim9script
5170
5171 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005172 static _svar: number
5173 this._mvar: number
5174 def new()
5175 _svar = 1
5176 this._mvar = 101
5177 enddef
5178 def AccessObject(): number
5179 return this._mvar
5180 enddef
5181 def AccessStaticThroughObject(): number
5182 return _svar
5183 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005184 endclass
5185
5186 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005187 def new()
5188 this._mvar = 102
5189 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005190 endclass
5191
5192 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005193 def new()
5194 this._mvar = 103
5195 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005196
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005197 def AccessPrivateStaticThroughClassName(): number
5198 assert_equal(1, A._svar)
5199 return 444
5200 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02005201 endclass
5202
5203 var oa = A.new()
5204 var ob = B.new()
5205 var oc = C.new()
5206 assert_equal(101, oa.AccessObject())
5207 assert_equal(102, ob.AccessObject())
5208 assert_equal(103, oc.AccessObject())
5209
Ernie Rael03042a22023-11-11 08:53:32 +01005210 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access protected variable "_svar" in class "A"')
Ernie Raelcf138d42023-09-06 20:45:03 +02005211
5212 # verify object properly resolves to correct static
5213 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005214 assert_equal(1, ob.AccessStaticThroughObject())
5215 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02005216 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005217 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02005218enddef
5219
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005220" Test for declaring duplicate object and class members
5221def Test_dup_member_variable()
5222 # Duplicate member variable
5223 var lines =<< trim END
5224 vim9script
5225 class C
5226 this.val = 10
5227 this.val = 20
5228 endclass
5229 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005230 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005231
Ernie Rael03042a22023-11-11 08:53:32 +01005232 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005233 lines =<< trim END
5234 vim9script
5235 class C
5236 this._val = 10
5237 this._val = 20
5238 endclass
5239 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005240 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005241
5242 # Duplicate public member variable
5243 lines =<< trim END
5244 vim9script
5245 class C
5246 public this.val = 10
5247 public this.val = 20
5248 endclass
5249 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005250 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005251
Ernie Rael03042a22023-11-11 08:53:32 +01005252 # Duplicate protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005253 lines =<< trim END
5254 vim9script
5255 class C
5256 this.val = 10
5257 this._val = 20
5258 endclass
5259 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005260 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005261
Ernie Rael03042a22023-11-11 08:53:32 +01005262 # Duplicate public and protected member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005263 lines =<< trim END
5264 vim9script
5265 class C
5266 this._val = 20
5267 public this.val = 10
5268 endclass
5269 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005270 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005271
5272 # Duplicate class member variable
5273 lines =<< trim END
5274 vim9script
5275 class C
5276 static s: string = "abc"
5277 static _s: string = "def"
5278 endclass
5279 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005280 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005281
Ernie Rael03042a22023-11-11 08:53:32 +01005282 # Duplicate public and protected class member variable
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005283 lines =<< trim END
5284 vim9script
5285 class C
5286 public static s: string = "abc"
5287 static _s: string = "def"
5288 endclass
5289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005290 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005291
5292 # Duplicate class and object member variable
5293 lines =<< trim END
5294 vim9script
5295 class C
5296 static val = 10
5297 this.val = 20
5298 def new()
5299 enddef
5300 endclass
5301 var c = C.new()
5302 assert_equal(10, C.val)
5303 assert_equal(20, c.val)
5304 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005305 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005306
5307 # Duplicate object member variable in a derived class
5308 lines =<< trim END
5309 vim9script
5310 class A
5311 this.val = 10
5312 endclass
5313 class B extends A
5314 endclass
5315 class C extends B
5316 this.val = 20
5317 endclass
5318 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005319 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005320
Ernie Rael03042a22023-11-11 08:53:32 +01005321 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005322 lines =<< trim END
5323 vim9script
5324 class A
5325 this._val = 10
5326 endclass
5327 class B extends A
5328 endclass
5329 class C extends B
5330 this._val = 20
5331 endclass
5332 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005333 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005334
Ernie Rael03042a22023-11-11 08:53:32 +01005335 # Duplicate object protected member variable in a derived class
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005336 lines =<< trim END
5337 vim9script
5338 class A
5339 this.val = 10
5340 endclass
5341 class B extends A
5342 endclass
5343 class C extends B
5344 this._val = 20
5345 endclass
5346 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005347 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02005348
5349 # Duplicate object member variable in a derived class
5350 lines =<< trim END
5351 vim9script
5352 class A
5353 this._val = 10
5354 endclass
5355 class B extends A
5356 endclass
5357 class C extends B
5358 this.val = 20
5359 endclass
5360 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005361 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005362
5363 # Two member variables with a common prefix
5364 lines =<< trim END
5365 vim9script
5366 class A
5367 public static svar2: number
5368 public static svar: number
5369 endclass
5370 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005371 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02005372enddef
5373
Ernie Rael03042a22023-11-11 08:53:32 +01005374" Test for accessing a protected member outside a class in a def function
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005375def Test_private_member_access_outside_class()
Ernie Rael03042a22023-11-11 08:53:32 +01005376 # protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005377 var lines =<< trim END
5378 vim9script
5379 class A
5380 this._val = 10
5381 def GetVal(): number
5382 return this._val
5383 enddef
5384 endclass
5385 def T()
5386 var a = A.new()
5387 a._val = 20
5388 enddef
5389 T()
5390 END
Ernie Rael03042a22023-11-11 08:53:32 +01005391 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005392
Ernie Rael03042a22023-11-11 08:53:32 +01005393 # access a non-existing protected object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005394 lines =<< trim END
5395 vim9script
5396 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005397 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005398 endclass
5399 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005400 var a = A.new()
5401 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005402 enddef
5403 T()
5404 END
Ernie Raeld4802ec2023-10-20 11:59:00 +02005405 v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005406
Ernie Rael03042a22023-11-11 08:53:32 +01005407 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005408 lines =<< trim END
5409 vim9script
5410 class A
5411 static _val = 10
5412 endclass
5413 def T()
5414 var a = A.new()
5415 var x = a._val
5416 enddef
5417 T()
5418 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005419 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005420
Ernie Rael03042a22023-11-11 08:53:32 +01005421 # protected static member variable
Ernie Rael18143d32023-09-04 22:30:41 +02005422 lines =<< trim END
5423 vim9script
5424 class A
5425 static _val = 10
5426 endclass
5427 def T()
5428 var a = A.new()
5429 a._val = 3
5430 enddef
5431 T()
5432 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005433 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02005434
Ernie Rael03042a22023-11-11 08:53:32 +01005435 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005436 lines =<< trim END
5437 vim9script
5438 class A
5439 static _val = 10
5440 endclass
5441 def T()
5442 var x = A._val
5443 enddef
5444 T()
5445 END
Ernie Rael03042a22023-11-11 08:53:32 +01005446 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02005447
Ernie Rael03042a22023-11-11 08:53:32 +01005448 # protected static class variable
Ernie Rael18143d32023-09-04 22:30:41 +02005449 lines =<< trim END
5450 vim9script
5451 class A
5452 static _val = 10
5453 endclass
5454 def T()
5455 A._val = 3
5456 enddef
5457 T()
5458 END
Ernie Rael03042a22023-11-11 08:53:32 +01005459 v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005460enddef
5461
5462" Test for changing the member access of an interface in a implementation class
5463def Test_change_interface_member_access()
5464 var lines =<< trim END
5465 vim9script
5466 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005467 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005468 endinterface
5469 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005470 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005471 endclass
5472 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005473 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005474
5475 lines =<< trim END
5476 vim9script
5477 interface A
5478 this.val: number
5479 endinterface
5480 class B implements A
5481 public this.val = 10
5482 endclass
5483 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005484 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02005485enddef
5486
5487" Test for trying to change a readonly member from a def function
5488def Test_readonly_member_change_in_def_func()
5489 var lines =<< trim END
5490 vim9script
5491 class A
5492 this.val: number
5493 endclass
5494 def T()
5495 var a = A.new()
5496 a.val = 20
5497 enddef
5498 T()
5499 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005500 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02005501enddef
5502
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005503" Test for reading and writing a class member from a def function
5504def Test_modify_class_member_from_def_function()
5505 var lines =<< trim END
5506 vim9script
5507 class A
5508 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005509 public static var2: list<number> = [1, 2]
5510 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005511 static _priv_var4: number = 40
5512 endclass
5513 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02005514 assert_equal([1, 2], A.var2)
5515 assert_equal({a: 1, b: 2}, A.var3)
5516 A.var2 = [3, 4]
5517 A.var3 = {c: 3, d: 4}
5518 assert_equal([3, 4], A.var2)
5519 assert_equal({c: 3, d: 4}, A.var3)
Ernie Rael03042a22023-11-11 08:53:32 +01005520 assert_fails('echo A._priv_var4', 'E1333: Cannot access protected variable "_priv_var4" in class "A"')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005521 enddef
5522 T()
5523 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005524 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02005525enddef
5526
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005527" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005528def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005529 var lines =<< trim END
5530 vim9script
5531 class A
5532 public static svar1: list<number> = [1]
5533 public static svar2: list<number> = [2]
5534 endclass
5535
5536 A.svar1->add(3)
5537 A.svar2->add(4)
5538 assert_equal([1, 3], A.svar1)
5539 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005540
5541 def Foo()
5542 A.svar1->add(7)
5543 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005544 assert_equal([1, 3, 7], A.svar1)
5545 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005546 enddef
5547 Foo()
5548 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005549 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005550
5551 # Cannot read from a class variable using an object in script context
5552 lines =<< trim END
5553 vim9script
5554 class A
5555 public this.var1: number
5556 public static svar2: list<number> = [1]
5557 endclass
5558
5559 var a = A.new()
5560 echo a.svar2
5561 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02005562 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005563
5564 # Cannot write to a class variable using an object in script context
5565 lines =<< trim END
5566 vim9script
5567 class A
5568 public this.var1: number
5569 public static svar2: list<number> = [1]
5570 endclass
5571
5572 var a = A.new()
5573 a.svar2 = [2]
5574 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005575 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005576
5577 # Cannot read from a class variable using an object in def method context
5578 lines =<< trim END
5579 vim9script
5580 class A
5581 public this.var1: number
5582 public static svar2: list<number> = [1]
5583 endclass
5584
5585 def T()
5586 var a = A.new()
5587 echo a.svar2
5588 enddef
5589 T()
5590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005591 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02005592
5593 # Cannot write to a class variable using an object in def method context
5594 lines =<< trim END
5595 vim9script
5596 class A
5597 public this.var1: number
5598 public static svar2: list<number> = [1]
5599 endclass
5600
5601 def T()
5602 var a = A.new()
5603 a.svar2 = [2]
5604 enddef
5605 T()
5606 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005607 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02005608enddef
5609
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005610" Test for using a interface method using a child object
5611def Test_interface_method_from_child()
5612 var lines =<< trim END
5613 vim9script
5614
5615 interface A
5616 def Foo(): string
5617 endinterface
5618
5619 class B implements A
5620 def Foo(): string
5621 return 'foo'
5622 enddef
5623 endclass
5624
5625 class C extends B
5626 def Bar(): string
5627 return 'bar'
5628 enddef
5629 endclass
5630
5631 def T1(a: A)
5632 assert_equal('foo', a.Foo())
5633 enddef
5634
5635 def T2(b: B)
5636 assert_equal('foo', b.Foo())
5637 enddef
5638
5639 var c = C.new()
5640 T1(c)
5641 T2(c)
5642 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005643 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005644enddef
5645
5646" Test for using an interface method using a child object when it is overridden
5647" by the child class.
5648" FIXME: This test fails.
5649" def Test_interface_overridden_method_from_child()
5650" var lines =<< trim END
5651" vim9script
5652"
5653" interface A
5654" def Foo(): string
5655" endinterface
5656"
5657" class B implements A
5658" def Foo(): string
5659" return 'b-foo'
5660" enddef
5661" endclass
5662"
5663" class C extends B
5664" def Bar(): string
5665" return 'bar'
5666" enddef
5667" def Foo(): string
5668" return 'c-foo'
5669" enddef
5670" endclass
5671"
5672" def T1(a: A)
5673" assert_equal('c-foo', a.Foo())
5674" enddef
5675"
5676" def T2(b: B)
5677" assert_equal('c-foo', b.Foo())
5678" enddef
5679"
5680" var c = C.new()
5681" T1(c)
5682" T2(c)
5683" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005684" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02005685" enddef
5686
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005687" Test for abstract methods
5688def Test_abstract_method()
5689 # Use two abstract methods
5690 var lines =<< trim END
5691 vim9script
5692 abstract class A
5693 def M1(): number
5694 return 10
5695 enddef
5696 abstract def M2(): number
5697 abstract def M3(): number
5698 endclass
5699 class B extends A
5700 def M2(): number
5701 return 20
5702 enddef
5703 def M3(): number
5704 return 30
5705 enddef
5706 endclass
5707 var b = B.new()
5708 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5709 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005710 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005711
5712 # Don't define an abstract method
5713 lines =<< trim END
5714 vim9script
5715 abstract class A
5716 abstract def Foo()
5717 endclass
5718 class B extends A
5719 endclass
5720 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005721 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005722
5723 # Use abstract method in a concrete class
5724 lines =<< trim END
5725 vim9script
5726 class A
5727 abstract def Foo()
5728 endclass
5729 class B extends A
5730 endclass
5731 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005732 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005733
5734 # Use abstract method in an interface
5735 lines =<< trim END
5736 vim9script
5737 interface A
5738 abstract def Foo()
5739 endinterface
5740 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005741 def Foo()
5742 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005743 endclass
5744 END
Yegappan Lakshmanan2b358ad2023-11-02 20:57:32 +01005745 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5746
5747 # Use abstract static method in an interface
5748 lines =<< trim END
5749 vim9script
5750 interface A
5751 abstract static def Foo()
5752 enddef
5753 endinterface
5754 END
5755 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
5756
5757 # Use abstract static variable in an interface
5758 lines =<< trim END
5759 vim9script
5760 interface A
5761 abstract static foo: number = 10
5762 endinterface
5763 END
5764 v9.CheckSourceFailure(lines, 'E1404: Abstract cannot be used in an interface', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005765
5766 # Abbreviate the "abstract" keyword
5767 lines =<< trim END
5768 vim9script
5769 class A
5770 abs def Foo()
5771 endclass
5772 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005773 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005774
5775 # Use "abstract" with a member variable
5776 lines =<< trim END
5777 vim9script
5778 abstract class A
5779 abstract this.val = 10
5780 endclass
5781 END
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005782 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005783
5784 # Use a static abstract method
Yegappan Lakshmanan5a539252023-11-04 09:42:46 +01005785 lines =<< trim END
5786 vim9script
5787 abstract class A
5788 abstract static def Foo(): number
5789 endclass
5790 END
5791 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005792
5793 # Type mismatch between abstract method and concrete method
5794 lines =<< trim END
5795 vim9script
5796 abstract class A
5797 abstract def Foo(a: string, b: number): list<number>
5798 endclass
5799 class B extends A
5800 def Foo(a: number, b: string): list<string>
5801 return []
5802 enddef
5803 endclass
5804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005805 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 +02005806
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005807 # Invoke an abstract method from a def function
5808 lines =<< trim END
5809 vim9script
5810 abstract class A
5811 abstract def Foo(): list<number>
5812 endclass
5813 class B extends A
5814 def Foo(): list<number>
5815 return [3, 5]
5816 enddef
5817 endclass
5818 def Bar(c: B)
5819 assert_equal([3, 5], c.Foo())
5820 enddef
5821 var b = B.new()
5822 Bar(b)
5823 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005824 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananef9e3f82023-11-02 20:43:57 +01005825
5826 # Use a static method in an abstract class
5827 lines =<< trim END
5828 vim9script
5829 abstract class A
5830 static def Foo(): string
5831 return 'foo'
5832 enddef
5833 endclass
5834 assert_equal('foo', A.Foo())
5835 END
5836 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005837enddef
5838
5839" Test for calling a class method from a subclass
5840def Test_class_method_call_from_subclass()
5841 # class method call from a subclass
5842 var lines =<< trim END
5843 vim9script
5844
5845 class A
5846 static def Foo()
5847 echo "foo"
5848 enddef
5849 endclass
5850
5851 class B extends A
5852 def Bar()
5853 Foo()
5854 enddef
5855 endclass
5856
5857 var b = B.new()
5858 b.Bar()
5859 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005860 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005861enddef
5862
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005863" Test for calling a class method using an object in a def function context and
5864" script context.
5865def Test_class_method_call_using_object()
5866 # script context
5867 var lines =<< trim END
5868 vim9script
5869 class A
5870 static def Foo(): list<string>
5871 return ['a', 'b']
5872 enddef
5873 def Bar()
5874 assert_equal(['a', 'b'], A.Foo())
5875 assert_equal(['a', 'b'], Foo())
5876 enddef
5877 endclass
5878
5879 def T()
5880 assert_equal(['a', 'b'], A.Foo())
5881 var t_a = A.new()
5882 t_a.Bar()
5883 enddef
5884
5885 assert_equal(['a', 'b'], A.Foo())
5886 var a = A.new()
5887 a.Bar()
5888 T()
5889 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005890 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005891
5892 # script context
5893 lines =<< trim END
5894 vim9script
5895 class A
5896 static def Foo(): string
5897 return 'foo'
5898 enddef
5899 endclass
5900
5901 var a = A.new()
5902 assert_equal('foo', a.Foo())
5903 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005904 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005905
5906 # def function context
5907 lines =<< trim END
5908 vim9script
5909 class A
5910 static def Foo(): string
5911 return 'foo'
5912 enddef
5913 endclass
5914
5915 def T()
5916 var a = A.new()
5917 assert_equal('foo', a.Foo())
5918 enddef
5919 T()
5920 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005921 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005922enddef
5923
5924def Test_class_variable()
5925 var lines =<< trim END
5926 vim9script
5927
5928 class A
5929 public static val: number = 10
5930 static def ClassFunc()
5931 assert_equal(10, val)
5932 enddef
5933 def ObjFunc()
5934 assert_equal(10, val)
5935 enddef
5936 endclass
5937
5938 class B extends A
5939 endclass
5940
5941 assert_equal(10, A.val)
5942 A.ClassFunc()
5943 var a = A.new()
5944 a.ObjFunc()
5945 var b = B.new()
5946 b.ObjFunc()
5947
5948 def T1(a1: A)
5949 a1.ObjFunc()
5950 A.ClassFunc()
5951 enddef
5952 T1(b)
5953
5954 A.val = 20
5955 assert_equal(20, A.val)
5956 END
5957 v9.CheckSourceSuccess(lines)
5958
5959 # Modifying a parent class variable from a child class method
5960 lines =<< trim END
5961 vim9script
5962
5963 class A
5964 static val: number = 10
5965 endclass
5966
5967 class B extends A
5968 static def ClassFunc()
5969 val = 20
5970 enddef
5971 endclass
5972 B.ClassFunc()
5973 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005974 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005975
5976 # Reading a parent class variable from a child class method
5977 lines =<< trim END
5978 vim9script
5979
5980 class A
5981 static val: number = 10
5982 endclass
5983
5984 class B extends A
5985 static def ClassFunc()
5986 var i = val
5987 enddef
5988 endclass
5989 B.ClassFunc()
5990 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005991 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005992
5993 # Modifying a parent class variable from a child object method
5994 lines =<< trim END
5995 vim9script
5996
5997 class A
5998 static val: number = 10
5999 endclass
6000
6001 class B extends A
6002 def ObjFunc()
6003 val = 20
6004 enddef
6005 endclass
6006 var b = B.new()
6007 b.ObjFunc()
6008 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006009 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006010
6011 # Reading a parent class variable from a child object method
6012 lines =<< trim END
6013 vim9script
6014
6015 class A
6016 static val: number = 10
6017 endclass
6018
6019 class B extends A
6020 def ObjFunc()
6021 var i = val
6022 enddef
6023 endclass
6024 var b = B.new()
6025 b.ObjFunc()
6026 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006027 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006028
6029 # Modifying a class variable using an object at script level
6030 lines =<< trim END
6031 vim9script
6032
6033 class A
6034 static val: number = 10
6035 endclass
6036 var a = A.new()
6037 a.val = 20
6038 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006039 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006040
6041 # Reading a class variable using an object at script level
6042 lines =<< trim END
6043 vim9script
6044
6045 class A
6046 static val: number = 10
6047 endclass
6048 var a = A.new()
6049 var i = a.val
6050 END
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02006051 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006052
6053 # Modifying a class variable using an object at function level
6054 lines =<< trim END
6055 vim9script
6056
6057 class A
6058 static val: number = 10
6059 endclass
6060
6061 def T()
6062 var a = A.new()
6063 a.val = 20
6064 enddef
6065 T()
6066 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006067 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006068
6069 # Reading a class variable using an object at function level
6070 lines =<< trim END
6071 vim9script
6072
6073 class A
6074 static val: number = 10
6075 endclass
6076 def T()
6077 var a = A.new()
6078 var i = a.val
6079 enddef
6080 T()
6081 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006082 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006083enddef
6084
6085" Test for using a duplicate class method and class variable in a child class
6086def Test_dup_class_member()
6087 # duplicate class variable, class method and overridden object method
6088 var lines =<< trim END
6089 vim9script
6090 class A
6091 static sval = 100
6092 static def Check()
6093 assert_equal(100, sval)
6094 enddef
6095 def GetVal(): number
6096 return sval
6097 enddef
6098 endclass
6099
6100 class B extends A
6101 static sval = 200
6102 static def Check()
6103 assert_equal(200, sval)
6104 enddef
6105 def GetVal(): number
6106 return sval
6107 enddef
6108 endclass
6109
6110 def T1(aa: A): number
6111 return aa.GetVal()
6112 enddef
6113
6114 def T2(bb: B): number
6115 return bb.GetVal()
6116 enddef
6117
6118 assert_equal(100, A.sval)
6119 assert_equal(200, B.sval)
6120 var a = A.new()
6121 assert_equal(100, a.GetVal())
6122 var b = B.new()
6123 assert_equal(200, b.GetVal())
6124 assert_equal(200, T1(b))
6125 assert_equal(200, T2(b))
6126 END
6127 v9.CheckSourceSuccess(lines)
6128
6129 # duplicate class variable and class method
6130 lines =<< trim END
6131 vim9script
6132 class A
6133 static sval = 100
6134 static def Check()
6135 assert_equal(100, sval)
6136 enddef
6137 def GetVal(): number
6138 return sval
6139 enddef
6140 endclass
6141
6142 class B extends A
6143 static sval = 200
6144 static def Check()
6145 assert_equal(200, sval)
6146 enddef
6147 endclass
6148
6149 def T1(aa: A): number
6150 return aa.GetVal()
6151 enddef
6152
6153 def T2(bb: B): number
6154 return bb.GetVal()
6155 enddef
6156
6157 assert_equal(100, A.sval)
6158 assert_equal(200, B.sval)
6159 var a = A.new()
6160 assert_equal(100, a.GetVal())
6161 var b = B.new()
6162 assert_equal(100, b.GetVal())
6163 assert_equal(100, T1(b))
6164 assert_equal(100, T2(b))
6165 END
6166 v9.CheckSourceSuccess(lines)
6167enddef
6168
6169" Test for calling an instance method using the class
6170def Test_instance_method_call_using_class()
6171 # Invoke an object method using a class in script context
6172 var lines =<< trim END
6173 vim9script
6174 class A
6175 def Foo()
6176 echo "foo"
6177 enddef
6178 endclass
6179 A.Foo()
6180 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006181 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006182
6183 # Invoke an object method using a class in def function context
6184 lines =<< trim END
6185 vim9script
6186 class A
6187 def Foo()
6188 echo "foo"
6189 enddef
6190 endclass
6191 def T()
6192 A.Foo()
6193 enddef
6194 T()
6195 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006196 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006197enddef
6198
6199" Test for duplicate class method and instance method
6200def Test_dup_classmethod_objmethod()
6201 # Duplicate instance method
6202 var lines =<< trim END
6203 vim9script
6204 class A
6205 static def Foo()
6206 enddef
6207 def Foo()
6208 enddef
6209 endclass
6210 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006211 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006212
Ernie Rael03042a22023-11-11 08:53:32 +01006213 # Duplicate protected instance method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006214 lines =<< trim END
6215 vim9script
6216 class A
6217 static def Foo()
6218 enddef
6219 def _Foo()
6220 enddef
6221 endclass
6222 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006223 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006224
6225 # Duplicate class method
6226 lines =<< trim END
6227 vim9script
6228 class A
6229 def Foo()
6230 enddef
6231 static def Foo()
6232 enddef
6233 endclass
6234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006235 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006236
Ernie Rael03042a22023-11-11 08:53:32 +01006237 # Duplicate protected class method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006238 lines =<< trim END
6239 vim9script
6240 class A
6241 def Foo()
6242 enddef
6243 static def _Foo()
6244 enddef
6245 endclass
6246 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006247 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006248
Ernie Rael03042a22023-11-11 08:53:32 +01006249 # Duplicate protected class and object method
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006250 lines =<< trim END
6251 vim9script
6252 class A
6253 def _Foo()
6254 enddef
6255 static def _Foo()
6256 enddef
6257 endclass
6258 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006259 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006260enddef
6261
6262" Test for an instance method access level comparison with parent instance
6263" methods.
6264def Test_instance_method_access_level()
Ernie Rael03042a22023-11-11 08:53:32 +01006265 # protected method in subclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006266 var lines =<< trim END
6267 vim9script
6268 class A
6269 def Foo()
6270 enddef
6271 endclass
6272 class B extends A
6273 endclass
6274 class C extends B
6275 def _Foo()
6276 enddef
6277 endclass
6278 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006279 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006280
6281 # Public method in subclass
6282 lines =<< trim END
6283 vim9script
6284 class A
6285 def _Foo()
6286 enddef
6287 endclass
6288 class B extends A
6289 endclass
6290 class C extends B
6291 def Foo()
6292 enddef
6293 endclass
6294 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006295 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02006296enddef
6297
6298def Test_extend_empty_class()
6299 var lines =<< trim END
6300 vim9script
6301 class A
6302 endclass
6303 class B extends A
6304 endclass
6305 class C extends B
6306 public static rw_class_var = 1
6307 public this.rw_obj_var = 2
6308 static def ClassMethod(): number
6309 return 3
6310 enddef
6311 def ObjMethod(): number
6312 return 4
6313 enddef
6314 endclass
6315 assert_equal(1, C.rw_class_var)
6316 assert_equal(3, C.ClassMethod())
6317 var c = C.new()
6318 assert_equal(2, c.rw_obj_var)
6319 assert_equal(4, c.ObjMethod())
6320 END
6321 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02006322enddef
6323
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006324" A interface cannot have a static variable or a static method or a private
Ernie Rael03042a22023-11-11 08:53:32 +01006325" variable or a protected method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006326def Test_interface_with_unsupported_members()
6327 var lines =<< trim END
6328 vim9script
6329 interface A
6330 static num: number
6331 endinterface
6332 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006333 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006334
6335 lines =<< trim END
6336 vim9script
6337 interface A
6338 static _num: number
6339 endinterface
6340 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006341 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006342
6343 lines =<< trim END
6344 vim9script
6345 interface A
6346 public static num: number
6347 endinterface
6348 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006349 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006350
6351 lines =<< trim END
6352 vim9script
6353 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006354 public static num: number
6355 endinterface
6356 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006357 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006358
6359 lines =<< trim END
6360 vim9script
6361 interface A
6362 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006363 endinterface
6364 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006365 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006366
6367 lines =<< trim END
6368 vim9script
6369 interface A
6370 static def Foo(d: dict<any>): list<string>
6371 endinterface
6372 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006373 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006374
6375 lines =<< trim END
6376 vim9script
6377 interface A
6378 static def _Foo(d: dict<any>): list<string>
6379 endinterface
6380 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006381 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006382
6383 lines =<< trim END
6384 vim9script
6385 interface A
6386 this._Foo: list<string>
6387 endinterface
6388 END
Ernie Rael03042a22023-11-11 08:53:32 +01006389 v9.CheckSourceFailure(lines, 'E1379: Protected variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006390
6391 lines =<< trim END
6392 vim9script
6393 interface A
6394 def _Foo(d: dict<any>): list<string>
6395 endinterface
6396 END
Ernie Rael03042a22023-11-11 08:53:32 +01006397 v9.CheckSourceFailure(lines, 'E1380: Protected method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006398enddef
6399
6400" Test for extending an interface
6401def Test_extend_interface()
6402 var lines =<< trim END
6403 vim9script
6404 interface A
6405 this.var1: list<string>
6406 def Foo()
6407 endinterface
6408 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006409 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006410 def Bar()
6411 endinterface
6412 class C implements A, B
6413 this.var1 = [1, 2]
6414 def Foo()
6415 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006416 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006417 def Bar()
6418 enddef
6419 endclass
6420 END
6421 v9.CheckSourceSuccess(lines)
6422
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02006423 # extending empty interface
6424 lines =<< trim END
6425 vim9script
6426 interface A
6427 endinterface
6428 interface B extends A
6429 endinterface
6430 class C implements B
6431 endclass
6432 END
6433 v9.CheckSourceSuccess(lines)
6434
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006435 lines =<< trim END
6436 vim9script
6437 interface A
6438 def Foo()
6439 endinterface
6440 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006441 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006442 endinterface
6443 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006444 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006445 endclass
6446 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006447 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006448
6449 lines =<< trim END
6450 vim9script
6451 interface A
6452 def Foo()
6453 endinterface
6454 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02006455 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006456 endinterface
6457 class C implements A, B
6458 def Foo()
6459 enddef
6460 endclass
6461 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006462 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006463
6464 # interface cannot extend a class
6465 lines =<< trim END
6466 vim9script
6467 class A
6468 endclass
6469 interface B extends A
6470 endinterface
6471 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006472 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006473
6474 # class cannot extend an interface
6475 lines =<< trim END
6476 vim9script
6477 interface A
6478 endinterface
6479 class B extends A
6480 endclass
6481 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006482 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006483
6484 # interface cannot implement another interface
6485 lines =<< trim END
6486 vim9script
6487 interface A
6488 endinterface
6489 interface B implements A
6490 endinterface
6491 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006492 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006493
6494 # interface cannot extend multiple interfaces
6495 lines =<< trim END
6496 vim9script
6497 interface A
6498 endinterface
6499 interface B
6500 endinterface
6501 interface C extends A, B
6502 endinterface
6503 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006504 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006505
6506 # Variable type in an extended interface is of different type
6507 lines =<< trim END
6508 vim9script
6509 interface A
6510 this.val1: number
6511 endinterface
6512 interface B extends A
6513 this.val2: string
6514 endinterface
6515 interface C extends B
6516 this.val1: string
6517 this.val2: number
6518 endinterface
6519 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006520 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006521enddef
6522
6523" Test for a child class implementing an interface when some of the methods are
6524" defined in the parent class.
6525def Test_child_class_implements_interface()
6526 var lines =<< trim END
6527 vim9script
6528
6529 interface Intf
6530 def F1(): list<list<number>>
6531 def F2(): list<list<number>>
6532 def F3(): list<list<number>>
6533 this.var1: list<dict<number>>
6534 this.var2: list<dict<number>>
6535 this.var3: list<dict<number>>
6536 endinterface
6537
6538 class A
6539 def A1()
6540 enddef
6541 def F3(): list<list<number>>
6542 return [[3]]
6543 enddef
6544 this.v1: list<list<number>> = [[0]]
6545 this.var3 = [{c: 30}]
6546 endclass
6547
6548 class B extends A
6549 def B1()
6550 enddef
6551 def F2(): list<list<number>>
6552 return [[2]]
6553 enddef
6554 this.v2: list<list<number>> = [[0]]
6555 this.var2 = [{b: 20}]
6556 endclass
6557
6558 class C extends B implements Intf
6559 def C1()
6560 enddef
6561 def F1(): list<list<number>>
6562 return [[1]]
6563 enddef
6564 this.v3: list<list<number>> = [[0]]
6565 this.var1 = [{a: 10}]
6566 endclass
6567
6568 def T(if: Intf)
6569 assert_equal([[1]], if.F1())
6570 assert_equal([[2]], if.F2())
6571 assert_equal([[3]], if.F3())
6572 assert_equal([{a: 10}], if.var1)
6573 assert_equal([{b: 20}], if.var2)
6574 assert_equal([{c: 30}], if.var3)
6575 enddef
6576
6577 var c = C.new()
6578 T(c)
6579 assert_equal([[1]], c.F1())
6580 assert_equal([[2]], c.F2())
6581 assert_equal([[3]], c.F3())
6582 assert_equal([{a: 10}], c.var1)
6583 assert_equal([{b: 20}], c.var2)
6584 assert_equal([{c: 30}], c.var3)
6585 END
6586 v9.CheckSourceSuccess(lines)
6587
6588 # One of the interface methods is not found
6589 lines =<< trim END
6590 vim9script
6591
6592 interface Intf
6593 def F1()
6594 def F2()
6595 def F3()
6596 endinterface
6597
6598 class A
6599 def A1()
6600 enddef
6601 endclass
6602
6603 class B extends A
6604 def B1()
6605 enddef
6606 def F2()
6607 enddef
6608 endclass
6609
6610 class C extends B implements Intf
6611 def C1()
6612 enddef
6613 def F1()
6614 enddef
6615 endclass
6616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006617 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006618
6619 # One of the interface methods is of different type
6620 lines =<< trim END
6621 vim9script
6622
6623 interface Intf
6624 def F1()
6625 def F2()
6626 def F3()
6627 endinterface
6628
6629 class A
6630 def F3(): number
6631 return 0
6632 enddef
6633 def A1()
6634 enddef
6635 endclass
6636
6637 class B extends A
6638 def B1()
6639 enddef
6640 def F2()
6641 enddef
6642 endclass
6643
6644 class C extends B implements Intf
6645 def C1()
6646 enddef
6647 def F1()
6648 enddef
6649 endclass
6650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006651 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006652
6653 # One of the interface variables is not present
6654 lines =<< trim END
6655 vim9script
6656
6657 interface Intf
6658 this.var1: list<dict<number>>
6659 this.var2: list<dict<number>>
6660 this.var3: list<dict<number>>
6661 endinterface
6662
6663 class A
6664 this.v1: list<list<number>> = [[0]]
6665 endclass
6666
6667 class B extends A
6668 this.v2: list<list<number>> = [[0]]
6669 this.var2 = [{b: 20}]
6670 endclass
6671
6672 class C extends B implements Intf
6673 this.v3: list<list<number>> = [[0]]
6674 this.var1 = [{a: 10}]
6675 endclass
6676 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006677 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006678
6679 # One of the interface variables is of different type
6680 lines =<< trim END
6681 vim9script
6682
6683 interface Intf
6684 this.var1: list<dict<number>>
6685 this.var2: list<dict<number>>
6686 this.var3: list<dict<number>>
6687 endinterface
6688
6689 class A
6690 this.v1: list<list<number>> = [[0]]
6691 this.var3: list<dict<string>>
6692 endclass
6693
6694 class B extends A
6695 this.v2: list<list<number>> = [[0]]
6696 this.var2 = [{b: 20}]
6697 endclass
6698
6699 class C extends B implements Intf
6700 this.v3: list<list<number>> = [[0]]
6701 this.var1 = [{a: 10}]
6702 endclass
6703 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006704 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 +02006705enddef
6706
6707" Test for extending an interface with duplicate variables and methods
6708def Test_interface_extends_with_dup_members()
6709 var lines =<< trim END
6710 vim9script
6711 interface A
6712 this.n1: number
6713 def Foo1(): number
6714 endinterface
6715 interface B extends A
6716 this.n2: number
6717 this.n1: number
6718 def Foo2(): number
6719 def Foo1(): number
6720 endinterface
6721 class C implements B
6722 this.n1 = 10
6723 this.n2 = 20
6724 def Foo1(): number
6725 return 30
6726 enddef
6727 def Foo2(): number
6728 return 40
6729 enddef
6730 endclass
6731 def T1(a: A)
6732 assert_equal(10, a.n1)
6733 assert_equal(30, a.Foo1())
6734 enddef
6735 def T2(b: B)
6736 assert_equal(10, b.n1)
6737 assert_equal(20, b.n2)
6738 assert_equal(30, b.Foo1())
6739 assert_equal(40, b.Foo2())
6740 enddef
6741 var c = C.new()
6742 T1(c)
6743 T2(c)
6744 END
6745 v9.CheckSourceSuccess(lines)
6746enddef
6747
6748" Test for using "any" type for a variable in a sub-class while it has a
6749" concrete type in the interface
6750def Test_implements_using_var_type_any()
6751 var lines =<< trim END
6752 vim9script
6753 interface A
6754 this.val: list<dict<string>>
6755 endinterface
6756 class B implements A
6757 this.val = [{a: '1'}, {b: '2'}]
6758 endclass
6759 var b = B.new()
6760 assert_equal([{a: '1'}, {b: '2'}], b.val)
6761 END
6762 v9.CheckSourceSuccess(lines)
6763
6764 # initialize instance variable using a different type
6765 lines =<< trim END
6766 vim9script
6767 interface A
6768 this.val: list<dict<string>>
6769 endinterface
6770 class B implements A
6771 this.val = {a: 1, b: 2}
6772 endclass
6773 var b = B.new()
6774 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006775 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006776enddef
6777
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006778" Test for assigning to a member variable in a nested class
6779def Test_nested_object_assignment()
6780 var lines =<< trim END
6781 vim9script
6782
6783 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006784 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006785 endclass
6786
6787 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006788 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006789 endclass
6790
6791 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006792 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006793 endclass
6794
6795 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006796 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006797 endclass
6798
6799 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006800 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006801 enddef
6802
6803 var d = D.new()
6804 T(d)
6805 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006806 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006807enddef
6808
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006809" Test for calling methods using a null object
6810def Test_null_object_method_call()
6811 # Calling a object method using a null object in script context
6812 var lines =<< trim END
6813 vim9script
6814
6815 class C
6816 def Foo()
6817 assert_report('This method should not be executed')
6818 enddef
6819 endclass
6820
6821 var o: C
6822 o.Foo()
6823 END
6824 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6825
6826 # Calling a object method using a null object in def function context
6827 lines =<< trim END
6828 vim9script
6829
6830 class C
6831 def Foo()
6832 assert_report('This method should not be executed')
6833 enddef
6834 endclass
6835
6836 def T()
6837 var o: C
6838 o.Foo()
6839 enddef
6840 T()
6841 END
6842 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6843
6844 # Calling a object method through another class method using a null object in
6845 # script context
6846 lines =<< trim END
6847 vim9script
6848
6849 class C
6850 def Foo()
6851 assert_report('This method should not be executed')
6852 enddef
6853
6854 static def Bar(o_any: any)
6855 var o_typed: C = o_any
6856 o_typed.Foo()
6857 enddef
6858 endclass
6859
6860 var o: C
6861 C.Bar(o)
6862 END
6863 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6864
6865 # Calling a object method through another class method using a null object in
6866 # def function context
6867 lines =<< trim END
6868 vim9script
6869
6870 class C
6871 def Foo()
6872 assert_report('This method should not be executed')
6873 enddef
6874
6875 static def Bar(o_any: any)
6876 var o_typed: C = o_any
6877 o_typed.Foo()
6878 enddef
6879 endclass
6880
6881 def T()
6882 var o: C
6883 C.Bar(o)
6884 enddef
6885 T()
6886 END
6887 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6888enddef
6889
6890" Test for using a dict as an object member
6891def Test_dict_object_member()
6892 var lines =<< trim END
6893 vim9script
6894
6895 class Context
6896 public this.state: dict<number> = {}
6897 def GetState(): dict<number>
6898 return this.state
6899 enddef
6900 endclass
6901
6902 var ctx = Context.new()
6903 ctx.state->extend({a: 1})
6904 ctx.state['b'] = 2
6905 assert_equal({a: 1, b: 2}, ctx.GetState())
6906
6907 def F()
6908 ctx.state['c'] = 3
6909 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6910 enddef
6911 F()
6912 assert_equal(3, ctx.state.c)
6913 ctx.state.c = 4
6914 assert_equal(4, ctx.state.c)
6915 END
6916 v9.CheckSourceSuccess(lines)
6917enddef
6918
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006919" The following test was failing after 9.0.1914. This was caused by using a
6920" freed object from a previous method call.
6921def Test_freed_object_from_previous_method_call()
6922 var lines =<< trim END
6923 vim9script
6924
6925 class Context
6926 endclass
6927
6928 class Result
6929 endclass
6930
6931 def Failure(): Result
6932 return Result.new()
6933 enddef
6934
6935 def GetResult(ctx: Context): Result
6936 return Failure()
6937 enddef
6938
6939 def Test_GetResult()
6940 var ctx = Context.new()
6941 var result = GetResult(ctx)
6942 enddef
6943
6944 Test_GetResult()
6945 END
6946 v9.CheckSourceSuccess(lines)
6947enddef
6948
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006949" Test for duplicate object and class variable
6950def Test_duplicate_variable()
6951 # Object variable name is same as the class variable name
6952 var lines =<< trim END
6953 vim9script
6954 class A
6955 public static sval: number
6956 public this.sval: number
6957 endclass
6958 var a = A.new()
6959 END
6960 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6961
6962 # Duplicate variable name and calling a class method
6963 lines =<< trim END
6964 vim9script
6965 class A
6966 public static sval: number
6967 public this.sval: number
6968 def F1()
6969 echo this.sval
6970 enddef
6971 static def F2()
6972 echo sval
6973 enddef
6974 endclass
6975 A.F2()
6976 END
6977 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6978
6979 # Duplicate variable with an empty constructor
6980 lines =<< trim END
6981 vim9script
6982 class A
6983 public static sval: number
6984 public this.sval: number
6985 def new()
6986 enddef
6987 endclass
6988 var a = A.new()
6989 END
6990 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6991enddef
6992
6993" Test for using a reserved keyword as a variable name
6994def Test_reserved_varname()
6995 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6996 'null_function', 'null_list', 'null_partial', 'null_string',
6997 'null_channel', 'null_job', 'super', 'this']
6998
6999 var lines =<< trim eval END
7000 vim9script
7001 class C
7002 public this.{kword}: list<number> = [1, 2, 3]
7003 endclass
7004 var o = C.new()
7005 END
7006 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7007
7008 lines =<< trim eval END
7009 vim9script
7010 class C
7011 public this.{kword}: list<number> = [1, 2, 3]
7012 def new()
7013 enddef
7014 endclass
7015 var o = C.new()
7016 END
7017 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7018
7019 lines =<< trim eval END
7020 vim9script
7021 class C
7022 public this.{kword}: list<number> = [1, 2, 3]
7023 def new()
7024 enddef
7025 def F()
7026 echo this.{kword}
7027 enddef
7028 endclass
7029 var o = C.new()
7030 o.F()
7031 END
7032 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
Yegappan Lakshmananb8523052023-10-08 19:07:39 +02007033
7034 # class variable name
7035 if kword != 'this'
7036 lines =<< trim eval END
7037 vim9script
7038 class C
7039 public static {kword}: list<number> = [1, 2, 3]
7040 endclass
7041 END
7042 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
7043 endif
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02007044 endfor
7045enddef
7046
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007047" Test for checking the type of the arguments and the return value of a object
7048" method in an extended class.
7049def Test_extended_obj_method_type_check()
7050 var lines =<< trim END
7051 vim9script
7052
7053 class A
7054 endclass
7055 class B extends A
7056 endclass
7057 class C extends B
7058 endclass
7059
7060 class Foo
7061 def Doit(p: B): B
7062 return B.new()
7063 enddef
7064 endclass
7065
7066 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007067 def Doit(p: C): B
7068 return B.new()
7069 enddef
7070 endclass
7071 END
7072 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
7073
7074 lines =<< trim END
7075 vim9script
7076
7077 class A
7078 endclass
7079 class B extends A
7080 endclass
7081 class C extends B
7082 endclass
7083
7084 class Foo
7085 def Doit(p: B): B
7086 return B.new()
7087 enddef
7088 endclass
7089
7090 class Bar extends Foo
7091 def Doit(p: B): C
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007092 return C.new()
7093 enddef
7094 endclass
7095 END
7096 v9.CheckSourceSuccess(lines)
7097
7098 lines =<< trim END
7099 vim9script
7100
7101 class A
7102 endclass
7103 class B extends A
7104 endclass
7105 class C extends B
7106 endclass
7107
7108 class Foo
7109 def Doit(p: B): B
7110 return B.new()
7111 enddef
7112 endclass
7113
7114 class Bar extends Foo
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007115 def Doit(p: A): B
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02007116 return B.new()
7117 enddef
7118 endclass
7119 END
Yegappan Lakshmananb32064f2023-10-02 21:43:58 +02007120 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 +02007121
7122 lines =<< trim END
7123 vim9script
7124
7125 class A
7126 endclass
7127 class B extends A
7128 endclass
7129 class C extends B
7130 endclass
7131
7132 class Foo
7133 def Doit(p: B): B
7134 return B.new()
7135 enddef
7136 endclass
7137
7138 class Bar extends Foo
7139 def Doit(p: B): A
7140 return A.new()
7141 enddef
7142 endclass
7143 END
7144 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 +02007145
7146 # check varargs type mismatch
7147 lines =<< trim END
7148 vim9script
7149
7150 class B
7151 def F(...xxx: list<any>)
7152 enddef
7153 endclass
7154 class C extends B
7155 def F(xxx: list<any>)
7156 enddef
7157 endclass
7158 END
7159 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 +02007160enddef
7161
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007162" Test type checking for class variable in assignments
7163func Test_class_variable_complex_type_check()
7164 " class variable with a specific type. Try assigning a different type at
7165 " script level.
7166 let lines =<< trim END
7167 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007168 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007169 return {}
7170 enddef
7171 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007172 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007173 endclass
7174 test_garbagecollect_now()
7175 A.Fn = "abc"
7176 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007177 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 +02007178
7179 " class variable with a specific type. Try assigning a different type at
7180 " class def method level.
7181 let lines =<< trim END
7182 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007183 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007184 return {}
7185 enddef
7186 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007187 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007188 def Bar()
7189 Fn = "abc"
7190 enddef
7191 endclass
7192 var a = A.new()
7193 test_garbagecollect_now()
7194 a.Bar()
7195 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007196 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 +02007197
7198 " class variable with a specific type. Try assigning a different type at
7199 " script def method level.
7200 let lines =<< trim END
7201 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007202 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007203 return {}
7204 enddef
7205 class A
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007206 public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007207 endclass
7208 def Bar()
7209 A.Fn = "abc"
7210 enddef
7211 test_garbagecollect_now()
7212 Bar()
7213 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007214 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 +02007215
7216 " class variable without any type. Should be set to the initialization
7217 " expression type. Try assigning a different type from script level.
7218 let lines =<< trim END
7219 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007220 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007221 return {}
7222 enddef
7223 class A
7224 public static Fn = Foo
7225 endclass
7226 test_garbagecollect_now()
7227 A.Fn = "abc"
7228 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007229 call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007230
7231 " class variable without any type. Should be set to the initialization
7232 " expression type. Try assigning a different type at class def level.
7233 let lines =<< trim END
7234 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007235 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007236 return {}
7237 enddef
7238 class A
7239 public static Fn = Foo
7240 def Bar()
7241 Fn = "abc"
7242 enddef
7243 endclass
7244 var a = A.new()
7245 test_garbagecollect_now()
7246 a.Bar()
7247 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007248 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 +02007249
7250 " class variable without any type. Should be set to the initialization
7251 " expression type. Try assigning a different type at script def level.
7252 let lines =<< trim END
7253 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007254 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007255 return {}
7256 enddef
7257 class A
7258 public static Fn = Foo
7259 endclass
7260 def Bar()
7261 A.Fn = "abc"
7262 enddef
7263 test_garbagecollect_now()
7264 Bar()
7265 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007266 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 +02007267
7268 " class variable with 'any" type. Can be assigned different types.
7269 let lines =<< trim END
7270 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007271 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007272 return {}
7273 enddef
7274 class A
7275 public static Fn: any = Foo
7276 public static Fn2: any
7277 endclass
7278 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007279 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007280 A.Fn = "abc"
7281 test_garbagecollect_now()
7282 assert_equal('string', typename(A.Fn))
7283 A.Fn2 = Foo
7284 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007285 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007286 A.Fn2 = "xyz"
7287 test_garbagecollect_now()
7288 assert_equal('string', typename(A.Fn2))
7289 END
7290 call v9.CheckSourceSuccess(lines)
7291
7292 " class variable with 'any" type. Can be assigned different types.
7293 let lines =<< trim END
7294 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007295 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007296 return {}
7297 enddef
7298 class A
7299 public static Fn: any = Foo
7300 public static Fn2: any
7301
7302 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007303 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007304 Fn = "abc"
7305 assert_equal('string', typename(Fn))
7306 Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007307 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007308 Fn2 = "xyz"
7309 assert_equal('string', typename(Fn2))
7310 enddef
7311 endclass
7312 var a = A.new()
7313 test_garbagecollect_now()
7314 a.Bar()
7315 test_garbagecollect_now()
7316 A.Fn = Foo
7317 a.Bar()
7318 END
7319 call v9.CheckSourceSuccess(lines)
7320
7321 " class variable with 'any" type. Can be assigned different types.
7322 let lines =<< trim END
7323 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007324 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007325 return {}
7326 enddef
7327 class A
7328 public static Fn: any = Foo
7329 public static Fn2: any
7330 endclass
7331
7332 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007333 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007334 A.Fn = "abc"
7335 assert_equal('string', typename(A.Fn))
7336 A.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007337 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007338 A.Fn2 = "xyz"
7339 assert_equal('string', typename(A.Fn2))
7340 enddef
7341 Bar()
7342 test_garbagecollect_now()
7343 A.Fn = Foo
7344 Bar()
7345 END
7346 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007347
7348 let lines =<< trim END
7349 vim9script
7350 class A
7351 public static foo = [0z10, 0z20]
7352 endclass
7353 assert_equal([0z10, 0z20], A.foo)
7354 A.foo = [0z30]
7355 assert_equal([0z30], A.foo)
7356 var a = A.foo
7357 assert_equal([0z30], a)
7358 END
7359 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007360endfunc
7361
7362" Test type checking for object variable in assignments
7363func Test_object_variable_complex_type_check()
7364 " object variable with a specific type. Try assigning a different type at
7365 " 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
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007372 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007373 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 with a specific type. Try assigning a different type at
7381 " object def method 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
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007388 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007389 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 with a specific type. Try assigning a different type at
7401 " script def method 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
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007408 public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007409 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 without any type. Should be set to the initialization
7421 " expression type. Try assigning a different type from script level.
7422 let lines =<< trim END
7423 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007424 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007425 return {}
7426 enddef
7427 class A
7428 public this.Fn = Foo
7429 endclass
7430 var a = A.new()
7431 test_garbagecollect_now()
7432 a.Fn = "abc"
7433 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007434 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 +02007435
7436 " object variable without any type. Should be set to the initialization
7437 " expression type. Try assigning a different type at object def level.
7438 let lines =<< trim END
7439 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007440 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007441 return {}
7442 enddef
7443 class A
7444 public this.Fn = Foo
7445 def Bar()
7446 this.Fn = "abc"
7447 this.Fn = Foo
7448 enddef
7449 endclass
7450 var a = A.new()
7451 test_garbagecollect_now()
7452 a.Bar()
7453 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007454 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 +02007455
7456 " object variable without any type. Should be set to the initialization
7457 " expression type. Try assigning a different type at script def level.
7458 let lines =<< trim END
7459 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007460 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007461 return {}
7462 enddef
7463 class A
7464 public this.Fn = Foo
7465 endclass
7466 def Bar()
7467 var a = A.new()
7468 a.Fn = "abc"
7469 a.Fn = Foo
7470 enddef
7471 test_garbagecollect_now()
7472 Bar()
7473 END
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007474 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 +02007475
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 var a = A.new()
7488 test_garbagecollect_now()
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 test_garbagecollect_now()
7492 assert_equal('string', typename(a.Fn))
7493 a.Fn2 = Foo
7494 test_garbagecollect_now()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007495 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007496 a.Fn2 = "xyz"
7497 test_garbagecollect_now()
7498 assert_equal('string', typename(a.Fn2))
7499 END
7500 call v9.CheckSourceSuccess(lines)
7501
7502 " object variable with 'any" type. Can be assigned different types.
7503 let lines =<< trim END
7504 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007505 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007506 return {}
7507 enddef
7508 class A
7509 public this.Fn: any = Foo
7510 public this.Fn2: any
7511
7512 def Bar()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007513 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007514 this.Fn = "abc"
7515 assert_equal('string', typename(this.Fn))
7516 this.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007517 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007518 this.Fn2 = "xyz"
7519 assert_equal('string', typename(this.Fn2))
7520 enddef
7521 endclass
7522
7523 var a = A.new()
7524 test_garbagecollect_now()
7525 a.Bar()
7526 test_garbagecollect_now()
7527 a.Fn = Foo
7528 a.Bar()
7529 END
7530 call v9.CheckSourceSuccess(lines)
7531
7532 " object variable with 'any" type. Can be assigned different types.
7533 let lines =<< trim END
7534 vim9script
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007535 def Foo(l: list<dict<blob>>): dict<list<blob>>
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007536 return {}
7537 enddef
7538 class A
7539 public this.Fn: any = Foo
7540 public this.Fn2: any
7541 endclass
7542
7543 def Bar()
7544 var a = A.new()
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007545 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007546 a.Fn = "abc"
7547 assert_equal('string', typename(a.Fn))
7548 a.Fn2 = Foo
Yegappan Lakshmanand2f48002023-10-05 20:24:18 +02007549 assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
Yegappan Lakshmananfe7b20a2023-10-04 19:47:52 +02007550 a.Fn2 = "xyz"
7551 assert_equal('string', typename(a.Fn2))
7552 enddef
7553 test_garbagecollect_now()
7554 Bar()
7555 test_garbagecollect_now()
7556 Bar()
7557 END
7558 call v9.CheckSourceSuccess(lines)
7559endfunc
7560
Yegappan Lakshmanan1087b8c2023-10-07 22:03:18 +02007561" Test for recursively calling an object method. This used to cause an
7562" use-after-free error.
7563def Test_recursive_object_method_call()
7564 var lines =<< trim END
7565 vim9script
7566 class A
7567 this.val: number = 0
7568 def Foo(): number
7569 if this.val >= 90
7570 return this.val
7571 endif
7572 this.val += 1
7573 return this.Foo()
7574 enddef
7575 endclass
7576 var a = A.new()
7577 assert_equal(90, a.Foo())
7578 END
7579 v9.CheckSourceSuccess(lines)
7580enddef
7581
7582" Test for recursively calling a class method.
7583def Test_recursive_class_method_call()
7584 var lines =<< trim END
7585 vim9script
7586 class A
7587 static val: number = 0
7588 static def Foo(): number
7589 if val >= 90
7590 return val
7591 endif
7592 val += 1
7593 return Foo()
7594 enddef
7595 endclass
7596 assert_equal(90, A.Foo())
7597 END
7598 v9.CheckSourceSuccess(lines)
7599enddef
7600
Yegappan Lakshmanane4671892023-10-09 18:01:06 +02007601" Test for checking the argument types and the return type when assigning a
7602" funcref to make sure the invariant class type is used.
7603def Test_funcref_argtype_returntype_check()
7604 var lines =<< trim END
7605 vim9script
7606 class A
7607 endclass
7608 class B extends A
7609 endclass
7610
7611 def Foo(p: B): B
7612 return B.new()
7613 enddef
7614
7615 var Bar: func(A): A = Foo
7616 END
7617 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 11)
7618
7619 lines =<< trim END
7620 vim9script
7621 class A
7622 endclass
7623 class B extends A
7624 endclass
7625
7626 def Foo(p: B): B
7627 return B.new()
7628 enddef
7629
7630 def Baz()
7631 var Bar: func(A): A = Foo
7632 enddef
7633 Baz()
7634 END
7635 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<A>): object<A> but got func(object<B>): object<B>', 1)
7636enddef
7637
Ernie Rael96952b22023-10-17 18:15:01 +02007638def Test_funcref_argtype_invariance_check()
7639 var lines =<< trim END
7640 vim9script
7641
7642 class A
7643 endclass
7644 class B extends A
7645 endclass
7646 class C extends B
7647 endclass
7648
7649 var Func: func(B): number
7650 Func = (o: B): number => 3
7651 assert_equal(3, Func(B.new()))
7652 END
7653 v9.CheckSourceSuccess(lines)
7654
7655 lines =<< trim END
7656 vim9script
7657
7658 class A
7659 endclass
7660 class B extends A
7661 endclass
7662 class C extends B
7663 endclass
7664
7665 var Func: func(B): number
7666 Func = (o: A): number => 3
7667 END
7668 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<A>): number', 11)
7669
7670 lines =<< trim END
7671 vim9script
7672
7673 class A
7674 endclass
7675 class B extends A
7676 endclass
7677 class C extends B
7678 endclass
7679
7680 var Func: func(B): number
7681 Func = (o: C): number => 3
7682 END
7683 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(object<B>): number but got func(object<C>): number', 11)
7684enddef
7685
Yegappan Lakshmanan1ea42882023-10-11 21:43:52 +02007686" Test for using an operator (e.g. +) with an assignment
7687def Test_op_and_assignment()
7688 # Using += with a class variable
7689 var lines =<< trim END
7690 vim9script
7691 class A
7692 public static val: list<number> = []
7693 static def Foo(): list<number>
7694 val += [1]
7695 return val
7696 enddef
7697 endclass
7698 def Bar(): list<number>
7699 A.val += [2]
7700 return A.val
7701 enddef
7702 assert_equal([1], A.Foo())
7703 assert_equal([1, 2], Bar())
7704 A.val += [3]
7705 assert_equal([1, 2, 3], A.val)
7706 END
7707 v9.CheckSourceSuccess(lines)
7708
7709 # Using += with an object variable
7710 lines =<< trim END
7711 vim9script
7712 class A
7713 public this.val: list<number> = []
7714 def Foo(): list<number>
7715 this.val += [1]
7716 return this.val
7717 enddef
7718 endclass
7719 def Bar(bar_a: A): list<number>
7720 bar_a.val += [2]
7721 return bar_a.val
7722 enddef
7723 var a = A.new()
7724 assert_equal([1], a.Foo())
7725 assert_equal([1, 2], Bar(a))
7726 a.val += [3]
7727 assert_equal([1, 2, 3], a.val)
7728 END
7729 v9.CheckSourceSuccess(lines)
7730enddef
7731
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007732" Test for using an object method as a funcref
7733def Test_object_funcref()
7734 # Using object method funcref from a def function
7735 var lines =<< trim END
7736 vim9script
7737 class A
7738 def Foo(): list<number>
7739 return [3, 2, 1]
7740 enddef
7741 endclass
7742 def Bar()
7743 var a = A.new()
7744 var Fn = a.Foo
7745 assert_equal([3, 2, 1], Fn())
7746 enddef
7747 Bar()
7748 END
7749 v9.CheckSourceSuccess(lines)
7750
7751 # Using object method funcref at the script level
7752 lines =<< trim END
7753 vim9script
7754 class A
7755 def Foo(): dict<number>
7756 return {a: 1, b: 2}
7757 enddef
7758 endclass
7759 var a = A.new()
7760 var Fn = a.Foo
7761 assert_equal({a: 1, b: 2}, Fn())
7762 END
7763 v9.CheckSourceSuccess(lines)
7764
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007765 # Using object method funcref at the script level
7766 lines =<< trim END
7767 vim9script
7768 class A
7769 this.val: number
7770 def Foo(): number
7771 return this.val
7772 enddef
7773 endclass
7774 var a = A.new(345)
7775 var Fn = a.Foo
7776 assert_equal(345, Fn())
7777 END
7778 v9.CheckSourceSuccess(lines)
7779
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007780 # Using object method funcref from another object method
7781 lines =<< trim END
7782 vim9script
7783 class A
7784 def Foo(): list<number>
7785 return [3, 2, 1]
7786 enddef
7787 def Bar()
7788 var Fn = this.Foo
7789 assert_equal([3, 2, 1], Fn())
7790 enddef
7791 endclass
7792 var a = A.new()
7793 a.Bar()
7794 END
7795 v9.CheckSourceSuccess(lines)
7796
7797 # Using function() to get a object method funcref
7798 lines =<< trim END
7799 vim9script
7800 class A
7801 def Foo(l: list<any>): list<any>
7802 return l
7803 enddef
7804 endclass
7805 var a = A.new()
7806 var Fn = function(a.Foo, [[{a: 1, b: 2}, [3, 4]]])
7807 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7808 END
7809 v9.CheckSourceSuccess(lines)
7810
7811 # Use an object method with a function returning a funcref and then call the
7812 # funcref.
7813 lines =<< trim END
7814 vim9script
7815
7816 def Map(F: func(number): number): func(number): number
7817 return (n: number) => F(n)
7818 enddef
7819
7820 class Math
7821 def Double(n: number): number
7822 return 2 * n
7823 enddef
7824 endclass
7825
7826 const math = Math.new()
7827 assert_equal(48, Map(math.Double)(24))
7828 END
7829 v9.CheckSourceSuccess(lines)
7830
Ernie Rael03042a22023-11-11 08:53:32 +01007831 # Try using a protected object method funcref from a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007832 lines =<< trim END
7833 vim9script
7834 class A
7835 def _Foo()
7836 enddef
7837 endclass
7838 def Bar()
7839 var a = A.new()
7840 var Fn = a._Foo
7841 enddef
7842 Bar()
7843 END
Ernie Rael03042a22023-11-11 08:53:32 +01007844 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 2)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007845
Ernie Rael03042a22023-11-11 08:53:32 +01007846 # Try using a protected object method funcref at the script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007847 lines =<< trim END
7848 vim9script
7849 class A
7850 def _Foo()
7851 enddef
7852 endclass
7853 var a = A.new()
7854 var Fn = a._Foo
7855 END
Ernie Rael03042a22023-11-11 08:53:32 +01007856 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 7)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007857
Ernie Rael03042a22023-11-11 08:53:32 +01007858 # Using a protected object method funcref from another object method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007859 lines =<< trim END
7860 vim9script
7861 class A
7862 def _Foo(): list<number>
7863 return [3, 2, 1]
7864 enddef
7865 def Bar()
7866 var Fn = this._Foo
7867 assert_equal([3, 2, 1], Fn())
7868 enddef
7869 endclass
7870 var a = A.new()
7871 a.Bar()
7872 END
7873 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007874
7875 # Using object method funcref using call()
7876 lines =<< trim END
7877 vim9script
7878 class A
7879 this.val: number
7880 def Foo(): number
7881 return this.val
7882 enddef
7883 endclass
7884
7885 def Bar(obj: A)
7886 assert_equal(123, call(obj.Foo, []))
7887 enddef
7888
7889 var a = A.new(123)
7890 Bar(a)
7891 assert_equal(123, call(a.Foo, []))
7892 END
7893 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007894enddef
7895
7896" Test for using a class method as a funcref
7897def Test_class_funcref()
7898 # Using class method funcref in a def function
7899 var lines =<< trim END
7900 vim9script
7901 class A
7902 static def Foo(): list<number>
7903 return [3, 2, 1]
7904 enddef
7905 endclass
7906 def Bar()
7907 var Fn = A.Foo
7908 assert_equal([3, 2, 1], Fn())
7909 enddef
7910 Bar()
7911 END
7912 v9.CheckSourceSuccess(lines)
7913
7914 # Using class method funcref at script level
7915 lines =<< trim END
7916 vim9script
7917 class A
7918 static def Foo(): dict<number>
7919 return {a: 1, b: 2}
7920 enddef
7921 endclass
7922 var Fn = A.Foo
7923 assert_equal({a: 1, b: 2}, Fn())
7924 END
7925 v9.CheckSourceSuccess(lines)
7926
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02007927 # Using class method funcref at the script level
7928 lines =<< trim END
7929 vim9script
7930 class A
7931 public static val: number
7932 static def Foo(): number
7933 return val
7934 enddef
7935 endclass
7936 A.val = 567
7937 var Fn = A.Foo
7938 assert_equal(567, Fn())
7939 END
7940 v9.CheckSourceSuccess(lines)
7941
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007942 # Using function() to get a class method funcref
7943 lines =<< trim END
7944 vim9script
7945 class A
7946 static def Foo(l: list<any>): list<any>
7947 return l
7948 enddef
7949 endclass
7950 var Fn = function(A.Foo, [[{a: 1, b: 2}, [3, 4]]])
7951 assert_equal([{a: 1, b: 2}, [3, 4]], Fn())
7952 END
7953 v9.CheckSourceSuccess(lines)
7954
7955 # Using a class method funcref from another class method
7956 lines =<< trim END
7957 vim9script
7958 class A
7959 static def Foo(): list<number>
7960 return [3, 2, 1]
7961 enddef
7962 static def Bar()
7963 var Fn = Foo
7964 assert_equal([3, 2, 1], Fn())
7965 enddef
7966 endclass
7967 A.Bar()
7968 END
7969 v9.CheckSourceSuccess(lines)
7970
7971 # Use a class method with a function returning a funcref and then call the
7972 # funcref.
7973 lines =<< trim END
7974 vim9script
7975
7976 def Map(F: func(number): number): func(number): number
7977 return (n: number) => F(n)
7978 enddef
7979
7980 class Math
7981 static def StaticDouble(n: number): number
7982 return 2 * n
7983 enddef
7984 endclass
7985
7986 assert_equal(48, Map(Math.StaticDouble)(24))
7987 END
7988 v9.CheckSourceSuccess(lines)
7989
Ernie Rael03042a22023-11-11 08:53:32 +01007990 # Try using a protected class method funcref in a def function
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02007991 lines =<< trim END
7992 vim9script
7993 class A
7994 static def _Foo()
7995 enddef
7996 endclass
7997 def Bar()
7998 var Fn = A._Foo
7999 enddef
8000 Bar()
8001 END
Ernie Rael03042a22023-11-11 08:53:32 +01008002 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 1)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008003
Ernie Rael03042a22023-11-11 08:53:32 +01008004 # Try using a protected class method funcref at script level
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008005 lines =<< trim END
8006 vim9script
8007 class A
8008 static def _Foo()
8009 enddef
8010 endclass
8011 var Fn = A._Foo
8012 END
Ernie Rael03042a22023-11-11 08:53:32 +01008013 v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Foo', 6)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008014
Ernie Rael03042a22023-11-11 08:53:32 +01008015 # Using a protected class method funcref from another class method
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008016 lines =<< trim END
8017 vim9script
8018 class A
8019 static def _Foo(): list<number>
8020 return [3, 2, 1]
8021 enddef
8022 static def Bar()
8023 var Fn = _Foo
8024 assert_equal([3, 2, 1], Fn())
8025 enddef
8026 endclass
8027 A.Bar()
8028 END
8029 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan1ace49f2023-10-15 09:53:41 +02008030
8031 # Using class method funcref using call()
8032 lines =<< trim END
8033 vim9script
8034 class A
8035 public static val: number
8036 static def Foo(): number
8037 return val
8038 enddef
8039 endclass
8040
8041 def Bar()
8042 A.val = 468
8043 assert_equal(468, call(A.Foo, []))
8044 enddef
8045 Bar()
8046 assert_equal(468, call(A.Foo, []))
8047 END
8048 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02008049enddef
8050
8051" Test for using an object member as a funcref
8052def Test_object_member_funcref()
8053 # Using a funcref object variable in an object method
8054 var lines =<< trim END
8055 vim9script
8056 def Foo(n: number): number
8057 return n * 10
8058 enddef
8059
8060 class A
8061 this.Cb: func(number): number = Foo
8062 def Bar()
8063 assert_equal(200, this.Cb(20))
8064 enddef
8065 endclass
8066
8067 var a = A.new()
8068 a.Bar()
8069 END
8070 v9.CheckSourceSuccess(lines)
8071
8072 # Using a funcref object variable in a def method
8073 lines =<< trim END
8074 vim9script
8075 def Foo(n: number): number
8076 return n * 10
8077 enddef
8078
8079 class A
8080 this.Cb: func(number): number = Foo
8081 endclass
8082
8083 def Bar()
8084 var a = A.new()
8085 assert_equal(200, a.Cb(20))
8086 enddef
8087 Bar()
8088 END
8089 v9.CheckSourceSuccess(lines)
8090
8091 # Using a funcref object variable at script level
8092 lines =<< trim END
8093 vim9script
8094 def Foo(n: number): number
8095 return n * 10
8096 enddef
8097
8098 class A
8099 this.Cb: func(number): number = Foo
8100 endclass
8101
8102 var a = A.new()
8103 assert_equal(200, a.Cb(20))
8104 END
8105 v9.CheckSourceSuccess(lines)
8106
8107 # Using a funcref object variable pointing to an object method in an object
8108 # method.
8109 lines =<< trim END
8110 vim9script
8111 class A
8112 this.Cb: func(number): number = this.Foo
8113 def Foo(n: number): number
8114 return n * 10
8115 enddef
8116 def Bar()
8117 assert_equal(200, this.Cb(20))
8118 enddef
8119 endclass
8120
8121 var a = A.new()
8122 a.Bar()
8123 END
8124 v9.CheckSourceSuccess(lines)
8125
8126 # Using a funcref object variable pointing to an object method in a def
8127 # method.
8128 lines =<< trim END
8129 vim9script
8130 class A
8131 this.Cb: func(number): number = this.Foo
8132 def Foo(n: number): number
8133 return n * 10
8134 enddef
8135 endclass
8136
8137 def Bar()
8138 var a = A.new()
8139 assert_equal(200, a.Cb(20))
8140 enddef
8141 Bar()
8142 END
8143 v9.CheckSourceSuccess(lines)
8144
8145 # Using a funcref object variable pointing to an object method at script
8146 # level.
8147 lines =<< trim END
8148 vim9script
8149 class A
8150 this.Cb = this.Foo
8151 def Foo(n: number): number
8152 return n * 10
8153 enddef
8154 endclass
8155
8156 var a = A.new()
8157 assert_equal(200, a.Cb(20))
8158 END
8159 v9.CheckSourceSuccess(lines)
8160enddef
8161
8162" Test for using a class member as a funcref
8163def Test_class_member_funcref()
8164 # Using a funcref class variable in a class method
8165 var lines =<< trim END
8166 vim9script
8167 def Foo(n: number): number
8168 return n * 10
8169 enddef
8170
8171 class A
8172 static Cb = Foo
8173 static def Bar()
8174 assert_equal(200, Cb(20))
8175 enddef
8176 endclass
8177
8178 A.Bar()
8179 END
8180 v9.CheckSourceSuccess(lines)
8181
8182 # Using a funcref class variable in a def method
8183 lines =<< trim END
8184 vim9script
8185 def Foo(n: number): number
8186 return n * 10
8187 enddef
8188
8189 class A
8190 public static Cb = Foo
8191 endclass
8192
8193 def Bar()
8194 assert_equal(200, A.Cb(20))
8195 enddef
8196 Bar()
8197 END
8198 v9.CheckSourceSuccess(lines)
8199
8200 # Using a funcref class variable at script level
8201 lines =<< trim END
8202 vim9script
8203 def Foo(n: number): number
8204 return n * 10
8205 enddef
8206
8207 class A
8208 public static Cb = Foo
8209 endclass
8210
8211 assert_equal(200, A.Cb(20))
8212 END
8213 v9.CheckSourceSuccess(lines)
8214
8215 # Using a funcref class variable pointing to a class method in a class
8216 # method.
8217 lines =<< trim END
8218 vim9script
8219 class A
8220 static Cb: func(number): number
8221 static def Foo(n: number): number
8222 return n * 10
8223 enddef
8224 static def Init()
8225 Cb = Foo
8226 enddef
8227 static def Bar()
8228 assert_equal(200, Cb(20))
8229 enddef
8230 endclass
8231
8232 A.Init()
8233 A.Bar()
8234 END
8235 v9.CheckSourceSuccess(lines)
8236
8237 # Using a funcref class variable pointing to a class method in a def method.
8238 lines =<< trim END
8239 vim9script
8240 class A
8241 static Cb: func(number): number
8242 static def Foo(n: number): number
8243 return n * 10
8244 enddef
8245 static def Init()
8246 Cb = Foo
8247 enddef
8248 endclass
8249
8250 def Bar()
8251 A.Init()
8252 assert_equal(200, A.Cb(20))
8253 enddef
8254 Bar()
8255 END
8256 v9.CheckSourceSuccess(lines)
8257
8258 # Using a funcref class variable pointing to a class method at script level.
8259 lines =<< trim END
8260 vim9script
8261 class A
8262 static Cb: func(number): number
8263 static def Foo(n: number): number
8264 return n * 10
8265 enddef
8266 static def Init()
8267 Cb = Foo
8268 enddef
8269 endclass
8270
8271 A.Init()
8272 assert_equal(200, A.Cb(20))
8273 END
8274 v9.CheckSourceSuccess(lines)
8275enddef
8276
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02008277" Test for using object methods as popup callback functions
8278def Test_objmethod_popup_callback()
8279 # Use the popup from the script level
8280 var lines =<< trim END
8281 vim9script
8282
8283 class A
8284 this.selection: number = -1
8285 this.filterkeys: list<string> = []
8286
8287 def PopupFilter(id: number, key: string): bool
8288 add(this.filterkeys, key)
8289 return popup_filter_yesno(id, key)
8290 enddef
8291
8292 def PopupCb(id: number, result: number)
8293 this.selection = result ? 100 : 200
8294 enddef
8295 endclass
8296
8297 var a = A.new()
8298 feedkeys('', 'xt')
8299 var winid = popup_create('Y/N?',
8300 {filter: a.PopupFilter, callback: a.PopupCb})
8301 feedkeys('y', 'xt')
8302 popup_close(winid)
8303 assert_equal(100, a.selection)
8304 assert_equal(['y'], a.filterkeys)
8305 feedkeys('', 'xt')
8306 winid = popup_create('Y/N?',
8307 {filter: a.PopupFilter, callback: a.PopupCb})
8308 feedkeys('n', 'xt')
8309 popup_close(winid)
8310 assert_equal(200, a.selection)
8311 assert_equal(['y', 'n'], a.filterkeys)
8312 END
8313 v9.CheckSourceSuccess(lines)
8314
8315 # Use the popup from a def function
8316 lines =<< trim END
8317 vim9script
8318
8319 class A
8320 this.selection: number = -1
8321 this.filterkeys: list<string> = []
8322
8323 def PopupFilter(id: number, key: string): bool
8324 add(this.filterkeys, key)
8325 return popup_filter_yesno(id, key)
8326 enddef
8327
8328 def PopupCb(id: number, result: number)
8329 this.selection = result ? 100 : 200
8330 enddef
8331 endclass
8332
8333 def Foo()
8334 var a = A.new()
8335 feedkeys('', 'xt')
8336 var winid = popup_create('Y/N?',
8337 {filter: a.PopupFilter, callback: a.PopupCb})
8338 feedkeys('y', 'xt')
8339 popup_close(winid)
8340 assert_equal(100, a.selection)
8341 assert_equal(['y'], a.filterkeys)
8342 feedkeys('', 'xt')
8343 winid = popup_create('Y/N?',
8344 {filter: a.PopupFilter, callback: a.PopupCb})
8345 feedkeys('n', 'xt')
8346 popup_close(winid)
8347 assert_equal(200, a.selection)
8348 assert_equal(['y', 'n'], a.filterkeys)
8349 enddef
8350 Foo()
8351 END
8352 v9.CheckSourceSuccess(lines)
8353enddef
8354
8355" Test for using class methods as popup callback functions
8356def Test_classmethod_popup_callback()
8357 # Use the popup from the script level
8358 var lines =<< trim END
8359 vim9script
8360
8361 class A
8362 static selection: number = -1
8363 static filterkeys: list<string> = []
8364
8365 static def PopupFilter(id: number, key: string): bool
8366 add(filterkeys, key)
8367 return popup_filter_yesno(id, key)
8368 enddef
8369
8370 static def PopupCb(id: number, result: number)
8371 selection = result ? 100 : 200
8372 enddef
8373 endclass
8374
8375 feedkeys('', 'xt')
8376 var winid = popup_create('Y/N?',
8377 {filter: A.PopupFilter, callback: A.PopupCb})
8378 feedkeys('y', 'xt')
8379 popup_close(winid)
8380 assert_equal(100, A.selection)
8381 assert_equal(['y'], A.filterkeys)
8382 feedkeys('', 'xt')
8383 winid = popup_create('Y/N?',
8384 {filter: A.PopupFilter, callback: A.PopupCb})
8385 feedkeys('n', 'xt')
8386 popup_close(winid)
8387 assert_equal(200, A.selection)
8388 assert_equal(['y', 'n'], A.filterkeys)
8389 END
8390 v9.CheckSourceSuccess(lines)
8391
8392 # Use the popup from a def function
8393 lines =<< trim END
8394 vim9script
8395
8396 class A
8397 static selection: number = -1
8398 static filterkeys: list<string> = []
8399
8400 static def PopupFilter(id: number, key: string): bool
8401 add(filterkeys, key)
8402 return popup_filter_yesno(id, key)
8403 enddef
8404
8405 static def PopupCb(id: number, result: number)
8406 selection = result ? 100 : 200
8407 enddef
8408 endclass
8409
8410 def Foo()
8411 feedkeys('', 'xt')
8412 var winid = popup_create('Y/N?',
8413 {filter: A.PopupFilter, callback: A.PopupCb})
8414 feedkeys('y', 'xt')
8415 popup_close(winid)
8416 assert_equal(100, A.selection)
8417 assert_equal(['y'], A.filterkeys)
8418 feedkeys('', 'xt')
8419 winid = popup_create('Y/N?',
8420 {filter: A.PopupFilter, callback: A.PopupCb})
8421 feedkeys('n', 'xt')
8422 popup_close(winid)
8423 assert_equal(200, A.selection)
8424 assert_equal(['y', 'n'], A.filterkeys)
8425 enddef
8426 Foo()
8427 END
8428 v9.CheckSourceSuccess(lines)
8429enddef
8430
8431" Test for using an object method as a timer callback function
8432def Test_objmethod_timer_callback()
8433 # Use the timer callback from script level
8434 var lines =<< trim END
8435 vim9script
8436
8437 class A
8438 this.timerTick: number = -1
8439 def TimerCb(timerID: number)
8440 this.timerTick = 6
8441 enddef
8442 endclass
8443
8444 var a = A.new()
8445 timer_start(0, a.TimerCb)
8446 var maxWait = 5
8447 while maxWait > 0 && a.timerTick == -1
8448 :sleep 10m
8449 maxWait -= 1
8450 endwhile
8451 assert_equal(6, a.timerTick)
8452 END
8453 v9.CheckSourceSuccess(lines)
8454
8455 # Use the timer callback from a def function
8456 lines =<< trim END
8457 vim9script
8458
8459 class A
8460 this.timerTick: number = -1
8461 def TimerCb(timerID: number)
8462 this.timerTick = 6
8463 enddef
8464 endclass
8465
8466 def Foo()
8467 var a = A.new()
8468 timer_start(0, a.TimerCb)
8469 var maxWait = 5
8470 while maxWait > 0 && a.timerTick == -1
8471 :sleep 10m
8472 maxWait -= 1
8473 endwhile
8474 assert_equal(6, a.timerTick)
8475 enddef
8476 Foo()
8477 END
8478 v9.CheckSourceSuccess(lines)
8479enddef
8480
8481" Test for using a class method as a timer callback function
8482def Test_classmethod_timer_callback()
8483 # Use the timer callback from script level
8484 var lines =<< trim END
8485 vim9script
8486
8487 class A
8488 static timerTick: number = -1
8489 static def TimerCb(timerID: number)
8490 timerTick = 6
8491 enddef
8492 endclass
8493
8494 timer_start(0, A.TimerCb)
8495 var maxWait = 5
8496 while maxWait > 0 && A.timerTick == -1
8497 :sleep 10m
8498 maxWait -= 1
8499 endwhile
8500 assert_equal(6, A.timerTick)
8501 END
8502 v9.CheckSourceSuccess(lines)
8503
8504 # Use the timer callback from a def function
8505 lines =<< trim END
8506 vim9script
8507
8508 class A
8509 static timerTick: number = -1
8510 static def TimerCb(timerID: number)
8511 timerTick = 6
8512 enddef
8513 endclass
8514
8515 def Foo()
8516 timer_start(0, A.TimerCb)
8517 var maxWait = 5
8518 while maxWait > 0 && A.timerTick == -1
8519 :sleep 10m
8520 maxWait -= 1
8521 endwhile
8522 assert_equal(6, A.timerTick)
8523 enddef
8524 Foo()
8525 END
8526 v9.CheckSourceSuccess(lines)
8527enddef
8528
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008529" Test for using a class variable as the first and/or second operand of a binary
8530" operator.
8531def Test_class_variable_as_operands()
8532 var lines =<< trim END
8533 vim9script
8534 class Tests
8535 static truthy: bool = true
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008536 public static TruthyFn: func
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008537 static list: list<any> = []
8538 static four: number = 4
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008539 static str: string = 'hello'
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008540
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008541 static def Str(): string
8542 return str
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008543 enddef
8544
8545 static def Four(): number
8546 return four
8547 enddef
8548
8549 static def List(): list<any>
8550 return list
8551 enddef
8552
8553 static def Truthy(): bool
8554 return truthy
8555 enddef
8556
8557 def TestOps()
8558 assert_true(Tests.truthy == truthy)
8559 assert_true(truthy == Tests.truthy)
8560 assert_true(Tests.list isnot [])
8561 assert_true([] isnot Tests.list)
8562 assert_equal(2, Tests.four >> 1)
8563 assert_equal(16, 1 << Tests.four)
8564 assert_equal(8, Tests.four + four)
8565 assert_equal(8, four + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008566 assert_equal('hellohello', Tests.str .. str)
8567 assert_equal('hellohello', str .. Tests.str)
8568
8569 # Using class variable for list indexing
8570 var l = range(10)
8571 assert_equal(4, l[Tests.four])
8572 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8573
8574 # Using class variable for Dict key
8575 var d = {hello: 'abc'}
8576 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008577 enddef
8578 endclass
8579
8580 def TestOps2()
8581 assert_true(Tests.truthy == Tests.Truthy())
8582 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008583 assert_true(Tests.truthy == Tests.TruthyFn())
8584 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008585 assert_true(Tests.list is Tests.List())
8586 assert_true(Tests.List() is Tests.list)
8587 assert_equal(2, Tests.four >> 1)
8588 assert_equal(16, 1 << Tests.four)
8589 assert_equal(8, Tests.four + Tests.Four())
8590 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008591 assert_equal('hellohello', Tests.str .. Tests.Str())
8592 assert_equal('hellohello', Tests.Str() .. Tests.str)
8593
8594 # Using class variable for list indexing
8595 var l = range(10)
8596 assert_equal(4, l[Tests.four])
8597 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8598
8599 # Using class variable for Dict key
8600 var d = {hello: 'abc'}
8601 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008602 enddef
8603
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008604 Tests.TruthyFn = Tests.Truthy
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008605 var t = Tests.new()
8606 t.TestOps()
8607 TestOps2()
8608
8609 assert_true(Tests.truthy == Tests.Truthy())
8610 assert_true(Tests.Truthy() == Tests.truthy)
Yegappan Lakshmanan00b55372023-10-19 17:18:28 +02008611 assert_true(Tests.truthy == Tests.TruthyFn())
8612 assert_true(Tests.TruthyFn() == Tests.truthy)
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008613 assert_true(Tests.list is Tests.List())
8614 assert_true(Tests.List() is Tests.list)
8615 assert_equal(2, Tests.four >> 1)
8616 assert_equal(16, 1 << Tests.four)
8617 assert_equal(8, Tests.four + Tests.Four())
8618 assert_equal(8, Tests.Four() + Tests.four)
Yegappan Lakshmanan0ab500d2023-10-21 11:59:42 +02008619 assert_equal('hellohello', Tests.str .. Tests.Str())
8620 assert_equal('hellohello', Tests.Str() .. Tests.str)
8621
8622 # Using class variable for list indexing
8623 var l = range(10)
8624 assert_equal(4, l[Tests.four])
8625 assert_equal([4, 5, 6], l[Tests.four : Tests.four + 2])
8626
8627 # Using class variable for Dict key
8628 var d = {hello: 'abc'}
8629 assert_equal('abc', d[Tests.str])
Yegappan Lakshmanand7b616d2023-10-19 10:47:53 +02008630 END
8631 v9.CheckSourceSuccess(lines)
8632enddef
8633
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008634" Test for checking the type of the key used to access an object dict member.
8635def Test_dict_member_key_type_check()
8636 var lines =<< trim END
8637 vim9script
8638
8639 abstract class State
8640 this.numbers: dict<string> = {0: 'nil', 1: 'unity'}
8641 endclass
8642
8643 class Test extends State
8644 def ObjMethodTests()
8645 var cursor: number = 0
8646 var z: number = 0
8647 [this.numbers[cursor]] = ['zero.1']
8648 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8649 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8650 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8651 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8652 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8653 [this.numbers[cursor], z] = ['zero.4', 1]
8654 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8655 [z, this.numbers[cursor]] = [1, 'zero.5']
8656 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8657 enddef
8658
8659 static def ClassMethodTests(that: State)
8660 var cursor: number = 0
8661 var z: number = 0
8662 [that.numbers[cursor]] = ['zero.1']
8663 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8664 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8665 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8666 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8667 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8668 [that.numbers[cursor], z] = ['zero.4', 1]
8669 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8670 [z, that.numbers[cursor]] = [1, 'zero.5']
8671 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8672 enddef
8673
8674 def new()
8675 enddef
8676
8677 def newMethodTests()
8678 var cursor: number = 0
8679 var z: number
8680 [this.numbers[cursor]] = ['zero.1']
8681 assert_equal({0: 'zero.1', 1: 'unity'}, this.numbers)
8682 [this.numbers[string(cursor)], z] = ['zero.2', 1]
8683 assert_equal({0: 'zero.2', 1: 'unity'}, this.numbers)
8684 [z, this.numbers[string(cursor)]] = [1, 'zero.3']
8685 assert_equal({0: 'zero.3', 1: 'unity'}, this.numbers)
8686 [this.numbers[cursor], z] = ['zero.4', 1]
8687 assert_equal({0: 'zero.4', 1: 'unity'}, this.numbers)
8688 [z, this.numbers[cursor]] = [1, 'zero.5']
8689 assert_equal({0: 'zero.5', 1: 'unity'}, this.numbers)
8690 enddef
8691 endclass
8692
8693 def DefFuncTests(that: Test)
8694 var cursor: number = 0
8695 var z: number
8696 [that.numbers[cursor]] = ['zero.1']
8697 assert_equal({0: 'zero.1', 1: 'unity'}, that.numbers)
8698 [that.numbers[string(cursor)], z] = ['zero.2', 1]
8699 assert_equal({0: 'zero.2', 1: 'unity'}, that.numbers)
8700 [z, that.numbers[string(cursor)]] = [1, 'zero.3']
8701 assert_equal({0: 'zero.3', 1: 'unity'}, that.numbers)
8702 [that.numbers[cursor], z] = ['zero.4', 1]
8703 assert_equal({0: 'zero.4', 1: 'unity'}, that.numbers)
8704 [z, that.numbers[cursor]] = [1, 'zero.5']
8705 assert_equal({0: 'zero.5', 1: 'unity'}, that.numbers)
8706 enddef
8707
8708 Test.newMethodTests()
8709 Test.new().ObjMethodTests()
8710 Test.ClassMethodTests(Test.new())
8711 DefFuncTests(Test.new())
8712
8713 const test: Test = Test.new()
8714 var cursor: number = 0
8715 [test.numbers[cursor], cursor] = ['zero', 1]
8716 [cursor, test.numbers[cursor]] = [1, 'one']
8717 assert_equal({0: 'zero', 1: 'one'}, test.numbers)
8718 END
8719 v9.CheckSourceSuccess(lines)
8720
8721 lines =<< trim END
8722 vim9script
8723
8724 class A
8725 this.numbers: dict<string> = {a: '1', b: '2'}
8726
8727 def new()
8728 enddef
8729
8730 def Foo()
8731 var z: number
8732 [this.numbers.a, z] = [{}, 10]
8733 enddef
8734 endclass
8735
8736 var a = A.new()
8737 a.Foo()
8738 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008739 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got dict<any>', 2)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008740
8741 lines =<< trim END
8742 vim9script
8743
8744 class A
8745 this.numbers: dict<number> = {a: 1, b: 2}
8746
8747 def new()
8748 enddef
8749
8750 def Foo()
8751 var x: string = 'a'
8752 var y: number
8753 [this.numbers[x], y] = [{}, 10]
8754 enddef
8755 endclass
8756
8757 var a = A.new()
8758 a.Foo()
8759 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01008760 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got dict<any>', 3)
Yegappan Lakshmananc229a6a2023-10-26 23:05:07 +02008761enddef
8762
mityua5550692023-11-25 15:41:20 +01008763def Test_compile_many_def_functions_in_funcref_instr()
8764 # This used to crash Vim. This is reproducible only when run on new instance
8765 # of Vim.
8766 var lines =<< trim END
8767 vim9script
8768
8769 class A
8770 def new()
8771 this.TakeFunc(this.F00)
8772 enddef
8773
8774 def TakeFunc(F: func)
8775 enddef
8776
8777 def F00()
8778 this.F01()
8779 this.F02()
8780 this.F03()
8781 this.F04()
8782 this.F05()
8783 this.F06()
8784 this.F07()
8785 this.F08()
8786 this.F09()
8787 this.F10()
8788 this.F11()
8789 this.F12()
8790 this.F13()
8791 this.F14()
8792 this.F15()
8793 this.F16()
8794 this.F17()
8795 this.F18()
8796 this.F19()
8797 this.F20()
8798 this.F21()
8799 this.F22()
8800 this.F23()
8801 this.F24()
8802 this.F25()
8803 this.F26()
8804 this.F27()
8805 this.F28()
8806 this.F29()
8807 this.F30()
8808 this.F31()
8809 this.F32()
8810 this.F33()
8811 this.F34()
8812 this.F35()
8813 this.F36()
8814 this.F37()
8815 this.F38()
8816 this.F39()
8817 this.F40()
8818 this.F41()
8819 this.F42()
8820 this.F43()
8821 this.F44()
8822 this.F45()
8823 this.F46()
8824 this.F47()
8825 enddef
8826
8827 def F01()
8828 enddef
8829 def F02()
8830 enddef
8831 def F03()
8832 enddef
8833 def F04()
8834 enddef
8835 def F05()
8836 enddef
8837 def F06()
8838 enddef
8839 def F07()
8840 enddef
8841 def F08()
8842 enddef
8843 def F09()
8844 enddef
8845 def F10()
8846 enddef
8847 def F11()
8848 enddef
8849 def F12()
8850 enddef
8851 def F13()
8852 enddef
8853 def F14()
8854 enddef
8855 def F15()
8856 enddef
8857 def F16()
8858 enddef
8859 def F17()
8860 enddef
8861 def F18()
8862 enddef
8863 def F19()
8864 enddef
8865 def F20()
8866 enddef
8867 def F21()
8868 enddef
8869 def F22()
8870 enddef
8871 def F23()
8872 enddef
8873 def F24()
8874 enddef
8875 def F25()
8876 enddef
8877 def F26()
8878 enddef
8879 def F27()
8880 enddef
8881 def F28()
8882 enddef
8883 def F29()
8884 enddef
8885 def F30()
8886 enddef
8887 def F31()
8888 enddef
8889 def F32()
8890 enddef
8891 def F33()
8892 enddef
8893 def F34()
8894 enddef
8895 def F35()
8896 enddef
8897 def F36()
8898 enddef
8899 def F37()
8900 enddef
8901 def F38()
8902 enddef
8903 def F39()
8904 enddef
8905 def F40()
8906 enddef
8907 def F41()
8908 enddef
8909 def F42()
8910 enddef
8911 def F43()
8912 enddef
8913 def F44()
8914 enddef
8915 def F45()
8916 enddef
8917 def F46()
8918 enddef
8919 def F47()
8920 enddef
8921 endclass
8922
8923 A.new()
8924 END
8925 writefile(lines, 'Xscript', 'D')
8926 g:RunVim([], [], '-u NONE -S Xscript -c qa')
8927 assert_equal(0, v:shell_error)
8928enddef
8929
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008930" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker