blob: 856ee031088e2022c0a6c4f2d8c4b2c0d326cfa6 [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02009 class NotWorking
10 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000011 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020012 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020016 vim9script
17 class notWorking
18 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000019 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020020 v9.CheckSourceFailure(lines, 'E1314: Class name must start with an uppercase letter: notWorking', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020024 vim9script
25 class Not@working
26 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000027 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020028 v9.CheckSourceFailure(lines, 'E1315: White space required after name: Not@working', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020032 vim9script
33 abstract noclass Something
34 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020036 v9.CheckSourceFailure(lines, 'E475: Invalid argument: noclass Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020038 # Only the completed word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020040 vim9script
41 abstract classy Something
42 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000043 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020044 v9.CheckSourceFailure(lines, 'E475: Invalid argument: classy Something', 2)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020048 vim9script
49 class Something
50 endcl
Bram Moolenaar00b28d62022-12-08 15:32:33 +000051 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020052 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: endcl', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020056 vim9script
57 class Something
58 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020060 v9.CheckSourceFailure(lines, "E488: Trailing characters: school's out", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020064 vim9script
65 class Something
66 endclass | echo 'done'
Bram Moolenaar00b28d62022-12-08 15:32:33 +000067 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020068 v9.CheckSourceFailure(lines, "E488: Trailing characters: | echo 'done'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020070 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000071 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020072 vim9script
73 class Something
74 this
75 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020077 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020079 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000080 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020081 vim9script
82 class Something
83 this.
84 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000085 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020086 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this.', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000087
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020088 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000089 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020090 vim9script
91 class Something
92 this .count
93 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +000094 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020095 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this .count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000096
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +020099 vim9script
100 class Something
101 this. count
102 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200104 v9.CheckSourceFailure(lines, 'E1317: Invalid object variable declaration: this. count', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200108 vim9script
109 class Something
110 this.count: number
111 that.count
112 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000113 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200114 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count', 4)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000115
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200116 # Member variable without a type or initialization
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000117 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200118 vim9script
119 class Something
120 this.count
121 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000122 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200123 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200125 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000126 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200127 vim9script
128 class Something
129 def new()
130 this.state = 0
131 enddef
132 endclass
133 var obj = Something.new()
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000134 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200135 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Something": state', 1)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000136
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200137 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200139 vim9script
140 class Something
141 this.count : number
142 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000143 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200144 v9.CheckSourceFailure(lines, 'E1059: No white space allowed before colon: count : number', 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000145
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200146 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000147 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200148 vim9script
149 class Something
150 this.count:number
151 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200153 v9.CheckSourceFailure(lines, "E1069: White space required after ':'", 3)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000154
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200155 # Test for unsupported comment specifier
156 lines =<< trim END
157 vim9script
158 class Something
159 # comment
160 #{
161 endclass
162 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200163 v9.CheckSourceFailure(lines, 'E1170: Cannot use #{ to start a comment', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200164
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200165 # Test for using class as a bool
166 lines =<< trim END
167 vim9script
168 class A
169 endclass
170 if A
171 endif
172 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200173 v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200174
175 # Test for using object as a bool
176 lines =<< trim END
177 vim9script
178 class A
179 endclass
180 var a = A.new()
181 if a
182 endif
183 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200184 v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200185
186 # Test for using class as a float
187 lines =<< trim END
188 vim9script
189 class A
190 endclass
191 sort([1.1, A], 'f')
192 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200193 v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200194
195 # Test for using object as a float
196 lines =<< trim END
197 vim9script
198 class A
199 endclass
200 var a = A.new()
201 sort([1.1, a], 'f')
202 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200203 v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200204
205 # Test for using class as a string
206 lines =<< trim END
207 vim9script
208 class A
209 endclass
210 :exe 'call ' .. A
211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200212 v9.CheckSourceFailure(lines, 'E1323: Using a class as a String', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200213
214 # Test for using object as a string
215 lines =<< trim END
216 vim9script
217 class A
218 endclass
219 var a = A.new()
220 :exe 'call ' .. a
221 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200222 v9.CheckSourceFailure(lines, 'E1324: Using an object as a String', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200223
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200224 # Test creating a class with member variables and methods, calling a object
225 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000226 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200227 vim9script
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000228
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200229 class TextPosition
230 this.lnum: number
231 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000232
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200233 # make a nicely formatted string
234 def ToString(): string
235 return $'({this.lnum}, {this.col})'
236 enddef
237 endclass
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000238
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200239 # use the automatically generated new() method
240 var pos = TextPosition.new(2, 12)
241 assert_equal(2, pos.lnum)
242 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000243
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200244 # call an object method
245 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000246
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200247 assert_equal(v:t_class, type(TextPosition))
248 assert_equal(v:t_object, type(pos))
249 assert_equal('class<TextPosition>', typename(TextPosition))
250 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200253
254 # When referencing object methods, space cannot be used after a "."
255 lines =<< trim END
256 vim9script
257 class A
258 def Foo(): number
259 return 10
260 enddef
261 endclass
262 var a = A.new()
263 var v = a. Foo()
264 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200265 v9.CheckSourceFailure(lines, "E1202: No white space allowed after '.'", 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200266
267 # Using an object without specifying a method or a member variable
268 lines =<< trim END
269 vim9script
270 class A
271 def Foo(): number
272 return 10
273 enddef
274 endclass
275 var a = A.new()
276 var v = a.
277 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200278 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a."', 8)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279
280 # Error when parsing the arguments of an object method.
281 lines =<< trim END
282 vim9script
283 class A
284 def Foo()
285 enddef
286 endclass
287 var a = A.new()
288 var v = a.Foo(,)
289 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200290 v9.CheckSourceFailure(lines, 'E15: Invalid expression: "a.Foo(,)"', 7)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200291
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200292 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200293 lines =<< trim END
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200294 vim9script
295 class A
296 this.y = {
297 X: 1
298 }
299 endclass
300 var a = A.new()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200301 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200302 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000303enddef
304
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +0200305" Tests for object/class methods in a class
306def Test_class_def_method()
307 # Using the "public" keyword when defining an object method
308 var lines =<< trim END
309 vim9script
310 class A
311 public def Foo()
312 enddef
313 endclass
314 END
315 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
316
317 # Using the "public" keyword when defining a class method
318 lines =<< trim END
319 vim9script
320 class A
321 public static def Foo()
322 enddef
323 endclass
324 END
325 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
326
327 # Using the "public" keyword when defining an object private method
328 lines =<< trim END
329 vim9script
330 class A
331 public def _Foo()
332 enddef
333 endclass
334 END
335 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
336
337 # Using the "public" keyword when defining a class private method
338 lines =<< trim END
339 vim9script
340 class A
341 public static def _Foo()
342 enddef
343 endclass
344 END
345 v9.CheckSourceFailure(lines, 'E1388: Public keyword not supported for a method', 3)
346
347 # Using a "def" keyword without an object method name
348 lines =<< trim END
349 vim9script
350 class A
351 def
352 enddef
353 endclass
354 END
355 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: def', 3)
356
357 # Using a "def" keyword without a class method name
358 lines =<< trim END
359 vim9script
360 class A
361 static def
362 enddef
363 endclass
364 END
365 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: static def', 3)
366enddef
367
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000368def Test_class_defined_twice()
369 # class defined twice should fail
370 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200371 vim9script
372 class There
373 endclass
374 class There
375 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000376 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200377 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"', 4)
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000378
379 # one class, reload same script twice is OK
380 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200381 vim9script
382 class There
383 endclass
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000384 END
385 writefile(lines, 'XclassTwice.vim', 'D')
386 source XclassTwice.vim
387 source XclassTwice.vim
388enddef
389
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000390def Test_returning_null_object()
391 # this was causing an internal error
392 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200393 vim9script
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000394
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200395 class BufferList
396 def Current(): any
397 return null_object
398 enddef
399 endclass
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000400
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200401 var buffers = BufferList.new()
402 echo buffers.Current()
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000403 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200404 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000405enddef
406
Bram Moolenaard13dd302023-03-11 20:56:35 +0000407def Test_using_null_class()
408 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200409 @_ = null_class.member
Bram Moolenaard13dd302023-03-11 20:56:35 +0000410 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200411 v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
Bram Moolenaard13dd302023-03-11 20:56:35 +0000412enddef
413
Bram Moolenaar657aea72023-01-27 13:16:19 +0000414def Test_class_interface_wrong_end()
415 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200416 vim9script
417 abstract class SomeName
418 this.member = 'text'
419 endinterface
Bram Moolenaar657aea72023-01-27 13:16:19 +0000420 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200421 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000422
423 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200424 vim9script
425 export interface AnotherName
426 this.member: string
427 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +0000428 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200429 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface', 4)
Bram Moolenaar657aea72023-01-27 13:16:19 +0000430enddef
431
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000432def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200433 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000434 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200435 vim9script
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200437 class State
438 this.value = 'xyz'
439 endclass
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000440
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200441 var state: State
442 var db = {'xyz': 789}
443 echo db[state.value]
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000444 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200445 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 9)
Bram Moolenaar0917e862023-02-18 14:42:44 +0000446
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200447 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200449 vim9script
Bram Moolenaar0917e862023-02-18 14:42:44 +0000450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200451 class Class
452 this.id: string
453 def Method1()
454 echo 'Method1' .. this.id
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000455 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200456 endclass
457
458 var obj: Class
459 def Func()
460 obj.Method1()
461 enddef
462 Func()
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000463 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200464 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000465
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200466 # Pass an uninitialized object variable to a "new" function and try to call an
467 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000468 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200469 vim9script
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000470
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200471 class Background
472 this.background = 'dark'
473 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000474
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200475 class Colorscheme
476 this._bg: Background
Bram Moolenaar0917e862023-02-18 14:42:44 +0000477
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200478 def GetBackground(): string
479 return this._bg.background
480 enddef
481 endclass
Bram Moolenaar0917e862023-02-18 14:42:44 +0000482
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200483 var bg: Background # UNINITIALIZED
484 echo Colorscheme.new(bg).GetBackground()
Bram Moolenaar0917e862023-02-18 14:42:44 +0000485 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200486 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
Ernie Raelf77a7f72023-03-03 15:05:30 +0000487
488 # TODO: this should not give an error but be handled at runtime
489 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200490 vim9script
Ernie Raelf77a7f72023-03-03 15:05:30 +0000491
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200492 class Class
493 this.id: string
494 def Method1()
495 echo 'Method1' .. this.id
Ernie Raelf77a7f72023-03-03 15:05:30 +0000496 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200497 endclass
498
499 var obj = null_object
500 def Func()
501 obj.Method1()
502 enddef
503 Func()
Ernie Raelf77a7f72023-03-03 15:05:30 +0000504 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200505 v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000506enddef
507
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200508" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200509def Test_null_object_assign_compare()
510 var lines =<< trim END
511 vim9script
512
513 var nullo = null_object
514 def F(): any
515 return nullo
516 enddef
517 assert_equal('object<Unknown>', typename(F()))
518
519 var o0 = F()
520 assert_true(o0 == null_object)
521 assert_true(o0 == null)
522
523 var o1: any = nullo
524 assert_true(o1 == null_object)
525 assert_true(o1 == null)
526
527 def G()
528 var x = null_object
529 enddef
530
531 class C
532 endclass
533 var o2: C
534 assert_true(o2 == null_object)
535 assert_true(o2 == null)
536
537 o2 = null_object
538 assert_true(o2 == null)
539
540 o2 = C.new()
541 assert_true(o2 != null)
542
543 o2 = null_object
544 assert_true(o2 == null)
545 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200546 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200547enddef
548
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200549" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000550def Test_class_member_initializer()
551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200552 vim9script
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200554 class TextPosition
555 this.lnum: number = 1
556 this.col: number = 1
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000557
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200558 # constructor with only the line number
559 def new(lnum: number)
560 this.lnum = lnum
561 enddef
562 endclass
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000563
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200564 var pos = TextPosition.new(3)
565 assert_equal(3, pos.lnum)
566 assert_equal(1, pos.col)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200568 var instr = execute('disassemble TextPosition.new')
569 assert_match('new\_s*' ..
570 '0 NEW TextPosition size \d\+\_s*' ..
571 '\d PUSHNR 1\_s*' ..
572 '\d STORE_THIS 0\_s*' ..
573 '\d PUSHNR 1\_s*' ..
574 '\d STORE_THIS 1\_s*' ..
575 'this.lnum = lnum\_s*' ..
576 '\d LOAD arg\[-1]\_s*' ..
577 '\d PUSHNR 0\_s*' ..
578 '\d LOAD $0\_s*' ..
579 '\d\+ STOREINDEX object\_s*' ..
580 '\d\+ RETURN object.*',
581 instr)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000582 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200583 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000584enddef
585
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000586def Test_member_any_used_as_object()
587 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200588 vim9script
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000589
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200590 class Inner
591 this.value: number = 0
592 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000593
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200594 class Outer
595 this.inner: any
596 endclass
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200598 def F(outer: Outer)
599 outer.inner.value = 1
600 enddef
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000601
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200602 var inner_obj = Inner.new(0)
603 var outer_obj = Outer.new(inner_obj)
604 F(outer_obj)
605 assert_equal(1, inner_obj.value)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000606 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200607 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000608
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200609 # Try modifying a private variable using an "any" object
610 lines =<< trim END
611 vim9script
612
613 class Inner
614 this._value: string = ''
615 endclass
616
617 class Outer
618 this.inner: any
619 endclass
620
621 def F(outer: Outer)
622 outer.inner._value = 'b'
623 enddef
624
625 var inner_obj = Inner.new('a')
626 var outer_obj = Outer.new(inner_obj)
627 F(outer_obj)
628 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200629 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _value', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200630
631 # Try modifying a non-existing variable using an "any" object
632 lines =<< trim END
633 vim9script
634
635 class Inner
636 this.value: string = ''
637 endclass
638
639 class Outer
640 this.inner: any
641 endclass
642
643 def F(outer: Outer)
644 outer.inner.someval = 'b'
645 enddef
646
647 var inner_obj = Inner.new('a')
648 var outer_obj = Outer.new(inner_obj)
649 F(outer_obj)
650 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200651 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "Inner": someval', 1)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000652enddef
653
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200654" Nested assignment to a object variable which is of another class type
655def Test_assignment_nested_type()
656 var lines =<< trim END
657 vim9script
658
659 class Inner
660 public this.value: number = 0
661 endclass
662
663 class Outer
664 this.inner: Inner
665 endclass
666
667 def F(outer: Outer)
668 outer.inner.value = 1
669 enddef
670
671 def Test_assign_to_nested_typed_member()
672 var inner = Inner.new(0)
673 var outer = Outer.new(inner)
674 F(outer)
675 assert_equal(1, inner.value)
676 enddef
677
678 Test_assign_to_nested_typed_member()
Ernie Rael98e68c02023-09-20 20:13:06 +0200679
680 var script_inner = Inner.new(0)
681 var script_outer = Outer.new(script_inner)
682 script_outer.inner.value = 1
683 assert_equal(1, script_inner.value)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200684 END
685 v9.CheckSourceSuccess(lines)
Ernie Rael98e68c02023-09-20 20:13:06 +0200686
687 # Assignment where target item is read only in :def
688 lines =<< trim END
689 vim9script
690
691 class Inner
692 this.value: number = 0
693 endclass
694
695 class Outer
696 this.inner: Inner
697 endclass
698
699 def F(outer: Outer)
700 outer.inner.value = 1
701 enddef
702
703 def Test_assign_to_nested_typed_member()
704 var inner = Inner.new(0)
705 var outer = Outer.new(inner)
706 F(outer)
707 assert_equal(1, inner.value)
708 enddef
709
710 Test_assign_to_nested_typed_member()
711 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200712 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 1)
Ernie Rael98e68c02023-09-20 20:13:06 +0200713
714 # Assignment where target item is read only script level
715 lines =<< trim END
716 vim9script
717
718 class Inner
719 this.value: number = 0
720 endclass
721
722 class Outer
723 this.inner: Inner
724 endclass
725
726 def F(outer: Outer)
727 outer.inner.value = 1
728 enddef
729
730 var script_inner = Inner.new(0)
731 var script_outer = Outer.new(script_inner)
732 script_outer.inner.value = 1
733 assert_equal(1, script_inner.value)
734 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200735 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "Inner" is not writable', 17)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200736enddef
737
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000738def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200739 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000740 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200741 vim9script
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000742
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200743 class Foo
744 public this.x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000745
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200746 def Add(n: number)
747 this.x += n
Bram Moolenaar22363c62023-04-24 17:15:25 +0100748 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200749 endclass
Bram Moolenaar22363c62023-04-24 17:15:25 +0100750
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200751 var f = Foo.new(3)
752 f.Add(17)
753 assert_equal(20, f.x)
754
755 def AddToFoo(obj: Foo)
756 obj.x += 3
757 enddef
758
759 AddToFoo(f)
760 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000761 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200762 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000763enddef
764
Bram Moolenaarf4508042023-01-15 16:54:57 +0000765def Test_list_of_objects()
766 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200767 vim9script
Bram Moolenaarf4508042023-01-15 16:54:57 +0000768
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200769 class Foo
770 def Add()
Bram Moolenaarf4508042023-01-15 16:54:57 +0000771 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200772 endclass
Bram Moolenaarf4508042023-01-15 16:54:57 +0000773
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200774 def ProcessList(fooList: list<Foo>)
775 for foo in fooList
776 foo.Add()
777 endfor
778 enddef
779
780 var l: list<Foo> = [Foo.new()]
781 ProcessList(l)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000782 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200783 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000784enddef
785
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000786def Test_expr_after_using_object()
787 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200788 vim9script
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000789
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200790 class Something
791 this.label: string = ''
792 endclass
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000793
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200794 def Foo(): Something
795 var v = Something.new()
796 echo 'in Foo(): ' .. typename(v)
797 return v
798 enddef
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000799
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200800 Foo()
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000801 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200802 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000803enddef
804
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000805def Test_class_default_new()
806 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200807 vim9script
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000808
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200809 class TextPosition
810 this.lnum: number = 1
811 this.col: number = 1
812 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000813
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200814 var pos = TextPosition.new()
815 assert_equal(1, pos.lnum)
816 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000817
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200818 pos = TextPosition.new(v:none, v:none)
819 assert_equal(1, pos.lnum)
820 assert_equal(1, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000821
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200822 pos = TextPosition.new(3, 22)
823 assert_equal(3, pos.lnum)
824 assert_equal(22, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000825
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200826 pos = TextPosition.new(v:none, 33)
827 assert_equal(1, pos.lnum)
828 assert_equal(33, pos.col)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000829 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200830 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000831
832 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200833 vim9script
834 class Person
835 this.name: string
836 this.age: number = 42
837 this.education: string = "unknown"
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000838
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200839 def new(this.name, this.age = v:none, this.education = v:none)
840 enddef
841 endclass
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000842
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200843 var piet = Person.new("Piet")
844 assert_equal("Piet", piet.name)
845 assert_equal(42, piet.age)
846 assert_equal("unknown", piet.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000847
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200848 var chris = Person.new("Chris", 4, "none")
849 assert_equal("Chris", chris.name)
850 assert_equal(4, chris.age)
851 assert_equal("none", chris.education)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000852 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200853 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000854
855 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200856 vim9script
857 class Person
858 this.name: string
859 this.age: number = 42
860 this.education: string = "unknown"
Bram Moolenaar74e12742022-12-13 21:14:28 +0000861
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200862 def new(this.name, this.age = v:none, this.education = v:none)
863 enddef
864 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000865
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200866 var missing = Person.new()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000867 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200868 v9.CheckSourceFailure(lines, 'E119: Not enough arguments for function: new', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200869
870 # Using a specific value to initialize an instance variable in the new()
871 # method.
872 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200873 vim9script
874 class A
875 this.val: string
876 def new(this.val = 'a')
877 enddef
878 endclass
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200879 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200880 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'", 4)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000881enddef
882
h-east2261c892023-08-16 21:49:54 +0900883def Test_class_new_with_object_member()
884 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200885 vim9script
h-east2261c892023-08-16 21:49:54 +0900886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200887 class C
888 this.str: string
889 this.num: number
890 def new(this.str, this.num)
h-east2261c892023-08-16 21:49:54 +0900891 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200892 def newVals(this.str, this.num)
893 enddef
894 endclass
h-east2261c892023-08-16 21:49:54 +0900895
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200896 def Check()
897 try
898 var c = C.new('cats', 2)
899 assert_equal('cats', c.str)
900 assert_equal(2, c.num)
901
902 c = C.newVals('dogs', 4)
903 assert_equal('dogs', c.str)
904 assert_equal(4, c.num)
905 catch
906 assert_report($'Unexpected exception was caught: {v:exception}')
907 endtry
908 enddef
909
910 Check()
h-east2261c892023-08-16 21:49:54 +0900911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200912 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900913
914 lines =<< trim END
h-eastdb385522023-09-28 22:18:19 +0200915 vim9script
916
917 class C
918 this.str: string
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200919 this.num: number
920 def new(this.str, this.num)
h-eastdb385522023-09-28 22:18:19 +0200921 enddef
922 endclass
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200923
924 def Check()
925 try
926 var c = C.new(1, 2)
927 catch
928 assert_report($'Unexpected exception was caught: {v:exception}')
929 endtry
930 enddef
931
932 Check()
h-eastdb385522023-09-28 22:18:19 +0200933 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200934 v9.CheckSourceFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number', 2)
h-eastdb385522023-09-28 22:18:19 +0200935
936 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200937 vim9script
h-eastb895b0f2023-09-24 15:46:31 +0200938
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200939 class C
940 this.str: string
941 this.num: number
942 def newVals(this.str, this.num)
h-eastb895b0f2023-09-24 15:46:31 +0200943 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200944 endclass
h-eastb895b0f2023-09-24 15:46:31 +0200945
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200946 def Check()
947 try
948 var c = C.newVals('dogs', 'apes')
949 catch
950 assert_report($'Unexpected exception was caught: {v:exception}')
951 endtry
952 enddef
953
954 Check()
955 END
956 v9.CheckSourceFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 2)
957
958 lines =<< trim END
959 vim9script
960
961 class C
962 this.str: string
963 def new(str: any)
964 enddef
965 endclass
966
967 def Check()
968 try
969 var c = C.new(1)
970 catch
971 assert_report($'Unexpected exception was caught: {v:exception}')
972 endtry
973 enddef
974
975 Check()
h-eastb895b0f2023-09-24 15:46:31 +0200976 END
977 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900978enddef
979
Bram Moolenaar74e12742022-12-13 21:14:28 +0000980def Test_class_object_member_inits()
981 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200982 vim9script
983 class TextPosition
984 this.lnum: number
985 this.col = 1
986 this.addcol: number = 2
987 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +0000988
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200989 var pos = TextPosition.new()
990 assert_equal(0, pos.lnum)
991 assert_equal(1, pos.col)
992 assert_equal(2, pos.addcol)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000993 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200994 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000995
996 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +0200997 vim9script
998 class TextPosition
999 this.lnum
1000 this.col = 1
1001 endclass
Bram Moolenaar74e12742022-12-13 21:14:28 +00001002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001003 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001004
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001005 # If the type is not specified for a member, then it should be set during
1006 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +00001007 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001008 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001009
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001010 var init_count = 0
1011 def Init(): string
1012 init_count += 1
1013 return 'foo'
1014 enddef
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001015
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001016 class A
1017 this.str1 = Init()
1018 this.str2: string = Init()
1019 this.col = 1
1020 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001021
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001022 assert_equal(init_count, 0)
1023 var a = A.new()
1024 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001025 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001026 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001027
1028 # Test for initializing an object member with an unknown variable/type
1029 lines =<< trim END
1030 vim9script
1031 class A
1032 this.value = init_val
1033 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02001034 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001035 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001036 v9.CheckSourceFailure(lines, 'E1001: Variable not found: init_val', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001037
1038 # Test for initializing an object member with an special type
1039 lines =<< trim END
1040 vim9script
1041 class A
1042 this.value: void
1043 endclass
1044 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001045 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object variable: void', 3)
Bram Moolenaar74e12742022-12-13 21:14:28 +00001046enddef
1047
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001048" Test for instance variable access
1049def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001050 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001051 vim9script
1052 class Triple
1053 this._one = 1
1054 this.two = 2
1055 public this.three = 3
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001056
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001057 def GetOne(): number
1058 return this._one
1059 enddef
1060 endclass
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001061
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001062 var trip = Triple.new()
1063 assert_equal(1, trip.GetOne())
1064 assert_equal(2, trip.two)
1065 assert_equal(3, trip.three)
1066 assert_fails('echo trip._one', 'E1333: Cannot access private variable: _one')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001067
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001068 assert_fails('trip._one = 11', 'E1333: Cannot access private variable: _one')
1069 assert_fails('trip.two = 22', 'E1335: Variable "two" in class "Triple" is not writable')
1070 trip.three = 33
1071 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +00001072
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001073 assert_fails('trip.four = 4', 'E1326: Variable not found on object "Triple": four')
Bram Moolenaard505d172022-12-18 21:42:55 +00001074 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001075 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +00001076
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001077 # Test for a public member variable name beginning with an underscore
1078 lines =<< trim END
1079 vim9script
1080 class A
1081 public this._val = 10
1082 endclass
1083 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001084 v9.CheckSourceFailure(lines, 'E1332: Public variable name cannot start with underscore: public this._val = 10', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001085
Bram Moolenaar590162c2022-12-24 21:24:06 +00001086 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001087 vim9script
Bram Moolenaar590162c2022-12-24 21:24:06 +00001088
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001089 class MyCar
1090 this.make: string
1091 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +00001092
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001093 def new(make_arg: string)
1094 this.make = make_arg
Bram Moolenaar574950d2023-01-03 19:08:50 +00001095 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001096
1097 def GetMake(): string
1098 return $"make = {this.make}"
1099 enddef
1100 def GetAge(): number
1101 return this.age
1102 enddef
1103 endclass
1104
1105 var c = MyCar.new("abc")
1106 assert_equal('make = abc', c.GetMake())
1107
1108 c = MyCar.new("def")
1109 assert_equal('make = def', c.GetMake())
1110
1111 var c2 = MyCar.new("123")
1112 assert_equal('make = 123', c2.GetMake())
1113
1114 def CheckCar()
1115 assert_equal("make = def", c.GetMake())
1116 assert_equal(5, c.GetAge())
1117 enddef
1118 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001119 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001120 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001121
1122 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001123 vim9script
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001124
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001125 class MyCar
1126 this.make: string
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001127
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001128 def new(make_arg: string)
1129 this.make = make_arg
1130 enddef
1131 endclass
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001132
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001133 var c = MyCar.new("abc")
1134 var c = MyCar.new("def")
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001136 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "c"', 12)
Bram Moolenaarb149d222023-01-24 13:03:37 +00001137
1138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001139 vim9script
Bram Moolenaarb149d222023-01-24 13:03:37 +00001140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001141 class Foo
1142 this.x: list<number> = []
Bram Moolenaarb149d222023-01-24 13:03:37 +00001143
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001144 def Add(n: number): any
1145 this.x->add(n)
1146 return this
1147 enddef
1148 endclass
Bram Moolenaarb149d222023-01-24 13:03:37 +00001149
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001150 echo Foo.new().Add(1).Add(2).x
1151 echo Foo.new().Add(1).Add(2)
1152 .x
1153 echo Foo.new().Add(1)
1154 .Add(2).x
1155 echo Foo.new()
1156 .Add(1).Add(2).x
1157 echo Foo.new()
1158 .Add(1)
1159 .Add(2)
1160 .x
Bram Moolenaarb149d222023-01-24 13:03:37 +00001161 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001162 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001163
1164 # Test for "public" cannot be abbreviated
1165 lines =<< trim END
1166 vim9script
1167 class Something
1168 pub this.val = 1
1169 endclass
1170 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001171 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: pub this.val = 1', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001172
1173 # Test for "public" keyword must be followed by "this" or "static".
1174 lines =<< trim END
1175 vim9script
1176 class Something
1177 public val = 1
1178 endclass
1179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001180 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001181
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001182 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001183 lines =<< trim END
1184 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001185 class A
1186 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001187 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001188 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001190 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001191
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001192 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001193 lines =<< trim END
1194 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001195 class A
1196 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001197 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001198 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001199 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001200 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 5)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001201
1202 # Modify a instance variable using the class name in a def function
1203 lines =<< trim END
1204 vim9script
1205 class A
1206 public this.val = 1
1207 endclass
1208 def T()
1209 A.val = 1
1210 enddef
1211 T()
1212 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001213 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001214
1215 # Read a instance variable using the class name in a def function
1216 lines =<< trim END
1217 vim9script
1218 class A
1219 public this.val = 1
1220 endclass
1221 def T()
1222 var i = A.val
1223 enddef
1224 T()
1225 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001226 v9.CheckSourceFailure(lines, 'E1376: Object variable "val" accessible only using class "A" object', 1)
Ernie Raelcf138d42023-09-06 20:45:03 +02001227
1228 # Access from child class extending a class:
1229 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001230 vim9script
1231 class A
1232 this.ro_obj_var = 10
1233 public this.rw_obj_var = 20
1234 this._priv_obj_var = 30
1235 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001236
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001237 class B extends A
1238 def Foo()
1239 var x: number
1240 x = this.ro_obj_var
1241 this.ro_obj_var = 0
1242 x = this.rw_obj_var
1243 this.rw_obj_var = 0
1244 x = this._priv_obj_var
1245 this._priv_obj_var = 0
1246 enddef
1247 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001248
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001249 var b = B.new()
1250 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001251 END
1252 v9.CheckSourceSuccess(lines)
1253enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001254
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001255" Test for class variable access
1256def Test_class_variable_access()
1257 # Test for "static" cannot be abbreviated
1258 var lines =<< trim END
1259 vim9script
1260 class Something
1261 stat this.val = 1
1262 endclass
1263 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001264 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: stat this.val = 1', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001265
1266 # Test for "static" cannot be followed by "this".
1267 lines =<< trim END
1268 vim9script
1269 class Something
1270 static this.val = 1
1271 endclass
1272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001273 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a variable name', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001274
1275 # Test for "static" cannot be followed by "public".
1276 lines =<< trim END
1277 vim9script
1278 class Something
1279 static public val = 1
1280 endclass
1281 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001282 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required', 3)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001283
1284 # A readonly class variable cannot be modified from a child class
1285 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001286 vim9script
1287 class A
1288 static ro_class_var = 40
1289 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001290
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001291 class B extends A
1292 def Foo()
1293 A.ro_class_var = 50
1294 enddef
1295 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001297 var b = B.new()
1298 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001299 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001300 v9.CheckSourceFailure(lines, 'E1335: Variable "ro_class_var" in class "A" is not writable', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001301
1302 # A private class variable cannot be accessed from a child class
1303 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001304 vim9script
1305 class A
1306 static _priv_class_var = 60
1307 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001308
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001309 class B extends A
1310 def Foo()
1311 var i = A._priv_class_var
1312 enddef
1313 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001314
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001315 var b = B.new()
1316 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001317 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001318 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001319
1320 # A private class variable cannot be modified from a child class
1321 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001322 vim9script
1323 class A
1324 static _priv_class_var = 60
1325 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001326
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001327 class B extends A
1328 def Foo()
1329 A._priv_class_var = 0
1330 enddef
1331 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001332
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001333 var b = B.new()
1334 b.Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001336 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _priv_class_var', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001337
1338 # Access from child class extending a class and from script context
1339 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001340 vim9script
1341 class A
1342 static ro_class_var = 10
1343 public static rw_class_var = 20
1344 static _priv_class_var = 30
1345 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001346
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001347 class B extends A
1348 def Foo()
1349 var x: number
1350 x = A.ro_class_var
1351 assert_equal(10, x)
1352 x = A.rw_class_var
1353 assert_equal(25, x)
1354 A.rw_class_var = 20
1355 assert_equal(20, A.rw_class_var)
1356 enddef
1357 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001358
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001359 assert_equal(10, A.ro_class_var)
1360 assert_equal(20, A.rw_class_var)
1361 A.rw_class_var = 25
1362 assert_equal(25, A.rw_class_var)
1363 var b = B.new()
1364 b.Foo()
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001365 END
1366 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001367enddef
1368
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001369def Test_class_object_compare()
1370 var class_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001371 vim9script
1372 class Item
1373 this.nr = 0
1374 this.name = 'xx'
1375 endclass
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001376 END
1377
1378 # used at the script level and in a compiled function
1379 var test_lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001380 var i1 = Item.new()
1381 assert_equal(i1, i1)
1382 assert_true(i1 is i1)
1383 var i2 = Item.new()
1384 assert_equal(i1, i2)
1385 assert_false(i1 is i2)
1386 var i3 = Item.new(0, 'xx')
1387 assert_equal(i1, i3)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001388
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001389 var io1 = Item.new(1, 'xx')
1390 assert_notequal(i1, io1)
1391 var io2 = Item.new(0, 'yy')
1392 assert_notequal(i1, io2)
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001393 END
1394
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001395 v9.CheckSourceSuccess(class_lines + test_lines)
1396 v9.CheckSourceSuccess(
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001397 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001398
1399 for op in ['>', '>=', '<', '<=', '=~', '!~']
1400 var op_lines = [
1401 'var i1 = Item.new()',
1402 'var i2 = Item.new()',
1403 'echo i1 ' .. op .. ' i2',
1404 ]
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001405 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object', 8)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001406 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001407 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001408 endfor
1409enddef
1410
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001411def Test_object_type()
1412 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001413 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001414
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001415 class One
1416 this.one = 1
1417 endclass
1418 class Two
1419 this.two = 2
1420 endclass
1421 class TwoMore extends Two
1422 this.more = 9
1423 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001424
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001425 var o: One = One.new()
1426 var t: Two = Two.new()
1427 var m: TwoMore = TwoMore.new()
1428 var tm: Two = TwoMore.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001429
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001430 t = m
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001431 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001432 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001433
1434 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001435 vim9script
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001436
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001437 class One
1438 this.one = 1
1439 endclass
1440 class Two
1441 this.two = 2
1442 endclass
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001443
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001444 var o: One = Two.new()
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001445 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001446 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>', 10)
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001447
1448 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001449 vim9script
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001450
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001451 interface One
1452 def GetMember(): number
1453 endinterface
1454 class Two implements One
1455 this.one = 1
1456 def GetMember(): number
1457 return this.one
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001458 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001459 endclass
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001460
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001461 var o: One = Two.new(5)
1462 assert_equal(5, o.GetMember())
1463 END
1464 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001465
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001466 lines =<< trim END
1467 vim9script
1468
1469 class Num
1470 this.n: number = 0
1471 endclass
1472
1473 def Ref(name: string): func(Num): Num
1474 return (arg: Num): Num => {
1475 return eval(name)(arg)
1476 }
1477 enddef
1478
1479 const Fn = Ref('Double')
1480 var Double = (m: Num): Num => Num.new(m.n * 2)
1481
1482 echo Fn(Num.new(4))
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001483 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001484 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001485enddef
1486
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001487def Test_class_member()
1488 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001489 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001490 vim9script
1491 class TextPos
1492 this.lnum = 1
1493 this.col = 1
1494 static counter = 0
1495 static _secret = 7
1496 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001497
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001498 static def AddToCounter(nr: number)
1499 counter += nr
1500 enddef
1501 endclass
Bram Moolenaard505d172022-12-18 21:42:55 +00001502
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001503 assert_equal(0, TextPos.counter)
1504 TextPos.AddToCounter(3)
1505 assert_equal(3, TextPos.counter)
1506 assert_fails('echo TextPos.noSuchMember', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001508 def GetCounter(): number
1509 return TextPos.counter
1510 enddef
1511 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001512
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001513 assert_fails('TextPos.noSuchMember = 2', 'E1337: Class variable "noSuchMember" not found in class "TextPos"')
1514 assert_fails('TextPos.counter = 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
1515 assert_fails('TextPos.counter += 5', 'E1335: Variable "counter" in class "TextPos" is not writable')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001516
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001517 assert_fails('echo TextPos._secret', 'E1333: Cannot access private variable: _secret')
1518 assert_fails('TextPos._secret = 8', 'E1333: Cannot access private variable: _secret')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001519
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001520 assert_equal(42, TextPos.anybody)
1521 TextPos.anybody = 12
1522 assert_equal(12, TextPos.anybody)
1523 TextPos.anybody += 5
1524 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001525 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001526 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001527
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001528 # example in the help
1529 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001530 vim9script
1531 class OtherThing
1532 this.size: number
1533 static totalSize: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001534
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001535 def new(this.size)
1536 totalSize += this.size
1537 enddef
1538 endclass
1539 assert_equal(0, OtherThing.totalSize)
1540 var to3 = OtherThing.new(3)
1541 assert_equal(3, OtherThing.totalSize)
1542 var to7 = OtherThing.new(7)
1543 assert_equal(10, OtherThing.totalSize)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001544 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001545 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001546
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001547 # using static class member twice
1548 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001549 vim9script
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001550
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001551 class HTML
1552 static author: string = 'John Doe'
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001554 static def MacroSubstitute(s: string): string
1555 return substitute(s, '{{author}}', author, 'gi')
1556 enddef
1557 endclass
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001559 assert_equal('some text', HTML.MacroSubstitute('some text'))
1560 assert_equal('some text', HTML.MacroSubstitute('some text'))
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001561 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001562 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001563
Bram Moolenaar62a69232023-01-24 15:07:04 +00001564 # access private member in lambda
1565 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001566 vim9script
Bram Moolenaar62a69232023-01-24 15:07:04 +00001567
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001568 class Foo
1569 this._x: number = 0
Bram Moolenaar62a69232023-01-24 15:07:04 +00001570
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001571 def Add(n: number): number
1572 const F = (): number => this._x + n
1573 return F()
1574 enddef
1575 endclass
Bram Moolenaar62a69232023-01-24 15:07:04 +00001576
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001577 var foo = Foo.new()
1578 assert_equal(5, foo.Add(5))
Bram Moolenaar62a69232023-01-24 15:07:04 +00001579 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001580 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001581
h-east2bd6a092023-05-19 19:01:17 +01001582 # access private member in lambda body
1583 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001584 vim9script
h-east2bd6a092023-05-19 19:01:17 +01001585
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001586 class Foo
1587 this._x: number = 6
h-east2bd6a092023-05-19 19:01:17 +01001588
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001589 def Add(n: number): number
1590 var Lam = () => {
1591 this._x = this._x + n
1592 }
1593 Lam()
1594 return this._x
1595 enddef
1596 endclass
h-east2bd6a092023-05-19 19:01:17 +01001597
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001598 var foo = Foo.new()
1599 assert_equal(13, foo.Add(7))
h-east2bd6a092023-05-19 19:01:17 +01001600 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001601 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001602
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001603 # check shadowing
1604 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001605 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001606
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001607 class Some
1608 static count = 0
1609 def Method(count: number)
1610 echo count
1611 enddef
1612 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001613
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001614 var s = Some.new()
1615 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001617 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001618
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02001619 # Use a local variable in a method with the same name as a class variable
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001620 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001621 vim9script
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001622
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001623 class Some
1624 static count = 0
1625 def Method(arg: number)
1626 var count = 3
1627 echo arg count
1628 enddef
1629 endclass
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001630
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001631 var s = Some.new()
1632 s.Method(7)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001634 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001635
1636 # Test for using an invalid type for a member variable
1637 lines =<< trim END
1638 vim9script
1639 class A
1640 this.val: xxx
1641 endclass
1642 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001643 v9.CheckSourceFailure(lines, 'E1010: Type not recognized: xxx', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001644
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001645 # Test for setting a member on a null object
1646 lines =<< trim END
1647 vim9script
1648 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001649 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001650 endclass
1651
1652 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001653 var obj: A
1654 obj.val = ""
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001655 enddef
1656 F()
1657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001658 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001659
1660 # Test for accessing a member on a null object
1661 lines =<< trim END
1662 vim9script
1663 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001664 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001665 endclass
1666
1667 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001668 var obj: A
1669 echo obj.val
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001670 enddef
1671 F()
1672 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001673 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001674
1675 # Test for setting a member on a null object, at script level
1676 lines =<< trim END
1677 vim9script
1678 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001679 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001680 endclass
1681
1682 var obj: A
1683 obj.val = ""
1684 END
1685 # FIXME(in source): this should give E1360 as well!
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001686 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001687
1688 # Test for accessing a member on a null object, at script level
1689 lines =<< trim END
1690 vim9script
1691 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001692 this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001693 endclass
1694
1695 var obj: A
1696 echo obj.val
1697 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001698 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 7)
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001699
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001700 # Test for no space before or after the '=' when initializing a member
1701 # variable
1702 lines =<< trim END
1703 vim9script
1704 class A
1705 this.val: number= 10
1706 endclass
1707 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001708 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001709 lines =<< trim END
1710 vim9script
1711 class A
1712 this.val: number =10
1713 endclass
1714 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001715 v9.CheckSourceFailure(lines, "E1004: White space required before and after '='", 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001716
1717 # Access a non-existing member
1718 lines =<< trim END
1719 vim9script
1720 class A
1721 endclass
1722 var a = A.new()
1723 var v = a.bar
1724 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001725 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": bar', 5)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001726enddef
1727
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001728func Test_class_garbagecollect()
1729 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001730 vim9script
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001731
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001732 class Point
1733 this.p = [2, 3]
1734 static pl = ['a', 'b']
1735 static pd = {a: 'a', b: 'b'}
1736 endclass
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001737
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001738 echo Point.pl Point.pd
1739 call test_garbagecollect_now()
1740 echo Point.pl Point.pd
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001742 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001743
1744 let lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001745 vim9script
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001746
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001747 interface View
1748 endinterface
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001749
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001750 class Widget
1751 this.view: View
1752 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001753
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001754 class MyView implements View
1755 this.widget: Widget
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001756
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001757 def new()
1758 # this will result in a circular reference to this object
1759 this.widget = Widget.new(this)
1760 enddef
1761 endclass
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001762
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001763 var view = MyView.new()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001764
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001765 # overwrite "view", will be garbage-collected next
1766 view = MyView.new()
1767 test_garbagecollect_now()
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001768 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001769 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001770endfunc
1771
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001772" Test interface garbage collection
1773func Test_interface_garbagecollect()
1774 let lines =<< trim END
1775 vim9script
1776
1777 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001778 this.ro_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001779
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001780 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001781 endinterface
1782
1783 class A implements I
1784 static ro_class_var: number = 10
1785 public static rw_class_var: number = 20
1786 static _priv_class_var: number = 30
1787 this.ro_obj_var: number = 40
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001788 this._priv_obj_var: number = 60
1789
1790 static def _ClassBar(): number
1791 return _priv_class_var
1792 enddef
1793
1794 static def ClassFoo(): number
1795 return ro_class_var + rw_class_var + A._ClassBar()
1796 enddef
1797
1798 def _ObjBar(): number
1799 return this._priv_obj_var
1800 enddef
1801
1802 def ObjFoo(): number
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001803 return this.ro_obj_var + this._ObjBar()
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001804 enddef
1805 endclass
1806
1807 assert_equal(60, A.ClassFoo())
1808 var o = A.new()
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001809 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001810 test_garbagecollect_now()
1811 assert_equal(60, A.ClassFoo())
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02001812 assert_equal(100, o.ObjFoo())
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001813 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001814 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001815endfunc
1816
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001817def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001818 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001819 vim9script
1820 class Value
1821 this.value = 0
1822 static objects = 0
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001823
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001824 def new(v: number)
1825 this.value = v
1826 ++objects
1827 enddef
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001828
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001829 static def GetCount(): number
1830 return objects
1831 enddef
1832 endclass
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001833
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001834 assert_equal(0, Value.GetCount())
1835 var v1 = Value.new(2)
1836 assert_equal(1, Value.GetCount())
1837 var v2 = Value.new(7)
1838 assert_equal(2, Value.GetCount())
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001839 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001840 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001841
1842 # Test for cleaning up after a class definition failure when using class
1843 # functions.
1844 lines =<< trim END
1845 vim9script
1846 class A
1847 static def Foo()
1848 enddef
1849 aaa
1850 endclass
1851 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001852 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: aaa', 5)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001853
1854 # Test for calling a class method from another class method without the class
1855 # name prefix.
1856 lines =<< trim END
1857 vim9script
1858 class A
1859 static myList: list<number> = [1]
1860 static def Foo(n: number)
1861 myList->add(n)
1862 enddef
1863 static def Bar()
1864 Foo(2)
1865 enddef
1866 def Baz()
1867 Foo(3)
1868 enddef
1869 endclass
1870 A.Bar()
1871 var a = A.new()
1872 a.Baz()
1873 assert_equal([1, 2, 3], A.myList)
1874 END
1875 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001876enddef
1877
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001878def Test_class_defcompile()
1879 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001880 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001881
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001882 class C
1883 def Fo(i: number): string
1884 return i
1885 enddef
1886 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001887
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001888 defcompile C.Fo
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001889 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001890 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number', 1)
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001891
1892 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001893 vim9script
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001894
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001895 class C
1896 static def Fc(): number
1897 return 'x'
1898 enddef
1899 endclass
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001900
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001901 defcompile C.Fc
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001902 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001903 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001904
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001905 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001906 vim9script
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001907
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001908 class C
1909 static def new()
1910 enddef
1911 endclass
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001912
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001913 defcompile C.new
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001914 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001915 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" method as static', 5)
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001916
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001917 # Trying to compile a function using a non-existing class variable
1918 lines =<< trim END
1919 vim9script
1920 defcompile x.Foo()
1921 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001922 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001923
1924 # Trying to compile a function using a variable which is not a class
1925 lines =<< trim END
1926 vim9script
1927 var x: number
1928 defcompile x.Foo()
1929 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001930 v9.CheckSourceFailure(lines, 'E475: Invalid argument: x.Foo()', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001931
1932 # Trying to compile a function without specifying the name
1933 lines =<< trim END
1934 vim9script
1935 class A
1936 endclass
1937 defcompile A.
1938 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001939 v9.CheckSourceFailure(lines, 'E475: Invalid argument: A.', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001940
1941 # Trying to compile a non-existing class object member function
1942 lines =<< trim END
1943 vim9script
1944 class A
1945 endclass
1946 var a = A.new()
1947 defcompile a.Foo()
1948 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001949 v9.CheckSourceFailureList(lines, ['E1326: Variable not found on object "A": Foo', 'E475: Invalid argument: a.Foo()'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001950enddef
1951
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001952def Test_class_object_to_string()
1953 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001954 vim9script
1955 class TextPosition
1956 this.lnum = 1
1957 this.col = 22
1958 endclass
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001959
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001960 assert_equal("class TextPosition", string(TextPosition))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001961
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001962 var pos = TextPosition.new()
1963 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001964 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001965 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001966enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001967
Bram Moolenaar554d0312023-01-05 19:59:18 +00001968def Test_interface_basics()
1969 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001970 vim9script
1971 interface Something
1972 this.ro_var: list<number>
1973 def GetCount(): number
1974 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00001975 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001976 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001977
1978 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001979 interface SomethingWrong
1980 static count = 7
1981 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00001982 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001983 v9.CheckSourceFailure(lines, 'E1342: Interface can only be defined in Vim9 script', 1)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001984
1985 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001986 vim9script
Bram Moolenaar554d0312023-01-05 19:59:18 +00001987
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001988 interface Some
1989 this.value: number
1990 def Method(value: number)
1991 endinterface
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001992 END
h-east61378a12023-04-18 19:07:29 +01001993 # The argument name and the object member name are the same, but this is not a
1994 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001995 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001996
1997 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02001998 vim9script
1999 interface somethingWrong
2000 static count = 7
2001 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002002 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002003 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong', 2)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002004
2005 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002006 vim9script
2007 interface SomethingWrong
2008 this.value: string
2009 this.count = 7
2010 def GetCount(): number
2011 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002012 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002013 v9.CheckSourceFailure(lines, 'E1344: Cannot initialize a variable in an interface', 4)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002014
2015 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002016 vim9script
2017 interface SomethingWrong
2018 this.value: string
2019 this.count: number
2020 def GetCount(): number
2021 return 5
2022 enddef
2023 endinterface
Bram Moolenaar554d0312023-01-05 19:59:18 +00002024 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002025 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5', 6)
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002026
2027 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002028 vim9script
2029 export interface EnterExit
2030 def Enter(): void
2031 def Exit(): void
2032 endinterface
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002033 END
2034 writefile(lines, 'XdefIntf.vim', 'D')
2035
2036 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002037 vim9script
2038 import './XdefIntf.vim' as defIntf
2039 export def With(ee: defIntf.EnterExit, F: func)
2040 ee.Enter()
2041 try
2042 F()
2043 finally
2044 ee.Exit()
2045 endtry
2046 enddef
Bram Moolenaar53f54e42023-01-26 20:36:56 +00002047 END
2048 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00002049
2050 var imported =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002051 vim9script
2052 export abstract class EnterExit
2053 def Enter(): void
2054 enddef
2055 def Exit(): void
2056 enddef
2057 endclass
Bram Moolenaar657aea72023-01-27 13:16:19 +00002058 END
2059 writefile(imported, 'XdefIntf2.vim', 'D')
2060
2061 lines[1] = " import './XdefIntf2.vim' as defIntf"
2062 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00002063enddef
2064
Bram Moolenaar94674f22023-01-06 18:42:20 +00002065def Test_class_implements_interface()
2066 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002067 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002068
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002069 interface Some
2070 this.count: number
2071 def Method(nr: number)
2072 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002073
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002074 class SomeImpl implements Some
2075 this.count: number
2076 def Method(nr: number)
2077 echo nr
2078 enddef
2079 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002080
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002081 interface Another
2082 this.member: string
2083 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002084
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002085 class AnotherImpl implements Some, Another
2086 this.member = 'abc'
2087 this.count = 20
2088 def Method(nr: number)
2089 echo nr
2090 enddef
2091 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002092 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002093 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002094
2095 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002096 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002097
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002098 interface Some
2099 this.count: number
2100 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002101
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002102 class SomeImpl implements Some implements Some
2103 this.count: number
2104 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002105 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002106 v9.CheckSourceFailure(lines, 'E1350: Duplicate "implements"', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002107
2108 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002109 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002110
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002111 interface Some
2112 this.count: number
2113 endinterface
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002114
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002115 class SomeImpl implements Some, Some
2116 this.count: number
2117 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002118 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002119 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some', 7)
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002120
2121 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002122 vim9script
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002123
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002124 interface Some
2125 this.counter: number
2126 def Method(nr: number)
2127 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002128
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002129 class SomeImpl implements Some
2130 this.count: number
2131 def Method(nr: number)
2132 echo nr
2133 enddef
2134 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002135 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002136 v9.CheckSourceFailure(lines, 'E1348: Variable "counter" of interface "Some" is not implemented', 13)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002137
2138 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002139 vim9script
Bram Moolenaar94674f22023-01-06 18:42:20 +00002140
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002141 interface Some
2142 this.count: number
2143 def Methods(nr: number)
2144 endinterface
Bram Moolenaar94674f22023-01-06 18:42:20 +00002145
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002146 class SomeImpl implements Some
2147 this.count: number
2148 def Method(nr: number)
2149 echo nr
2150 enddef
2151 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00002152 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002153 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented', 13)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002154
2155 # Check different order of members in class and interface works.
2156 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002157 vim9script
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002158
2159 interface Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002160 this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002161 this.errpos: number
2162 endinterface
2163
2164 # order of members is opposite of interface
2165 class Failure implements Result
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002166 public this.lnum: number = 5
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002167 this.errpos: number = 42
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002168 this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002169 endclass
2170
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002171 def Test()
2172 var result: Result = Failure.new()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002173
2174 assert_equal('label', result.label)
2175 assert_equal(42, result.errpos)
2176 enddef
2177
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002178 Test()
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002179 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002180 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002181
2182 # Interface name after "extends" doesn't end in a space or NUL character
2183 lines =<< trim END
2184 vim9script
2185 interface A
2186 endinterface
2187 class B extends A"
2188 endclass
2189 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002190 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002191
2192 # Trailing characters after a class name
2193 lines =<< trim END
2194 vim9script
2195 class A bbb
2196 endclass
2197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002198 v9.CheckSourceFailure(lines, 'E488: Trailing characters: bbb', 2)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002199
2200 # using "implements" with a non-existing class
2201 lines =<< trim END
2202 vim9script
2203 class A implements B
2204 endclass
2205 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002206 v9.CheckSourceFailure(lines, 'E1346: Interface name not found: B', 3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002207
2208 # using "implements" with a regular class
2209 lines =<< trim END
2210 vim9script
2211 class A
2212 endclass
2213 class B implements A
2214 endclass
2215 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002216 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: A', 5)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002217
2218 # using "implements" with a variable
2219 lines =<< trim END
2220 vim9script
2221 var T: number = 10
2222 class A implements T
2223 endclass
2224 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002225 v9.CheckSourceFailure(lines, 'E1347: Not a valid interface: T', 4)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002226
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002227 # implements should be followed by a white space
2228 lines =<< trim END
2229 vim9script
2230 interface A
2231 endinterface
2232 class B implements A;
2233 endclass
2234 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002235 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A;', 4)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002236
LemonBoyc5d27442023-08-19 13:02:35 +02002237 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002238 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002239
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002240 interface One
2241 def IsEven(nr: number): bool
2242 endinterface
2243 class Two implements One
2244 def IsEven(nr: number): string
2245 enddef
2246 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002247 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002248 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002249
2250 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002251 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002252
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002253 interface One
2254 def IsEven(nr: number): bool
2255 endinterface
2256 class Two implements One
2257 def IsEven(nr: bool): bool
2258 enddef
2259 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002260 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002261 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool', 9)
LemonBoyc5d27442023-08-19 13:02:35 +02002262
2263 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002264 vim9script
LemonBoyc5d27442023-08-19 13:02:35 +02002265
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002266 interface One
2267 def IsEven(nr: number): bool
2268 endinterface
2269 class Two implements One
2270 def IsEven(nr: number, ...extra: list<number>): bool
2271 enddef
2272 endclass
LemonBoyc5d27442023-08-19 13:02:35 +02002273 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002274 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 +02002275
2276 # access superclass interface members from subclass, mix variable order
2277 lines =<< trim END
2278 vim9script
2279
2280 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002281 this.mvar1: number
2282 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002283 endinterface
2284
2285 # NOTE: the order is swapped
2286 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002287 this.mvar2: number
2288 this.mvar1: number
2289 public static svar2: number
2290 public static svar1: number
2291 def new()
2292 svar1 = 11
2293 svar2 = 12
2294 this.mvar1 = 111
2295 this.mvar2 = 112
2296 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002297 endclass
2298
2299 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002300 def new()
2301 this.mvar1 = 121
2302 this.mvar2 = 122
2303 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002304 endclass
2305
2306 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002307 def new()
2308 this.mvar1 = 131
2309 this.mvar2 = 132
2310 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002311 endclass
2312
Ernie Raelcf138d42023-09-06 20:45:03 +02002313 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002314 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002315 enddef
2316
2317 var oa = A.new()
2318 var ob = B.new()
2319 var oc = C.new()
2320
Ernie Raelcf138d42023-09-06 20:45:03 +02002321 assert_equal([111, 112], F2(oa))
2322 assert_equal([121, 122], F2(ob))
2323 assert_equal([131, 132], F2(oc))
2324 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002325 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002326
2327 # Access superclass interface members from subclass, mix variable order.
2328 # Two interfaces, one on A, one on B; each has both kinds of variables
2329 lines =<< trim END
2330 vim9script
2331
2332 interface I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002333 this.mvar1: number
2334 this.mvar2: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002335 endinterface
2336
2337 interface I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002338 this.mvar3: number
2339 this.mvar4: number
Ernie Raelcf138d42023-09-06 20:45:03 +02002340 endinterface
2341
2342 class A implements I1
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002343 public static svar1: number
2344 public static svar2: number
2345 this.mvar1: number
2346 this.mvar2: number
2347 def new()
2348 svar1 = 11
2349 svar2 = 12
2350 this.mvar1 = 111
2351 this.mvar2 = 112
2352 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002353 endclass
2354
2355 class B extends A implements I2
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002356 static svar3: number
2357 static svar4: number
2358 this.mvar3: number
2359 this.mvar4: number
2360 def new()
2361 svar3 = 23
2362 svar4 = 24
2363 this.mvar1 = 121
2364 this.mvar2 = 122
2365 this.mvar3 = 123
2366 this.mvar4 = 124
2367 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002368 endclass
2369
2370 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002371 public static svar5: number
2372 def new()
2373 svar5 = 1001
2374 this.mvar1 = 131
2375 this.mvar2 = 132
2376 this.mvar3 = 133
2377 this.mvar4 = 134
2378 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02002379 endclass
2380
Ernie Raelcf138d42023-09-06 20:45:03 +02002381 def F2(i: I1): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002382 return [ i.mvar1, i.mvar2 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002383 enddef
2384
Ernie Raelcf138d42023-09-06 20:45:03 +02002385 def F4(i: I2): list<number>
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002386 return [ i.mvar3, i.mvar4 ]
Ernie Raelcf138d42023-09-06 20:45:03 +02002387 enddef
2388
Ernie Raelcf138d42023-09-06 20:45:03 +02002389 var oa = A.new()
2390 var ob = B.new()
2391 var oc = C.new()
2392
Ernie Raelcf138d42023-09-06 20:45:03 +02002393 assert_equal([[111, 112]], [F2(oa)])
2394 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2395 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002396 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002397 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02002398
2399 # Using two interface names without a space after the ","
2400 lines =<< trim END
2401 vim9script
2402 interface A
2403 endinterface
2404 interface B
2405 endinterface
2406 class C implements A,B
2407 endclass
2408 END
2409 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A,B', 6)
2410
2411 # No interface name after a comma
2412 lines =<< trim END
2413 vim9script
2414 interface A
2415 endinterface
2416 class B implements A,
2417 endclass
2418 END
2419 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 4)
2420
2421 # No interface name after implements
2422 lines =<< trim END
2423 vim9script
2424 class A implements
2425 endclass
2426 END
2427 v9.CheckSourceFailure(lines, 'E1389: Missing name after implements', 2)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002428enddef
2429
Bram Moolenaard0200c82023-01-28 15:19:40 +00002430def Test_call_interface_method()
2431 var lines =<< trim END
2432 vim9script
2433 interface Base
2434 def Enter(): void
2435 endinterface
2436
2437 class Child implements Base
2438 def Enter(): void
2439 g:result ..= 'child'
2440 enddef
2441 endclass
2442
2443 def F(obj: Base)
2444 obj.Enter()
2445 enddef
2446
2447 g:result = ''
2448 F(Child.new())
2449 assert_equal('child', g:result)
2450 unlet g:result
2451 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002452 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002453
2454 lines =<< trim END
2455 vim9script
2456 class Base
2457 def Enter(): void
2458 g:result ..= 'base'
2459 enddef
2460 endclass
2461
2462 class Child extends Base
2463 def Enter(): void
2464 g:result ..= 'child'
2465 enddef
2466 endclass
2467
2468 def F(obj: Base)
2469 obj.Enter()
2470 enddef
2471
2472 g:result = ''
2473 F(Child.new())
2474 assert_equal('child', g:result)
2475 unlet g:result
2476 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002477 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002478
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002479 # method of interface returns a value
2480 lines =<< trim END
2481 vim9script
2482 interface Base
2483 def Enter(): string
2484 endinterface
2485
2486 class Child implements Base
2487 def Enter(): string
2488 g:result ..= 'child'
2489 return "/resource"
2490 enddef
2491 endclass
2492
2493 def F(obj: Base)
2494 var r = obj.Enter()
2495 g:result ..= r
2496 enddef
2497
2498 g:result = ''
2499 F(Child.new())
2500 assert_equal('child/resource', g:result)
2501 unlet g:result
2502 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002503 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002504
2505 lines =<< trim END
2506 vim9script
2507 class Base
2508 def Enter(): string
2509 return null_string
2510 enddef
2511 endclass
2512
2513 class Child extends Base
2514 def Enter(): string
2515 g:result ..= 'child'
2516 return "/resource"
2517 enddef
2518 endclass
2519
2520 def F(obj: Base)
2521 var r = obj.Enter()
2522 g:result ..= r
2523 enddef
2524
2525 g:result = ''
2526 F(Child.new())
2527 assert_equal('child/resource', g:result)
2528 unlet g:result
2529 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002530 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002531
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002532 # No class that implements the interface.
2533 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002534 vim9script
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002535
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002536 interface IWithEE
2537 def Enter(): any
2538 def Exit(): void
2539 endinterface
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002540
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002541 def With1(ee: IWithEE, F: func)
2542 var r = ee.Enter()
2543 enddef
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002544
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002545 defcompile
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002547 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002548enddef
2549
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002550def Test_class_used_as_type()
2551 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002552 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002553
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002554 class Point
2555 this.x = 0
2556 this.y = 0
2557 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002558
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002559 var p: Point
2560 p = Point.new(2, 33)
2561 assert_equal(2, p.x)
2562 assert_equal(33, p.y)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002563 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002564 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002565
2566 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002567 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002568
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002569 interface HasX
2570 this.x: number
2571 endinterface
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002572
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002573 class Point implements HasX
2574 this.x = 0
2575 this.y = 0
2576 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002577
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002578 var p: Point
2579 p = Point.new(2, 33)
2580 var hx = p
2581 assert_equal(2, hx.x)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002582 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002583 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002584
2585 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002586 vim9script
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002587
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002588 class Point
2589 this.x = 0
2590 this.y = 0
2591 endclass
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002592
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002593 var p: Point
2594 p = 'text'
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002595 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002596 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string', 9)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002597enddef
2598
Bram Moolenaar83677162023-01-08 19:54:10 +00002599def Test_class_extends()
2600 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002601 vim9script
2602 class Base
2603 this.one = 1
2604 def GetOne(): number
2605 return this.one
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002606 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002607 endclass
2608 class Child extends Base
2609 this.two = 2
2610 def GetTotal(): number
2611 return this.one + this.two
2612 enddef
2613 endclass
2614 var o = Child.new()
2615 assert_equal(1, o.one)
2616 assert_equal(2, o.two)
2617 assert_equal(1, o.GetOne())
2618 assert_equal(3, o.GetTotal())
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002619 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002620 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002621
2622 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002623 vim9script
2624 class Base
2625 this.one = 1
2626 endclass
2627 class Child extends Base
2628 this.two = 2
2629 endclass
2630 var o = Child.new(3, 44)
2631 assert_equal(3, o.one)
2632 assert_equal(44, o.two)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002633 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002634 v9.CheckSourceSuccess(lines)
2635
2636 lines =<< trim END
2637 vim9script
2638 class Base
2639 this.one = 1
2640 endclass
2641 class Child extends Base extends Base
2642 this.two = 2
2643 endclass
2644 END
2645 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"', 5)
2646
2647 lines =<< trim END
2648 vim9script
2649 class Child extends BaseClass
2650 this.two = 2
2651 endclass
2652 END
2653 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass', 4)
2654
2655 lines =<< trim END
2656 vim9script
2657 var SomeVar = 99
2658 class Child extends SomeVar
2659 this.two = 2
2660 endclass
2661 END
2662 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar', 5)
2663
2664 lines =<< trim END
2665 vim9script
2666 class Base
2667 this.name: string
2668 def ToString(): string
2669 return this.name
2670 enddef
2671 endclass
2672
2673 class Child extends Base
2674 this.age: number
2675 def ToString(): string
2676 return super.ToString() .. ': ' .. this.age
2677 enddef
2678 endclass
2679
2680 var o = Child.new('John', 42)
2681 assert_equal('John: 42', o.ToString())
2682 END
2683 v9.CheckSourceSuccess(lines)
2684
2685 lines =<< trim END
2686 vim9script
2687 class Child
2688 this.age: number
2689 def ToString(): number
2690 return this.age
2691 enddef
2692 def ToString(): string
2693 return this.age
2694 enddef
2695 endclass
2696 END
2697 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString', 9)
2698
2699 lines =<< trim END
2700 vim9script
2701 class Child
2702 this.age: number
2703 def ToString(): string
2704 return super .ToString() .. ': ' .. this.age
2705 enddef
2706 endclass
2707 var o = Child.new(42)
2708 echo o.ToString()
2709 END
2710 v9.CheckSourceFailure(lines, 'E1356: "super" must be followed by a dot', 1)
2711
2712 lines =<< trim END
2713 vim9script
2714 class Base
2715 this.name: string
2716 def ToString(): string
2717 return this.name
2718 enddef
2719 endclass
2720
2721 var age = 42
2722 def ToString(): string
2723 return super.ToString() .. ': ' .. age
2724 enddef
2725 echo ToString()
2726 END
2727 v9.CheckSourceFailure(lines, 'E1357: Using "super" not in a class method', 1)
2728
2729 lines =<< trim END
2730 vim9script
2731 class Child
2732 this.age: number
2733 def ToString(): string
2734 return super.ToString() .. ': ' .. this.age
2735 enddef
2736 endclass
2737 var o = Child.new(42)
2738 echo o.ToString()
2739 END
2740 v9.CheckSourceFailure(lines, 'E1358: Using "super" not in a child class', 1)
2741
2742 lines =<< trim END
2743 vim9script
2744 class Base
2745 this.name: string
2746 static def ToString(): string
2747 return 'Base class'
2748 enddef
2749 endclass
2750
2751 class Child extends Base
2752 this.age: number
2753 def ToString(): string
2754 return Base.ToString() .. ': ' .. this.age
2755 enddef
2756 endclass
2757
2758 var o = Child.new('John', 42)
2759 assert_equal('Base class: 42', o.ToString())
2760 END
2761 v9.CheckSourceSuccess(lines)
2762
2763 lines =<< trim END
2764 vim9script
2765 class Base
2766 this.value = 1
2767 def new(init: number)
2768 this.value = number + 1
2769 enddef
2770 endclass
2771 class Child extends Base
2772 def new()
2773 this.new(3)
2774 enddef
2775 endclass
2776 var c = Child.new()
2777 END
2778 v9.CheckSourceFailure(lines, 'E1385: Class method "new" accessible only using class "Child"', 1)
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002779
2780 # base class with more than one object member
2781 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002782 vim9script
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002783
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002784 class Result
2785 this.success: bool
2786 this.value: any = null
2787 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002788
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002789 class Success extends Result
2790 def new(this.value = v:none)
2791 this.success = true
2792 enddef
2793 endclass
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002794
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002795 var v = Success.new('asdf')
2796 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002797 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002798 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002799
2800 # class name after "extends" doesn't end in a space or NUL character
2801 lines =<< trim END
2802 vim9script
2803 class A
2804 endclass
2805 class B extends A"
2806 endclass
2807 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002808 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A"', 4)
Bram Moolenaar83677162023-01-08 19:54:10 +00002809enddef
2810
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002811def Test_using_base_class()
2812 var lines =<< trim END
2813 vim9script
2814
2815 class BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002816 def Enter(): any
2817 return null
2818 enddef
2819 def Exit(resource: any): void
2820 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002821 endclass
2822
2823 class ChildEE extends BaseEE
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002824 def Enter(): any
2825 return 42
2826 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002827
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002828 def Exit(resource: number): void
2829 g:result ..= '/exit'
2830 enddef
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002831 endclass
2832
2833 def With(ee: BaseEE)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002834 var r = ee.Enter()
2835 try
2836 g:result ..= r
2837 finally
2838 g:result ..= '/finally'
2839 ee.Exit(r)
2840 endtry
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002841 enddef
2842
2843 g:result = ''
2844 With(ChildEE.new())
2845 assert_equal('42/finally/exit', g:result)
2846 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002847 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002848 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002849
2850 # Using super, Child invokes Base method which has optional arg. #12471
2851 lines =<< trim END
2852 vim9script
2853
2854 class Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002855 this.success: bool = false
2856 def Method(arg = 0)
2857 this.success = true
2858 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002859 endclass
2860
2861 class Child extends Base
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002862 def new()
2863 super.Method()
2864 enddef
Ernie Rael114ec812023-06-04 18:11:35 +01002865 endclass
2866
2867 var obj = Child.new()
2868 assert_equal(true, obj.success)
2869 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002870 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002871enddef
2872
Bram Moolenaara86655a2023-01-12 17:06:27 +00002873def Test_class_import()
2874 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002875 vim9script
2876 export class Animal
2877 this.kind: string
2878 this.name: string
2879 endclass
Bram Moolenaara86655a2023-01-12 17:06:27 +00002880 END
2881 writefile(lines, 'Xanimal.vim', 'D')
2882
2883 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002884 vim9script
2885 import './Xanimal.vim' as animal
Bram Moolenaara86655a2023-01-12 17:06:27 +00002886
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002887 var a: animal.Animal
2888 a = animal.Animal.new('fish', 'Eric')
2889 assert_equal('fish', a.kind)
2890 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002891
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002892 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2893 assert_equal('cat', b.kind)
2894 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002895 END
2896 v9.CheckScriptSuccess(lines)
2897enddef
2898
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002899def Test_abstract_class()
2900 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002901 vim9script
2902 abstract class Base
2903 this.name: string
2904 endclass
2905 class Person extends Base
2906 this.age: number
2907 endclass
2908 var p: Base = Person.new('Peter', 42)
2909 assert_equal('Peter', p.name)
2910 assert_equal(42, p.age)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002911 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002912 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002913
2914 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002915 vim9script
2916 abstract class Base
2917 this.name: string
2918 endclass
2919 class Person extends Base
2920 this.age: number
2921 endclass
2922 var p = Base.new('Peter')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002923 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002924 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new', 8)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002925
2926 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002927 abstract class Base
2928 this.name: string
2929 endclass
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002930 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002931 v9.CheckSourceFailure(lines, 'E1316: Class can only be defined in Vim9 script', 1)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002932
2933 # Abstract class cannot have a "new" function
2934 lines =<< trim END
2935 vim9script
2936 abstract class Base
2937 def new()
2938 enddef
2939 endclass
2940 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002941 v9.CheckSourceFailure(lines, 'E1359: Cannot define a "new" method in an abstract class', 4)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002942enddef
2943
Bram Moolenaar486fc252023-01-18 14:51:07 +00002944def Test_closure_in_class()
2945 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002946 vim9script
Bram Moolenaar486fc252023-01-18 14:51:07 +00002947
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002948 class Foo
2949 this.y: list<string> = ['B']
Bram Moolenaar486fc252023-01-18 14:51:07 +00002950
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002951 def new()
2952 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2953 enddef
2954 endclass
Bram Moolenaar486fc252023-01-18 14:51:07 +00002955
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002956 Foo.new()
2957 assert_equal(['A'], g:result)
Bram Moolenaar486fc252023-01-18 14:51:07 +00002958 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002959 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00002960enddef
2961
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002962def Test_call_constructor_from_legacy()
2963 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002964 vim9script
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002965
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002966 var newCalled = 'false'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002967
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002968 class A
2969 def new()
2970 newCalled = 'true'
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002971 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002972 endclass
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002973
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002974 export def F(options = {}): any
2975 return A
2976 enddef
2977
2978 g:p = F()
2979 legacy call p.new()
2980 assert_equal('true', newCalled)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002981 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002982 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002983enddef
2984
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002985def Test_defer_with_object()
2986 var lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002987 vim9script
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002988
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002989 class CWithEE
2990 def Enter()
2991 g:result ..= "entered/"
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002992 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002993 def Exit()
2994 g:result ..= "exited"
2995 enddef
2996 endclass
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002997
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02002998 def With(ee: CWithEE, F: func)
2999 ee.Enter()
3000 defer ee.Exit()
3001 F()
3002 enddef
3003
3004 g:result = ''
3005 var obj = CWithEE.new()
3006 obj->With(() => {
3007 g:result ..= "called/"
3008 })
3009 assert_equal('entered/called/exited', g:result)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003011 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003012 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00003013
3014 lines =<< trim END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003015 vim9script
Bram Moolenaar313e4722023-02-08 20:55:27 +00003016
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003017 class BaseWithEE
3018 def Enter()
3019 g:result ..= "entered-base/"
Bram Moolenaar313e4722023-02-08 20:55:27 +00003020 enddef
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003021 def Exit()
3022 g:result ..= "exited-base"
3023 enddef
3024 endclass
Bram Moolenaar313e4722023-02-08 20:55:27 +00003025
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003026 class CWithEE extends BaseWithEE
3027 def Enter()
3028 g:result ..= "entered-child/"
3029 enddef
3030 def Exit()
3031 g:result ..= "exited-child"
3032 enddef
3033 endclass
3034
3035 def With(ee: BaseWithEE, F: func)
3036 ee.Enter()
3037 defer ee.Exit()
3038 F()
3039 enddef
3040
3041 g:result = ''
3042 var obj = CWithEE.new()
3043 obj->With(() => {
3044 g:result ..= "called/"
3045 })
3046 assert_equal('entered-child/called/exited-child', g:result)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003047 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003048 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00003049 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00003050enddef
3051
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003052" The following test used to crash Vim (Github issue #12676)
3053def Test_extends_method_crashes_vim()
3054 var lines =<< trim END
3055 vim9script
3056
3057 class Observer
3058 endclass
3059
3060 class Property
3061 this.value: any
3062
3063 def Set(v: any)
3064 if v != this.value
3065 this.value = v
3066 endif
3067 enddef
3068
3069 def Register(observer: Observer)
3070 enddef
3071 endclass
3072
3073 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003074 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003075 endclass
3076
3077 def Observe(obj: Property, who: Observer)
3078 obj.Register(who)
3079 enddef
3080
3081 var p = Bool.new(false)
3082 var myObserver = Observer.new()
3083
3084 Observe(p, myObserver)
3085
3086 p.Set(true)
3087 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003088 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02003089enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003090
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003091" Test for calling a method in a class that is extended
3092def Test_call_method_in_extended_class()
3093 var lines =<< trim END
3094 vim9script
3095
3096 var prop_init_called = false
3097 var prop_register_called = false
3098
3099 class Property
3100 def Init()
3101 prop_init_called = true
3102 enddef
3103
3104 def Register()
3105 prop_register_called = true
3106 enddef
3107 endclass
3108
3109 class Bool extends Property
3110 endclass
3111
3112 def Observe(obj: Property)
3113 obj.Register()
3114 enddef
3115
3116 var p = Property.new()
3117 Observe(p)
3118
3119 p.Init()
3120 assert_true(prop_init_called)
3121 assert_true(prop_register_called)
3122 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003123 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02003124enddef
3125
LemonBoyafe04662023-08-23 21:08:11 +02003126def Test_instanceof()
3127 var lines =<< trim END
3128 vim9script
3129
3130 class Base1
3131 endclass
3132
3133 class Base2 extends Base1
3134 endclass
3135
3136 interface Intf1
3137 endinterface
3138
3139 class Mix1 implements Intf1
3140 endclass
3141
3142 class Base3 extends Mix1
3143 endclass
3144
3145 var b1 = Base1.new()
3146 var b2 = Base2.new()
3147 var b3 = Base3.new()
3148
3149 assert_true(instanceof(b1, Base1))
3150 assert_true(instanceof(b2, Base1))
3151 assert_false(instanceof(b1, Base2))
3152 assert_true(instanceof(b3, Mix1))
3153 assert_false(instanceof(b3, []))
3154 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003155
3156 def Foo()
3157 var a1 = Base1.new()
3158 var a2 = Base2.new()
3159 var a3 = Base3.new()
3160
3161 assert_true(instanceof(a1, Base1))
3162 assert_true(instanceof(a2, Base1))
3163 assert_false(instanceof(a1, Base2))
3164 assert_true(instanceof(a3, Mix1))
3165 assert_false(instanceof(a3, []))
3166 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3167 enddef
3168 Foo()
Ernie Rael3da696d2023-09-19 20:14:18 +02003169
3170 var o_null: Base1
3171 assert_false(instanceof(o_null, Base1))
3172
LemonBoyafe04662023-08-23 21:08:11 +02003173 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003174 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003175enddef
3176
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003177" Test for calling a method in the parent class that is extended partially.
3178" This used to fail with the 'E118: Too many arguments for function: Text' error
3179" message (Github issue #12524).
3180def Test_call_method_in_parent_class()
3181 var lines =<< trim END
3182 vim9script
3183
3184 class Widget
3185 this._lnum: number = 1
3186
3187 def SetY(lnum: number)
3188 this._lnum = lnum
3189 enddef
3190
3191 def Text(): string
3192 return ''
3193 enddef
3194 endclass
3195
3196 class Foo extends Widget
3197 def Text(): string
3198 return '<Foo>'
3199 enddef
3200 endclass
3201
3202 def Stack(w1: Widget, w2: Widget): list<Widget>
3203 w1.SetY(1)
3204 w2.SetY(2)
3205 return [w1, w2]
3206 enddef
3207
3208 var foo1 = Foo.new()
3209 var foo2 = Foo.new()
3210 var l = Stack(foo1, foo2)
3211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003212 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003213enddef
3214
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003215" Test for calling methods from three levels of classes
3216def Test_multi_level_method_call()
3217 var lines =<< trim END
3218 vim9script
3219
3220 var A_func1: number = 0
3221 var A_func2: number = 0
3222 var A_func3: number = 0
3223 var B_func2: number = 0
3224 var B_func3: number = 0
3225 var C_func3: number = 0
3226
3227 class A
3228 def Func1()
3229 A_func1 += 1
3230 enddef
3231
3232 def Func2()
3233 A_func2 += 1
3234 enddef
3235
3236 def Func3()
3237 A_func3 += 1
3238 enddef
3239 endclass
3240
3241 class B extends A
3242 def Func2()
3243 B_func2 += 1
3244 enddef
3245
3246 def Func3()
3247 B_func3 += 1
3248 enddef
3249 endclass
3250
3251 class C extends B
3252 def Func3()
3253 C_func3 += 1
3254 enddef
3255 endclass
3256
3257 def A_CallFuncs(a: A)
3258 a.Func1()
3259 a.Func2()
3260 a.Func3()
3261 enddef
3262
3263 def B_CallFuncs(b: B)
3264 b.Func1()
3265 b.Func2()
3266 b.Func3()
3267 enddef
3268
3269 def C_CallFuncs(c: C)
3270 c.Func1()
3271 c.Func2()
3272 c.Func3()
3273 enddef
3274
3275 var cobj = C.new()
3276 A_CallFuncs(cobj)
3277 B_CallFuncs(cobj)
3278 C_CallFuncs(cobj)
3279 assert_equal(3, A_func1)
3280 assert_equal(0, A_func2)
3281 assert_equal(0, A_func3)
3282 assert_equal(3, B_func2)
3283 assert_equal(0, B_func3)
3284 assert_equal(3, C_func3)
3285 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003286 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003287enddef
3288
3289" Test for using members from three levels of classes
3290def Test_multi_level_member_access()
3291 var lines =<< trim END
3292 vim9script
3293
3294 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003295 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003296 endclass
3297
3298 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003299 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003300 endclass
3301
3302 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003303 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003304 endclass
3305
3306 def A_members(a: A)
3307 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003308 enddef
3309
3310 def B_members(b: B)
3311 b.val1 += 1
3312 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003313 enddef
3314
3315 def C_members(c: C)
3316 c.val1 += 1
3317 c.val2 += 1
3318 c.val3 += 1
3319 enddef
3320
3321 var cobj = C.new()
3322 A_members(cobj)
3323 B_members(cobj)
3324 C_members(cobj)
3325 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003326 assert_equal(2, cobj.val2)
3327 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003328 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003329 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003330enddef
3331
LemonBoy0ffc17a2023-08-20 18:09:11 +02003332" Test expansion of <stack> with class methods.
3333def Test_stack_expansion_with_methods()
3334 var lines =<< trim END
3335 vim9script
3336
3337 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003338 def M1()
3339 F0()
3340 enddef
LemonBoy0ffc17a2023-08-20 18:09:11 +02003341 endclass
3342
3343 def F0()
3344 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3345 enddef
3346
3347 def F()
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003348 C.new().M1()
LemonBoy0ffc17a2023-08-20 18:09:11 +02003349 enddef
3350
3351 F()
3352 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003353 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003354enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003355
3356" Test the return type of the new() constructor
3357def Test_new_return_type()
3358 # new() uses the default return type and there is no return statement
3359 var lines =<< trim END
3360 vim9script
3361
3362 class C
3363 this._bufnr: number
3364
3365 def new(this._bufnr)
3366 if !bufexists(this._bufnr)
3367 this._bufnr = -1
3368 endif
3369 enddef
3370 endclass
3371
3372 var c = C.new(12345)
3373 assert_equal('object<C>', typename(c))
3374
3375 var v1: C
3376 v1 = C.new(12345)
3377 assert_equal('object<C>', typename(v1))
3378
3379 def F()
3380 var v2: C
3381 v2 = C.new(12345)
3382 assert_equal('object<C>', typename(v2))
3383 enddef
3384 F()
3385 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003386 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003387
3388 # new() uses the default return type and an empty 'return' statement
3389 lines =<< trim END
3390 vim9script
3391
3392 class C
3393 this._bufnr: number
3394
3395 def new(this._bufnr)
3396 if !bufexists(this._bufnr)
3397 this._bufnr = -1
3398 return
3399 endif
3400 enddef
3401 endclass
3402
3403 var c = C.new(12345)
3404 assert_equal('object<C>', typename(c))
3405
3406 var v1: C
3407 v1 = C.new(12345)
3408 assert_equal('object<C>', typename(v1))
3409
3410 def F()
3411 var v2: C
3412 v2 = C.new(12345)
3413 assert_equal('object<C>', typename(v2))
3414 enddef
3415 F()
3416 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003417 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003418
3419 # new() uses "any" return type and returns "this"
3420 lines =<< trim END
3421 vim9script
3422
3423 class C
3424 this._bufnr: number
3425
3426 def new(this._bufnr): any
3427 if !bufexists(this._bufnr)
3428 this._bufnr = -1
3429 return this
3430 endif
3431 enddef
3432 endclass
3433 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003434 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 11)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003435
3436 # new() uses 'Dict' return type and returns a Dict
3437 lines =<< trim END
3438 vim9script
3439
3440 class C
3441 this._state: dict<any>
3442
3443 def new(): dict<any>
3444 this._state = {}
3445 return this._state
3446 enddef
3447 endclass
3448
3449 var c = C.new()
3450 assert_equal('object<C>', typename(c))
3451 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003452 v9.CheckSourceFailure(lines, 'E1365: Cannot use a return type with the "new" method', 9)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003453enddef
3454
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003455" Test for checking a member initialization type at run time.
3456def Test_runtime_type_check_for_member_init()
3457 var lines =<< trim END
3458 vim9script
3459
3460 var retnum: bool = false
3461
3462 def F(): any
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003463 retnum = !retnum
3464 if retnum
3465 return 1
3466 else
3467 return "hello"
3468 endif
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003469 enddef
3470
3471 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003472 this._foo: bool = F()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003473 endclass
3474
3475 var c1 = C.new()
3476 var c2 = C.new()
3477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003478 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected bool but got string', 0)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003479enddef
3480
3481" Test for locking a variable referring to an object and reassigning to another
3482" object.
Ernie Raelee865f32023-09-29 19:53:55 +02003483def Test_lockvar_object()
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003484 var lines =<< trim END
3485 vim9script
3486
3487 class C
3488 this.val: number
3489 def new(this.val)
3490 enddef
3491 endclass
3492
3493 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3494 lockvar 2 some_dict
3495
3496 var current: C
3497 current = some_dict['c']
3498 assert_equal(3, current.val)
3499 current = some_dict['b']
3500 assert_equal(2, current.val)
3501
3502 def F()
3503 current = some_dict['c']
3504 enddef
3505
3506 def G()
3507 current = some_dict['b']
3508 enddef
3509
3510 F()
3511 assert_equal(3, current.val)
3512 G()
3513 assert_equal(2, current.val)
3514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003516enddef
3517
Ernie Raelee865f32023-09-29 19:53:55 +02003518" Test trying to lock an object variable from various places
3519def Test_lockvar_object_variable()
3520 # An object variable lockvar has several cases:
3521 # object method, scriptlevel, scriplevel from :def, :def arg
3522 # method arg, static method arg.
3523 # Also different depths
3524
3525 # TODO: handle inside_class in vim9class
3526 # lockvar of a read-only currently fails even if inside
3527
3528 #
3529 # lockvar of read-only object variable
3530 #
3531
3532 # read-only lockvar from object method
3533 var lines =<< trim END
3534 vim9script
3535
3536 class C
3537 this.val1: number
3538 def Lock()
3539 lockvar this.val1
3540 enddef
3541 endclass
3542 var o = C.new(3)
3543 o.Lock()
3544 END
3545 # TODO: wrong error
3546 v9.CheckSourceFailure(lines, 'E1335: Variable "val1" in class "C" is not writable')
3547
3548 # read-only lockvar from scriptlevel
3549 lines =<< trim END
3550 vim9script
3551
3552 class C
3553 this.val2: number
3554 endclass
3555 var o = C.new(3)
3556 lockvar o.val2
3557 END
3558 v9.CheckSourceFailure(lines, 'E1335: Variable "val2" in class "C" is not writable')
3559
3560 # read-only lockvar of scriptlevel variable from def
3561 lines =<< trim END
3562 vim9script
3563
3564 class C
3565 this.val3: number
3566 endclass
3567 var o = C.new(3)
3568 def Lock()
3569 lockvar o.val3
3570 enddef
3571 Lock()
3572 END
3573 v9.CheckSourceFailure(lines, 'E1335: Variable "val3" in class "C" is not writable')
3574
3575 # read-only lockvar of def argument variable
3576 lines =<< trim END
3577 vim9script
3578
3579 class C
3580 this.val4: number
3581 endclass
3582 def Lock(o: C)
3583 lockvar o.val4
3584 enddef
3585 Lock(C.new(3))
3586 END
3587 v9.CheckSourceFailure(lines, 'E1335: Variable "val4" in class "C" is not writable')
3588
3589 # TODO: the following tests use type "any" for argument. Need a run time
3590 # check for access. Probably OK as is for now.
3591
3592 # read-only lockvar from object method arg
3593 lines =<< trim END
3594 vim9script
3595
3596 class C
3597 this.val5: number
3598 def Lock(o_any: any)
3599 lockvar o_any.val5
3600 enddef
3601 endclass
3602 var o = C.new(3)
3603 o.Lock(C.new(5))
3604 END
3605 # TODO: wrong error, tricky since type "any"
3606 v9.CheckSourceFailure(lines, 'E1335: Variable "val5" in class "C" is not writable')
3607
3608 # read-only lockvar from class method arg
3609 lines =<< trim END
3610 vim9script
3611
3612 class C
3613 this.val6: number
3614 static def Lock(o_any: any)
3615 lockvar o_any.val6
3616 enddef
3617 endclass
3618 var o = C.new(3)
3619 C.Lock(o)
3620 END
3621 # TODO: wrong error, tricky since type "any"
3622 v9.CheckSourceFailure(lines, 'E1335: Variable "val6" in class "C" is not writable')
3623
3624 #
3625 # lockvar of public object variable
3626 #
3627
3628 # lockvar from object method
3629 lines =<< trim END
3630 vim9script
3631
3632 class C
3633 public this.val1: number
3634 def Lock()
3635 lockvar this.val1
3636 enddef
3637 endclass
3638 var o = C.new(3)
3639 o.Lock()
3640 END
3641 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "this.val1" in class "C"', 1)
3642
3643 # lockvar from scriptlevel
3644 lines =<< trim END
3645 vim9script
3646
3647 class C
3648 public this.val2: number
3649 endclass
3650 var o = C.new(3)
3651 lockvar o.val2
3652 END
3653 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val2" in class "C"', 7)
3654
3655 # lockvar of scriptlevel variable from def
3656 lines =<< trim END
3657 vim9script
3658
3659 class C
3660 public this.val3: number
3661 endclass
3662 var o = C.new(3)
3663 def Lock()
3664 lockvar o.val3
3665 enddef
3666 Lock()
3667 END
3668 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val3" in class "C"', 1)
3669
3670 # lockvar of def argument variable
3671 lines =<< trim END
3672 vim9script
3673
3674 class C
3675 public this.val4: number
3676 endclass
3677 def Lock(o: C)
3678 lockvar o.val4
3679 enddef
3680 Lock(C.new(3))
3681 END
3682 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o.val4" in class "C"', 1)
3683
3684 # lockvar from object method arg
3685 lines =<< trim END
3686 vim9script
3687
3688 class C
3689 public this.val5: number
3690 def Lock(o_any: any)
3691 lockvar o_any.val5
3692 enddef
3693 endclass
3694 var o = C.new(3)
3695 o.Lock(C.new(5))
3696 END
3697 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val5" in class "C"', 1)
3698
3699 # lockvar from class method arg
3700 lines =<< trim END
3701 vim9script
3702
3703 class C
3704 public this.val6: number
3705 static def Lock(o_any: any)
3706 lockvar o_any.val6
3707 enddef
3708 endclass
3709 var o = C.new(3)
3710 C.Lock(o)
3711 END
3712 v9.CheckSourceFailure(lines, 'E1391: Cannot (un)lock variable "o_any.val6" in class "C"', 1)
3713enddef
3714
3715" Test trying to lock a class variable from various places
3716def Test_lockvar_class_variable()
3717
3718 # lockvar bare static from object method
3719 var lines =<< trim END
3720 vim9script
3721
3722 class C
3723 public static sval1: number
3724 def Lock()
3725 lockvar sval1
3726 enddef
3727 endclass
3728 var o = C.new()
3729 o.Lock()
3730 END
3731 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval1" in class "C"', 1)
3732
3733 # lockvar C.static from object method
3734 lines =<< trim END
3735 vim9script
3736
3737 class C
3738 public static sval2: number
3739 def Lock()
3740 lockvar C.sval2
3741 enddef
3742 endclass
3743 var o = C.new()
3744 o.Lock()
3745 END
3746 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval2" in class "C"', 1)
3747
3748 # lockvar bare static from class method
3749 lines =<< trim END
3750 vim9script
3751
3752 class C
3753 public static sval3: number
3754 static def Lock()
3755 lockvar sval3
3756 enddef
3757 endclass
3758 C.Lock()
3759 END
3760 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval3" in class "C"', 1)
3761
3762 # lockvar C.static from class method
3763 lines =<< trim END
3764 vim9script
3765
3766 class C
3767 public static sval4: number
3768 static def Lock()
3769 lockvar C.sval4
3770 enddef
3771 endclass
3772 C.Lock()
3773 END
3774 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval4" in class "C"', 1)
3775
3776 # lockvar C.static from script level
3777 lines =<< trim END
3778 vim9script
3779
3780 class C
3781 public static sval5: number
3782 endclass
3783 lockvar C.sval5
3784 END
3785 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "C.sval5" in class "C"', 6)
3786
3787 # lockvar o.static from script level
3788 lines =<< trim END
3789 vim9script
3790
3791 class C
3792 public static sval6: number
3793 endclass
3794 var o = C.new()
3795 lockvar o.sval6
3796 END
3797 v9.CheckSourceFailure(lines, 'E1375: Class variable "sval6" accessible only using class "C"', 7)
3798enddef
3799
3800" Test locking an argument to :def
3801def Test_lockvar_argument()
3802 # Lockvar a function arg
3803 var lines =<< trim END
3804 vim9script
3805
3806 def Lock(val: any)
3807 lockvar val
3808 enddef
3809
3810 var d = {a: 1, b: 2}
3811 Lock(d)
3812
3813 d->extend({c: 3})
3814 END
3815 v9.CheckSourceFailure(lines, 'E741: Value is locked: extend() argument')
3816
3817 # Lockvar a function arg. Verify "sval" is interpreted as argument and not a
3818 # class member in "C". This tests lval_root_is_arg.
3819 lines =<< trim END
3820 vim9script
3821
3822 class C
3823 public static sval: list<number>
3824 endclass
3825
3826 def Lock2(sval: any)
3827 lockvar sval
3828 enddef
3829
3830 var o = C.new()
3831 Lock2(o)
3832 END
3833 v9.CheckSourceSuccess(lines)
3834
3835 # Lock a class.
3836 lines =<< trim END
3837 vim9script
3838
3839 class C
3840 public static sval: list<number>
3841 endclass
3842
3843 def Lock2(sval: any)
3844 lockvar sval
3845 enddef
3846
3847 Lock2(C)
3848 END
3849 v9.CheckSourceSuccess(lines)
3850
3851 # Lock an object.
3852 lines =<< trim END
3853 vim9script
3854
3855 class C
3856 public static sval: list<number>
3857 endclass
3858
3859 def Lock2(sval: any)
3860 lockvar sval
3861 enddef
3862
3863 Lock2(C.new())
3864 END
3865 v9.CheckSourceSuccess(lines)
3866
3867 # In this case (unlike previous) "lockvar sval" is a class member.
3868 lines =<< trim END
3869 vim9script
3870
3871 class C
3872 public static sval: list<number>
3873 def Lock2()
3874 lockvar sval
3875 enddef
3876 endclass
3877
3878
3879 var o = C.new()
3880 o.Lock2()
3881 END
3882 v9.CheckSourceFailure(lines, 'E1392: Cannot (un)lock class variable "sval" in class "C"', 1)
3883enddef
3884
3885" Test that this can be locked without error
3886def Test_lockvar_this()
3887 # lockvar this
3888 var lines =<< trim END
3889 vim9script
3890 class C
3891 def TLock()
3892 lockvar this
3893 enddef
3894 endclass
3895 var o = C.new()
3896 o.TLock()
3897 END
3898 v9.CheckSourceSuccess(lines)
3899
3900 # lockvar four (four letter word, but not this)
3901 lines =<< trim END
3902 vim9script
3903 class C
3904 def TLock4()
3905 var four: number
3906 lockvar four
3907 enddef
3908 endclass
3909 var o = C.new()
3910 o.TLock4()
3911 END
3912 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
3913
3914 # lockvar this5; "this" + one char, 5 letter word, starting with "this"
3915 lines =<< trim END
3916 vim9script
3917 class C
3918 def TLock5()
3919 var this5: number
3920 lockvar this5
3921 enddef
3922 endclass
3923 var o = C.new()
3924 o.TLock5()
3925 END
3926 v9.CheckSourceFailure(lines, 'E1178: Cannot lock or unlock a local variable')
3927enddef
3928
3929" Test some general lockvar cases
3930def Test_lockvar_general()
3931 # lockvar an object and a class. It does nothing
3932 var lines =<< trim END
3933 vim9script
3934 class C
3935 endclass
3936 var o = C.new()
3937 lockvar o
3938 lockvar C
3939 END
3940 v9.CheckSourceSuccess(lines)
3941
3942 # Lock a list element that's nested in an object variable from a :def
3943 lines =<< trim END
3944 vim9script
3945
3946 class C
3947 public this.val: list<list<number>> = [ [1], [2], [3] ]
3948 endclass
3949 def Lock2(obj: any)
3950 lockvar obj.val[1]
3951 enddef
3952
3953 var o = C.new()
3954 Lock2(o)
3955 o.val[0] = [9]
3956 assert_equal([ [9], [2], [3] ], o.val)
3957 try
3958 o.val[1] = [999]
3959 call assert_false(true, 'assign should have failed')
3960 catch
3961 assert_exception('E741:')
3962 endtry
3963 o.val[2] = [8]
3964 assert_equal([ [9], [2], [8] ], o.val)
3965 END
3966 v9.CheckSourceSuccess(lines)
3967
3968 # Lock a list element that's nested in an object variable from scriptlevel
3969 lines =<< trim END
3970 vim9script
3971
3972 class C
3973 public this.val: list<list<number>> = [ [1], [2], [3] ]
3974 endclass
3975
3976 var o = C.new()
3977 lockvar o.val[1]
3978 o.val[0] = [9]
3979 assert_equal([ [9], [2], [3] ], o.val)
3980 try
3981 o.val[1] = [999]
3982 call assert_false(true, 'assign should have failed')
3983 catch
3984 assert_exception('E741:')
3985 endtry
3986 o.val[2] = [8]
3987 assert_equal([ [9], [2], [8] ], o.val)
3988 END
3989 v9.CheckSourceSuccess(lines)
3990enddef
3991
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003992" Test for a private object method
3993def Test_private_object_method()
3994 # Try calling a private method using an object (at the script level)
3995 var lines =<< trim END
3996 vim9script
3997
3998 class A
3999 def _Foo(): number
4000 return 1234
4001 enddef
4002 endclass
4003 var a = A.new()
4004 a._Foo()
4005 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004006 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004007
4008 # Try calling a private method using an object (from a def function)
4009 lines =<< trim END
4010 vim9script
4011
4012 class A
4013 def _Foo(): number
4014 return 1234
4015 enddef
4016 endclass
4017 def T()
4018 var a = A.new()
4019 a._Foo()
4020 enddef
4021 T()
4022 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004023 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004024
4025 # Use a private method from another object method (in script context)
4026 lines =<< trim END
4027 vim9script
4028
4029 class A
4030 def _Foo(): number
4031 return 1234
4032 enddef
4033 def Bar(): number
4034 return this._Foo()
4035 enddef
4036 endclass
4037 var a = A.new()
4038 assert_equal(1234, a.Bar())
4039 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004040 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004041
4042 # Use a private method from another object method (def function context)
4043 lines =<< trim END
4044 vim9script
4045
4046 class A
4047 def _Foo(): number
4048 return 1234
4049 enddef
4050 def Bar(): number
4051 return this._Foo()
4052 enddef
4053 endclass
4054 def T()
4055 var a = A.new()
4056 assert_equal(1234, a.Bar())
4057 enddef
4058 T()
4059 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004060 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004061
4062 # Try calling a private method without the "this" prefix
4063 lines =<< trim END
4064 vim9script
4065
4066 class A
4067 def _Foo(): number
4068 return 1234
4069 enddef
4070 def Bar(): number
4071 return _Foo()
4072 enddef
4073 endclass
4074 var a = A.new()
4075 a.Bar()
4076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004077 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004078
4079 # Try calling a private method using the class name
4080 lines =<< trim END
4081 vim9script
4082
4083 class A
4084 def _Foo(): number
4085 return 1234
4086 enddef
4087 endclass
4088 A._Foo()
4089 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004090 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004091
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004092 # Define two private methods with the same name
4093 lines =<< trim END
4094 vim9script
4095
4096 class A
4097 def _Foo()
4098 enddef
4099 def _Foo()
4100 enddef
4101 endclass
4102 var a = A.new()
4103 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004104 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004105
4106 # Define a private method and a object method with the same name
4107 lines =<< trim END
4108 vim9script
4109
4110 class A
4111 def _Foo()
4112 enddef
4113 def Foo()
4114 enddef
4115 endclass
4116 var a = A.new()
4117 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004118 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004119
4120 # Define an object method and a private method with the same name
4121 lines =<< trim END
4122 vim9script
4123
4124 class A
4125 def Foo()
4126 enddef
4127 def _Foo()
4128 enddef
4129 endclass
4130 var a = A.new()
4131 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004132 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004133
4134 # Call a public method and a private method from a private method
4135 lines =<< trim END
4136 vim9script
4137
4138 class A
4139 def Foo(): number
4140 return 100
4141 enddef
4142 def _Bar(): number
4143 return 200
4144 enddef
4145 def _Baz()
4146 assert_equal(100, this.Foo())
4147 assert_equal(200, this._Bar())
4148 enddef
4149 def T()
4150 this._Baz()
4151 enddef
4152 endclass
4153 var a = A.new()
4154 a.T()
4155 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004156 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004157
4158 # Try calling a private method from another class
4159 lines =<< trim END
4160 vim9script
4161
4162 class A
4163 def _Foo(): number
4164 return 100
4165 enddef
4166 endclass
4167 class B
4168 def Foo(): number
4169 var a = A.new()
4170 a._Foo()
4171 enddef
4172 endclass
4173 var b = B.new()
4174 b.Foo()
4175 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004176 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004177
4178 # Call a private object method from a child class object method
4179 lines =<< trim END
4180 vim9script
4181 class A
4182 def _Foo(): number
4183 return 1234
4184 enddef
4185 endclass
4186 class B extends A
4187 def Bar()
4188 enddef
4189 endclass
4190 class C extends B
4191 def Baz(): number
4192 return this._Foo()
4193 enddef
4194 endclass
4195 var c = C.new()
4196 assert_equal(1234, c.Baz())
4197 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004198 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004199
4200 # Call a private object method from a child class object
4201 lines =<< trim END
4202 vim9script
4203 class A
4204 def _Foo(): number
4205 return 1234
4206 enddef
4207 endclass
4208 class B extends A
4209 def Bar()
4210 enddef
4211 endclass
4212 class C extends B
4213 def Baz(): number
4214 enddef
4215 endclass
4216 var c = C.new()
4217 assert_equal(1234, c._Foo())
4218 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004219 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004220
4221 # Using "_" prefix in a method name should fail outside of a class
4222 lines =<< trim END
4223 vim9script
4224 def _Foo(): number
4225 return 1234
4226 enddef
4227 var a = _Foo()
4228 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004229 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004230enddef
4231
4232" Test for an private class method
4233def Test_private_class_method()
4234 # Try calling a class private method (at the script level)
4235 var lines =<< trim END
4236 vim9script
4237
4238 class A
4239 static def _Foo(): number
4240 return 1234
4241 enddef
4242 endclass
4243 A._Foo()
4244 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004245 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004246
4247 # Try calling a class private method (from a def function)
4248 lines =<< trim END
4249 vim9script
4250
4251 class A
4252 static def _Foo(): number
4253 return 1234
4254 enddef
4255 endclass
4256 def T()
4257 A._Foo()
4258 enddef
4259 T()
4260 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004261 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004262
4263 # Try calling a class private method using an object (at the script level)
4264 lines =<< trim END
4265 vim9script
4266
4267 class A
4268 static def _Foo(): number
4269 return 1234
4270 enddef
4271 endclass
4272 var a = A.new()
4273 a._Foo()
4274 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004275 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004276
4277 # Try calling a class private method using an object (from a def function)
4278 lines =<< trim END
4279 vim9script
4280
4281 class A
4282 static def _Foo(): number
4283 return 1234
4284 enddef
4285 endclass
4286 def T()
4287 var a = A.new()
4288 a._Foo()
4289 enddef
4290 T()
4291 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004292 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004293
4294 # Use a class private method from an object method
4295 lines =<< trim END
4296 vim9script
4297
4298 class A
4299 static def _Foo(): number
4300 return 1234
4301 enddef
4302 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004303 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004304 enddef
4305 endclass
4306 var a = A.new()
4307 a.Bar()
4308 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004309 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004310
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004311 # Use a class private method from another class private method without the
4312 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004313 lines =<< trim END
4314 vim9script
4315
4316 class A
4317 static def _Foo1(): number
4318 return 1234
4319 enddef
4320 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004321 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004322 enddef
4323 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004324 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004325 enddef
4326 endclass
4327 var a = A.new()
4328 a.Bar()
4329 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004330 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004331
4332 # Declare a class method and a class private method with the same name
4333 lines =<< trim END
4334 vim9script
4335
4336 class A
4337 static def _Foo()
4338 enddef
4339 static def Foo()
4340 enddef
4341 endclass
4342 var a = A.new()
4343 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004344 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004345
4346 # Try calling a class private method from another class
4347 lines =<< trim END
4348 vim9script
4349
4350 class A
4351 static def _Foo(): number
4352 return 1234
4353 enddef
4354 endclass
4355 class B
4356 def Foo(): number
4357 return A._Foo()
4358 enddef
4359 endclass
4360 var b = B.new()
4361 assert_equal(1234, b.Foo())
4362 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004363 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004364
4365 # Call a private class method from a child class object method
4366 lines =<< trim END
4367 vim9script
4368 class A
4369 static def _Foo(): number
4370 return 1234
4371 enddef
4372 endclass
4373 class B extends A
4374 def Bar()
4375 enddef
4376 endclass
4377 class C extends B
4378 def Baz(): number
4379 return A._Foo()
4380 enddef
4381 endclass
4382 var c = C.new()
4383 assert_equal(1234, c.Baz())
4384 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004385 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004386
4387 # Call a private class method from a child class private class method
4388 lines =<< trim END
4389 vim9script
4390 class A
4391 static def _Foo(): number
4392 return 1234
4393 enddef
4394 endclass
4395 class B extends A
4396 def Bar()
4397 enddef
4398 endclass
4399 class C extends B
4400 static def Baz(): number
4401 return A._Foo()
4402 enddef
4403 endclass
4404 assert_equal(1234, C.Baz())
4405 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004406 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004407
4408 # Call a private class method from a child class object
4409 lines =<< trim END
4410 vim9script
4411 class A
4412 static def _Foo(): number
4413 return 1234
4414 enddef
4415 endclass
4416 class B extends A
4417 def Bar()
4418 enddef
4419 endclass
4420 class C extends B
4421 def Baz(): number
4422 enddef
4423 endclass
4424 var c = C.new()
4425 assert_equal(1234, C._Foo())
4426 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004427 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02004428enddef
4429
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004430" Test for using the return value of a class/object method as a function
4431" argument.
4432def Test_objmethod_funcarg()
4433 var lines =<< trim END
4434 vim9script
4435
4436 class C
4437 def Foo(): string
4438 return 'foo'
4439 enddef
4440 endclass
4441
4442 def Bar(a: number, s: string): string
4443 return s
4444 enddef
4445
4446 def Baz(c: C)
4447 assert_equal('foo', Bar(10, c.Foo()))
4448 enddef
4449
4450 var t = C.new()
4451 Baz(t)
4452 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004453 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004454
4455 lines =<< trim END
4456 vim9script
4457
4458 class C
4459 static def Foo(): string
4460 return 'foo'
4461 enddef
4462 endclass
4463
4464 def Bar(a: number, s: string): string
4465 return s
4466 enddef
4467
4468 def Baz()
4469 assert_equal('foo', Bar(10, C.Foo()))
4470 enddef
4471
4472 Baz()
4473 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004474 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004475enddef
4476
Ernie Raelcf138d42023-09-06 20:45:03 +02004477def Test_static_inheritence()
4478 # subclasses get their own static copy
4479 var lines =<< trim END
4480 vim9script
4481
4482 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004483 static _svar: number
4484 this._mvar: number
4485 def new()
4486 _svar = 1
4487 this._mvar = 101
4488 enddef
4489 def AccessObject(): number
4490 return this._mvar
4491 enddef
4492 def AccessStaticThroughObject(): number
4493 return _svar
4494 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004495 endclass
4496
4497 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004498 def new()
4499 this._mvar = 102
4500 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004501 endclass
4502
4503 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004504 def new()
4505 this._mvar = 103
4506 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004507
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004508 def AccessPrivateStaticThroughClassName(): number
4509 assert_equal(1, A._svar)
4510 return 444
4511 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004512 endclass
4513
4514 var oa = A.new()
4515 var ob = B.new()
4516 var oc = C.new()
4517 assert_equal(101, oa.AccessObject())
4518 assert_equal(102, ob.AccessObject())
4519 assert_equal(103, oc.AccessObject())
4520
RestorerZ7fe8f432023-09-24 23:21:24 +02004521 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable: _svar')
Ernie Raelcf138d42023-09-06 20:45:03 +02004522
4523 # verify object properly resolves to correct static
4524 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004525 assert_equal(1, ob.AccessStaticThroughObject())
4526 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02004527 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004528 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02004529enddef
4530
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004531" Test for declaring duplicate object and class members
4532def Test_dup_member_variable()
4533 # Duplicate member variable
4534 var lines =<< trim END
4535 vim9script
4536 class C
4537 this.val = 10
4538 this.val = 20
4539 endclass
4540 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004541 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004542
4543 # Duplicate private member variable
4544 lines =<< trim END
4545 vim9script
4546 class C
4547 this._val = 10
4548 this._val = 20
4549 endclass
4550 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004551 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004552
4553 # Duplicate public member variable
4554 lines =<< trim END
4555 vim9script
4556 class C
4557 public this.val = 10
4558 public this.val = 20
4559 endclass
4560 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004561 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004562
4563 # Duplicate private member variable
4564 lines =<< trim END
4565 vim9script
4566 class C
4567 this.val = 10
4568 this._val = 20
4569 endclass
4570 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004571 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004572
4573 # Duplicate public and private member variable
4574 lines =<< trim END
4575 vim9script
4576 class C
4577 this._val = 20
4578 public this.val = 10
4579 endclass
4580 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004581 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004582
4583 # Duplicate class member variable
4584 lines =<< trim END
4585 vim9script
4586 class C
4587 static s: string = "abc"
4588 static _s: string = "def"
4589 endclass
4590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004591 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004592
4593 # Duplicate public and private class member variable
4594 lines =<< trim END
4595 vim9script
4596 class C
4597 public static s: string = "abc"
4598 static _s: string = "def"
4599 endclass
4600 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004601 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004602
4603 # Duplicate class and object member variable
4604 lines =<< trim END
4605 vim9script
4606 class C
4607 static val = 10
4608 this.val = 20
4609 def new()
4610 enddef
4611 endclass
4612 var c = C.new()
4613 assert_equal(10, C.val)
4614 assert_equal(20, c.val)
4615 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02004616 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004617
4618 # Duplicate object member variable in a derived class
4619 lines =<< trim END
4620 vim9script
4621 class A
4622 this.val = 10
4623 endclass
4624 class B extends A
4625 endclass
4626 class C extends B
4627 this.val = 20
4628 endclass
4629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004630 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004631
4632 # Duplicate object private member variable in a derived class
4633 lines =<< trim END
4634 vim9script
4635 class A
4636 this._val = 10
4637 endclass
4638 class B extends A
4639 endclass
4640 class C extends B
4641 this._val = 20
4642 endclass
4643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004644 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004645
4646 # Duplicate object private member variable in a derived class
4647 lines =<< trim END
4648 vim9script
4649 class A
4650 this.val = 10
4651 endclass
4652 class B extends A
4653 endclass
4654 class C extends B
4655 this._val = 20
4656 endclass
4657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004658 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004659
4660 # Duplicate object member variable in a derived class
4661 lines =<< trim END
4662 vim9script
4663 class A
4664 this._val = 10
4665 endclass
4666 class B extends A
4667 endclass
4668 class C extends B
4669 this.val = 20
4670 endclass
4671 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004672 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004673
4674 # Two member variables with a common prefix
4675 lines =<< trim END
4676 vim9script
4677 class A
4678 public static svar2: number
4679 public static svar: number
4680 endclass
4681 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004682 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004683enddef
4684
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004685" Test for accessing a private member outside a class in a def function
4686def Test_private_member_access_outside_class()
4687 # private object member variable
4688 var lines =<< trim END
4689 vim9script
4690 class A
4691 this._val = 10
4692 def GetVal(): number
4693 return this._val
4694 enddef
4695 endclass
4696 def T()
4697 var a = A.new()
4698 a._val = 20
4699 enddef
4700 T()
4701 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004702 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004703
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004704 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004705 lines =<< trim END
4706 vim9script
4707 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004708 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004709 endclass
4710 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004711 var a = A.new()
4712 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004713 enddef
4714 T()
4715 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004716 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004717
4718 # private static member variable
4719 lines =<< trim END
4720 vim9script
4721 class A
4722 static _val = 10
4723 endclass
4724 def T()
4725 var a = A.new()
4726 var x = a._val
4727 enddef
4728 T()
4729 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004730 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004731
4732 # private static member variable
4733 lines =<< trim END
4734 vim9script
4735 class A
4736 static _val = 10
4737 endclass
4738 def T()
4739 var a = A.new()
4740 a._val = 3
4741 enddef
4742 T()
4743 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004744 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004745
4746 # private static class variable
4747 lines =<< trim END
4748 vim9script
4749 class A
4750 static _val = 10
4751 endclass
4752 def T()
4753 var x = A._val
4754 enddef
4755 T()
4756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004757 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02004758
4759 # private static class variable
4760 lines =<< trim END
4761 vim9script
4762 class A
4763 static _val = 10
4764 endclass
4765 def T()
4766 A._val = 3
4767 enddef
4768 T()
4769 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004770 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004771enddef
4772
4773" Test for changing the member access of an interface in a implementation class
4774def Test_change_interface_member_access()
4775 var lines =<< trim END
4776 vim9script
4777 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004778 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004779 endinterface
4780 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004781 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004782 endclass
4783 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004784 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004785
4786 lines =<< trim END
4787 vim9script
4788 interface A
4789 this.val: number
4790 endinterface
4791 class B implements A
4792 public this.val = 10
4793 endclass
4794 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004795 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004796enddef
4797
4798" Test for trying to change a readonly member from a def function
4799def Test_readonly_member_change_in_def_func()
4800 var lines =<< trim END
4801 vim9script
4802 class A
4803 this.val: number
4804 endclass
4805 def T()
4806 var a = A.new()
4807 a.val = 20
4808 enddef
4809 T()
4810 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004811 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004812enddef
4813
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004814" Test for reading and writing a class member from a def function
4815def Test_modify_class_member_from_def_function()
4816 var lines =<< trim END
4817 vim9script
4818 class A
4819 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004820 public static var2: list<number> = [1, 2]
4821 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004822 static _priv_var4: number = 40
4823 endclass
4824 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004825 assert_equal([1, 2], A.var2)
4826 assert_equal({a: 1, b: 2}, A.var3)
4827 A.var2 = [3, 4]
4828 A.var3 = {c: 3, d: 4}
4829 assert_equal([3, 4], A.var2)
4830 assert_equal({c: 3, d: 4}, A.var3)
RestorerZ7fe8f432023-09-24 23:21:24 +02004831 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable: _priv_var4')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004832 enddef
4833 T()
4834 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004835 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004836enddef
4837
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004838" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004839def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004840 var lines =<< trim END
4841 vim9script
4842 class A
4843 public static svar1: list<number> = [1]
4844 public static svar2: list<number> = [2]
4845 endclass
4846
4847 A.svar1->add(3)
4848 A.svar2->add(4)
4849 assert_equal([1, 3], A.svar1)
4850 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004851
4852 def Foo()
4853 A.svar1->add(7)
4854 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004855 assert_equal([1, 3, 7], A.svar1)
4856 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004857 enddef
4858 Foo()
4859 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004860 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004861
4862 # Cannot read from a class variable using an object in script context
4863 lines =<< trim END
4864 vim9script
4865 class A
4866 public this.var1: number
4867 public static svar2: list<number> = [1]
4868 endclass
4869
4870 var a = A.new()
4871 echo a.svar2
4872 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004873 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004874
4875 # Cannot write to a class variable using an object in script context
4876 lines =<< trim END
4877 vim9script
4878 class A
4879 public this.var1: number
4880 public static svar2: list<number> = [1]
4881 endclass
4882
4883 var a = A.new()
4884 a.svar2 = [2]
4885 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004886 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004887
4888 # Cannot read from a class variable using an object in def method context
4889 lines =<< trim END
4890 vim9script
4891 class A
4892 public this.var1: number
4893 public static svar2: list<number> = [1]
4894 endclass
4895
4896 def T()
4897 var a = A.new()
4898 echo a.svar2
4899 enddef
4900 T()
4901 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004902 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004903
4904 # Cannot write to a class variable using an object in def method context
4905 lines =<< trim END
4906 vim9script
4907 class A
4908 public this.var1: number
4909 public static svar2: list<number> = [1]
4910 endclass
4911
4912 def T()
4913 var a = A.new()
4914 a.svar2 = [2]
4915 enddef
4916 T()
4917 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004918 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004919enddef
4920
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004921" Test for using a interface method using a child object
4922def Test_interface_method_from_child()
4923 var lines =<< trim END
4924 vim9script
4925
4926 interface A
4927 def Foo(): string
4928 endinterface
4929
4930 class B implements A
4931 def Foo(): string
4932 return 'foo'
4933 enddef
4934 endclass
4935
4936 class C extends B
4937 def Bar(): string
4938 return 'bar'
4939 enddef
4940 endclass
4941
4942 def T1(a: A)
4943 assert_equal('foo', a.Foo())
4944 enddef
4945
4946 def T2(b: B)
4947 assert_equal('foo', b.Foo())
4948 enddef
4949
4950 var c = C.new()
4951 T1(c)
4952 T2(c)
4953 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004954 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004955enddef
4956
4957" Test for using an interface method using a child object when it is overridden
4958" by the child class.
4959" FIXME: This test fails.
4960" def Test_interface_overridden_method_from_child()
4961" var lines =<< trim END
4962" vim9script
4963"
4964" interface A
4965" def Foo(): string
4966" endinterface
4967"
4968" class B implements A
4969" def Foo(): string
4970" return 'b-foo'
4971" enddef
4972" endclass
4973"
4974" class C extends B
4975" def Bar(): string
4976" return 'bar'
4977" enddef
4978" def Foo(): string
4979" return 'c-foo'
4980" enddef
4981" endclass
4982"
4983" def T1(a: A)
4984" assert_equal('c-foo', a.Foo())
4985" enddef
4986"
4987" def T2(b: B)
4988" assert_equal('c-foo', b.Foo())
4989" enddef
4990"
4991" var c = C.new()
4992" T1(c)
4993" T2(c)
4994" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004995" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004996" enddef
4997
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004998" Test for abstract methods
4999def Test_abstract_method()
5000 # Use two abstract methods
5001 var lines =<< trim END
5002 vim9script
5003 abstract class A
5004 def M1(): number
5005 return 10
5006 enddef
5007 abstract def M2(): number
5008 abstract def M3(): number
5009 endclass
5010 class B extends A
5011 def M2(): number
5012 return 20
5013 enddef
5014 def M3(): number
5015 return 30
5016 enddef
5017 endclass
5018 var b = B.new()
5019 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
5020 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005021 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005022
5023 # Don't define an abstract method
5024 lines =<< trim END
5025 vim9script
5026 abstract class A
5027 abstract def Foo()
5028 endclass
5029 class B extends A
5030 endclass
5031 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005032 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005033
5034 # Use abstract method in a concrete class
5035 lines =<< trim END
5036 vim9script
5037 class A
5038 abstract def Foo()
5039 endclass
5040 class B extends A
5041 endclass
5042 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005043 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005044
5045 # Use abstract method in an interface
5046 lines =<< trim END
5047 vim9script
5048 interface A
5049 abstract def Foo()
5050 endinterface
5051 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005052 def Foo()
5053 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005054 endclass
5055 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005056 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005057
5058 # Abbreviate the "abstract" keyword
5059 lines =<< trim END
5060 vim9script
5061 class A
5062 abs def Foo()
5063 endclass
5064 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005065 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005066
5067 # Use "abstract" with a member variable
5068 lines =<< trim END
5069 vim9script
5070 abstract class A
5071 abstract this.val = 10
5072 endclass
5073 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005074 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005075
5076 # Use a static abstract method
5077 lines =<< trim END
5078 vim9script
5079 abstract class A
5080 abstract static def Foo(): number
5081 endclass
5082 class B extends A
5083 static def Foo(): number
5084 return 4
5085 enddef
5086 endclass
5087 assert_equal(4, B.Foo())
5088 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005089 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005090
5091 # Type mismatch between abstract method and concrete method
5092 lines =<< trim END
5093 vim9script
5094 abstract class A
5095 abstract def Foo(a: string, b: number): list<number>
5096 endclass
5097 class B extends A
5098 def Foo(a: number, b: string): list<string>
5099 return []
5100 enddef
5101 endclass
5102 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005103 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 +02005104
5105 # Use an abstract class to invoke an abstract method
5106 # FIXME: This should fail
5107 lines =<< trim END
5108 vim9script
5109 abstract class A
5110 abstract static def Foo()
5111 endclass
5112 A.Foo()
5113 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005114 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005115
5116 # Invoke an abstract method from a def function
5117 lines =<< trim END
5118 vim9script
5119 abstract class A
5120 abstract def Foo(): list<number>
5121 endclass
5122 class B extends A
5123 def Foo(): list<number>
5124 return [3, 5]
5125 enddef
5126 endclass
5127 def Bar(c: B)
5128 assert_equal([3, 5], c.Foo())
5129 enddef
5130 var b = B.new()
5131 Bar(b)
5132 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005133 v9.CheckSourceSuccess(lines)
5134enddef
5135
5136" Test for calling a class method from a subclass
5137def Test_class_method_call_from_subclass()
5138 # class method call from a subclass
5139 var lines =<< trim END
5140 vim9script
5141
5142 class A
5143 static def Foo()
5144 echo "foo"
5145 enddef
5146 endclass
5147
5148 class B extends A
5149 def Bar()
5150 Foo()
5151 enddef
5152 endclass
5153
5154 var b = B.new()
5155 b.Bar()
5156 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005157 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02005158enddef
5159
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005160" Test for calling a class method using an object in a def function context and
5161" script context.
5162def Test_class_method_call_using_object()
5163 # script context
5164 var lines =<< trim END
5165 vim9script
5166 class A
5167 static def Foo(): list<string>
5168 return ['a', 'b']
5169 enddef
5170 def Bar()
5171 assert_equal(['a', 'b'], A.Foo())
5172 assert_equal(['a', 'b'], Foo())
5173 enddef
5174 endclass
5175
5176 def T()
5177 assert_equal(['a', 'b'], A.Foo())
5178 var t_a = A.new()
5179 t_a.Bar()
5180 enddef
5181
5182 assert_equal(['a', 'b'], A.Foo())
5183 var a = A.new()
5184 a.Bar()
5185 T()
5186 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005187 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005188
5189 # script context
5190 lines =<< trim END
5191 vim9script
5192 class A
5193 static def Foo(): string
5194 return 'foo'
5195 enddef
5196 endclass
5197
5198 var a = A.new()
5199 assert_equal('foo', a.Foo())
5200 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005201 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005202
5203 # def function context
5204 lines =<< trim END
5205 vim9script
5206 class A
5207 static def Foo(): string
5208 return 'foo'
5209 enddef
5210 endclass
5211
5212 def T()
5213 var a = A.new()
5214 assert_equal('foo', a.Foo())
5215 enddef
5216 T()
5217 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005218 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005219enddef
5220
5221def Test_class_variable()
5222 var lines =<< trim END
5223 vim9script
5224
5225 class A
5226 public static val: number = 10
5227 static def ClassFunc()
5228 assert_equal(10, val)
5229 enddef
5230 def ObjFunc()
5231 assert_equal(10, val)
5232 enddef
5233 endclass
5234
5235 class B extends A
5236 endclass
5237
5238 assert_equal(10, A.val)
5239 A.ClassFunc()
5240 var a = A.new()
5241 a.ObjFunc()
5242 var b = B.new()
5243 b.ObjFunc()
5244
5245 def T1(a1: A)
5246 a1.ObjFunc()
5247 A.ClassFunc()
5248 enddef
5249 T1(b)
5250
5251 A.val = 20
5252 assert_equal(20, A.val)
5253 END
5254 v9.CheckSourceSuccess(lines)
5255
5256 # Modifying a parent class variable from a child class method
5257 lines =<< trim END
5258 vim9script
5259
5260 class A
5261 static val: number = 10
5262 endclass
5263
5264 class B extends A
5265 static def ClassFunc()
5266 val = 20
5267 enddef
5268 endclass
5269 B.ClassFunc()
5270 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005271 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005272
5273 # Reading a parent class variable from a child class method
5274 lines =<< trim END
5275 vim9script
5276
5277 class A
5278 static val: number = 10
5279 endclass
5280
5281 class B extends A
5282 static def ClassFunc()
5283 var i = val
5284 enddef
5285 endclass
5286 B.ClassFunc()
5287 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005288 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005289
5290 # Modifying a parent class variable from a child object method
5291 lines =<< trim END
5292 vim9script
5293
5294 class A
5295 static val: number = 10
5296 endclass
5297
5298 class B extends A
5299 def ObjFunc()
5300 val = 20
5301 enddef
5302 endclass
5303 var b = B.new()
5304 b.ObjFunc()
5305 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005306 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005307
5308 # Reading a parent class variable from a child object method
5309 lines =<< trim END
5310 vim9script
5311
5312 class A
5313 static val: number = 10
5314 endclass
5315
5316 class B extends A
5317 def ObjFunc()
5318 var i = val
5319 enddef
5320 endclass
5321 var b = B.new()
5322 b.ObjFunc()
5323 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005324 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005325
5326 # Modifying a class variable using an object at script level
5327 lines =<< trim END
5328 vim9script
5329
5330 class A
5331 static val: number = 10
5332 endclass
5333 var a = A.new()
5334 a.val = 20
5335 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005336 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005337
5338 # Reading a class variable using an object at script level
5339 lines =<< trim END
5340 vim9script
5341
5342 class A
5343 static val: number = 10
5344 endclass
5345 var a = A.new()
5346 var i = a.val
5347 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005348 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005349
5350 # Modifying a class variable using an object at function level
5351 lines =<< trim END
5352 vim9script
5353
5354 class A
5355 static val: number = 10
5356 endclass
5357
5358 def T()
5359 var a = A.new()
5360 a.val = 20
5361 enddef
5362 T()
5363 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005364 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005365
5366 # Reading a class variable using an object at function level
5367 lines =<< trim END
5368 vim9script
5369
5370 class A
5371 static val: number = 10
5372 endclass
5373 def T()
5374 var a = A.new()
5375 var i = a.val
5376 enddef
5377 T()
5378 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005379 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005380enddef
5381
5382" Test for using a duplicate class method and class variable in a child class
5383def Test_dup_class_member()
5384 # duplicate class variable, class method and overridden object method
5385 var lines =<< trim END
5386 vim9script
5387 class A
5388 static sval = 100
5389 static def Check()
5390 assert_equal(100, sval)
5391 enddef
5392 def GetVal(): number
5393 return sval
5394 enddef
5395 endclass
5396
5397 class B extends A
5398 static sval = 200
5399 static def Check()
5400 assert_equal(200, sval)
5401 enddef
5402 def GetVal(): number
5403 return sval
5404 enddef
5405 endclass
5406
5407 def T1(aa: A): number
5408 return aa.GetVal()
5409 enddef
5410
5411 def T2(bb: B): number
5412 return bb.GetVal()
5413 enddef
5414
5415 assert_equal(100, A.sval)
5416 assert_equal(200, B.sval)
5417 var a = A.new()
5418 assert_equal(100, a.GetVal())
5419 var b = B.new()
5420 assert_equal(200, b.GetVal())
5421 assert_equal(200, T1(b))
5422 assert_equal(200, T2(b))
5423 END
5424 v9.CheckSourceSuccess(lines)
5425
5426 # duplicate class variable and class method
5427 lines =<< trim END
5428 vim9script
5429 class A
5430 static sval = 100
5431 static def Check()
5432 assert_equal(100, sval)
5433 enddef
5434 def GetVal(): number
5435 return sval
5436 enddef
5437 endclass
5438
5439 class B extends A
5440 static sval = 200
5441 static def Check()
5442 assert_equal(200, sval)
5443 enddef
5444 endclass
5445
5446 def T1(aa: A): number
5447 return aa.GetVal()
5448 enddef
5449
5450 def T2(bb: B): number
5451 return bb.GetVal()
5452 enddef
5453
5454 assert_equal(100, A.sval)
5455 assert_equal(200, B.sval)
5456 var a = A.new()
5457 assert_equal(100, a.GetVal())
5458 var b = B.new()
5459 assert_equal(100, b.GetVal())
5460 assert_equal(100, T1(b))
5461 assert_equal(100, T2(b))
5462 END
5463 v9.CheckSourceSuccess(lines)
5464enddef
5465
5466" Test for calling an instance method using the class
5467def Test_instance_method_call_using_class()
5468 # Invoke an object method using a class in script context
5469 var lines =<< trim END
5470 vim9script
5471 class A
5472 def Foo()
5473 echo "foo"
5474 enddef
5475 endclass
5476 A.Foo()
5477 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005478 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005479
5480 # Invoke an object method using a class in def function context
5481 lines =<< trim END
5482 vim9script
5483 class A
5484 def Foo()
5485 echo "foo"
5486 enddef
5487 endclass
5488 def T()
5489 A.Foo()
5490 enddef
5491 T()
5492 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005493 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005494enddef
5495
5496" Test for duplicate class method and instance method
5497def Test_dup_classmethod_objmethod()
5498 # Duplicate instance method
5499 var lines =<< trim END
5500 vim9script
5501 class A
5502 static def Foo()
5503 enddef
5504 def Foo()
5505 enddef
5506 endclass
5507 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005508 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005509
5510 # Duplicate private instance method
5511 lines =<< trim END
5512 vim9script
5513 class A
5514 static def Foo()
5515 enddef
5516 def _Foo()
5517 enddef
5518 endclass
5519 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005520 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005521
5522 # Duplicate class method
5523 lines =<< trim END
5524 vim9script
5525 class A
5526 def Foo()
5527 enddef
5528 static def Foo()
5529 enddef
5530 endclass
5531 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005532 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005533
5534 # Duplicate private class method
5535 lines =<< trim END
5536 vim9script
5537 class A
5538 def Foo()
5539 enddef
5540 static def _Foo()
5541 enddef
5542 endclass
5543 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005544 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005545
5546 # Duplicate private class and object method
5547 lines =<< trim END
5548 vim9script
5549 class A
5550 def _Foo()
5551 enddef
5552 static def _Foo()
5553 enddef
5554 endclass
5555 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005556 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005557enddef
5558
5559" Test for an instance method access level comparison with parent instance
5560" methods.
5561def Test_instance_method_access_level()
5562 # Private method in subclass
5563 var lines =<< trim END
5564 vim9script
5565 class A
5566 def Foo()
5567 enddef
5568 endclass
5569 class B extends A
5570 endclass
5571 class C extends B
5572 def _Foo()
5573 enddef
5574 endclass
5575 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005576 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005577
5578 # Public method in subclass
5579 lines =<< trim END
5580 vim9script
5581 class A
5582 def _Foo()
5583 enddef
5584 endclass
5585 class B extends A
5586 endclass
5587 class C extends B
5588 def Foo()
5589 enddef
5590 endclass
5591 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005592 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005593enddef
5594
5595def Test_extend_empty_class()
5596 var lines =<< trim END
5597 vim9script
5598 class A
5599 endclass
5600 class B extends A
5601 endclass
5602 class C extends B
5603 public static rw_class_var = 1
5604 public this.rw_obj_var = 2
5605 static def ClassMethod(): number
5606 return 3
5607 enddef
5608 def ObjMethod(): number
5609 return 4
5610 enddef
5611 endclass
5612 assert_equal(1, C.rw_class_var)
5613 assert_equal(3, C.ClassMethod())
5614 var c = C.new()
5615 assert_equal(2, c.rw_obj_var)
5616 assert_equal(4, c.ObjMethod())
5617 END
5618 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005619enddef
5620
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005621" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005622" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005623def Test_interface_with_unsupported_members()
5624 var lines =<< trim END
5625 vim9script
5626 interface A
5627 static num: number
5628 endinterface
5629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005630 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005631
5632 lines =<< trim END
5633 vim9script
5634 interface A
5635 static _num: number
5636 endinterface
5637 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005638 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005639
5640 lines =<< trim END
5641 vim9script
5642 interface A
5643 public static num: number
5644 endinterface
5645 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005646 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005647
5648 lines =<< trim END
5649 vim9script
5650 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005651 public static num: number
5652 endinterface
5653 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005654 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005655
5656 lines =<< trim END
5657 vim9script
5658 interface A
5659 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005660 endinterface
5661 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005662 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005663
5664 lines =<< trim END
5665 vim9script
5666 interface A
5667 static def Foo(d: dict<any>): list<string>
5668 endinterface
5669 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005670 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005671
5672 lines =<< trim END
5673 vim9script
5674 interface A
5675 static def _Foo(d: dict<any>): list<string>
5676 endinterface
5677 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005678 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005679
5680 lines =<< trim END
5681 vim9script
5682 interface A
5683 this._Foo: list<string>
5684 endinterface
5685 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005686 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005687
5688 lines =<< trim END
5689 vim9script
5690 interface A
5691 def _Foo(d: dict<any>): list<string>
5692 endinterface
5693 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005694 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005695enddef
5696
5697" Test for extending an interface
5698def Test_extend_interface()
5699 var lines =<< trim END
5700 vim9script
5701 interface A
5702 this.var1: list<string>
5703 def Foo()
5704 endinterface
5705 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005706 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005707 def Bar()
5708 endinterface
5709 class C implements A, B
5710 this.var1 = [1, 2]
5711 def Foo()
5712 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005713 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005714 def Bar()
5715 enddef
5716 endclass
5717 END
5718 v9.CheckSourceSuccess(lines)
5719
5720 lines =<< trim END
5721 vim9script
5722 interface A
5723 def Foo()
5724 endinterface
5725 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005726 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005727 endinterface
5728 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005729 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005730 endclass
5731 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005732 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005733
5734 lines =<< trim END
5735 vim9script
5736 interface A
5737 def Foo()
5738 endinterface
5739 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005740 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005741 endinterface
5742 class C implements A, B
5743 def Foo()
5744 enddef
5745 endclass
5746 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005747 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005748
5749 # interface cannot extend a class
5750 lines =<< trim END
5751 vim9script
5752 class A
5753 endclass
5754 interface B extends A
5755 endinterface
5756 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005757 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005758
5759 # class cannot extend an interface
5760 lines =<< trim END
5761 vim9script
5762 interface A
5763 endinterface
5764 class B extends A
5765 endclass
5766 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005767 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005768
5769 # interface cannot implement another interface
5770 lines =<< trim END
5771 vim9script
5772 interface A
5773 endinterface
5774 interface B implements A
5775 endinterface
5776 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005777 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005778
5779 # interface cannot extend multiple interfaces
5780 lines =<< trim END
5781 vim9script
5782 interface A
5783 endinterface
5784 interface B
5785 endinterface
5786 interface C extends A, B
5787 endinterface
5788 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005789 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005790
5791 # Variable type in an extended interface is of different type
5792 lines =<< trim END
5793 vim9script
5794 interface A
5795 this.val1: number
5796 endinterface
5797 interface B extends A
5798 this.val2: string
5799 endinterface
5800 interface C extends B
5801 this.val1: string
5802 this.val2: number
5803 endinterface
5804 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005805 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005806enddef
5807
5808" Test for a child class implementing an interface when some of the methods are
5809" defined in the parent class.
5810def Test_child_class_implements_interface()
5811 var lines =<< trim END
5812 vim9script
5813
5814 interface Intf
5815 def F1(): list<list<number>>
5816 def F2(): list<list<number>>
5817 def F3(): list<list<number>>
5818 this.var1: list<dict<number>>
5819 this.var2: list<dict<number>>
5820 this.var3: list<dict<number>>
5821 endinterface
5822
5823 class A
5824 def A1()
5825 enddef
5826 def F3(): list<list<number>>
5827 return [[3]]
5828 enddef
5829 this.v1: list<list<number>> = [[0]]
5830 this.var3 = [{c: 30}]
5831 endclass
5832
5833 class B extends A
5834 def B1()
5835 enddef
5836 def F2(): list<list<number>>
5837 return [[2]]
5838 enddef
5839 this.v2: list<list<number>> = [[0]]
5840 this.var2 = [{b: 20}]
5841 endclass
5842
5843 class C extends B implements Intf
5844 def C1()
5845 enddef
5846 def F1(): list<list<number>>
5847 return [[1]]
5848 enddef
5849 this.v3: list<list<number>> = [[0]]
5850 this.var1 = [{a: 10}]
5851 endclass
5852
5853 def T(if: Intf)
5854 assert_equal([[1]], if.F1())
5855 assert_equal([[2]], if.F2())
5856 assert_equal([[3]], if.F3())
5857 assert_equal([{a: 10}], if.var1)
5858 assert_equal([{b: 20}], if.var2)
5859 assert_equal([{c: 30}], if.var3)
5860 enddef
5861
5862 var c = C.new()
5863 T(c)
5864 assert_equal([[1]], c.F1())
5865 assert_equal([[2]], c.F2())
5866 assert_equal([[3]], c.F3())
5867 assert_equal([{a: 10}], c.var1)
5868 assert_equal([{b: 20}], c.var2)
5869 assert_equal([{c: 30}], c.var3)
5870 END
5871 v9.CheckSourceSuccess(lines)
5872
5873 # One of the interface methods is not found
5874 lines =<< trim END
5875 vim9script
5876
5877 interface Intf
5878 def F1()
5879 def F2()
5880 def F3()
5881 endinterface
5882
5883 class A
5884 def A1()
5885 enddef
5886 endclass
5887
5888 class B extends A
5889 def B1()
5890 enddef
5891 def F2()
5892 enddef
5893 endclass
5894
5895 class C extends B implements Intf
5896 def C1()
5897 enddef
5898 def F1()
5899 enddef
5900 endclass
5901 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005902 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005903
5904 # One of the interface methods is of different type
5905 lines =<< trim END
5906 vim9script
5907
5908 interface Intf
5909 def F1()
5910 def F2()
5911 def F3()
5912 endinterface
5913
5914 class A
5915 def F3(): number
5916 return 0
5917 enddef
5918 def A1()
5919 enddef
5920 endclass
5921
5922 class B extends A
5923 def B1()
5924 enddef
5925 def F2()
5926 enddef
5927 endclass
5928
5929 class C extends B implements Intf
5930 def C1()
5931 enddef
5932 def F1()
5933 enddef
5934 endclass
5935 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005936 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005937
5938 # One of the interface variables is not present
5939 lines =<< trim END
5940 vim9script
5941
5942 interface Intf
5943 this.var1: list<dict<number>>
5944 this.var2: list<dict<number>>
5945 this.var3: list<dict<number>>
5946 endinterface
5947
5948 class A
5949 this.v1: list<list<number>> = [[0]]
5950 endclass
5951
5952 class B extends A
5953 this.v2: list<list<number>> = [[0]]
5954 this.var2 = [{b: 20}]
5955 endclass
5956
5957 class C extends B implements Intf
5958 this.v3: list<list<number>> = [[0]]
5959 this.var1 = [{a: 10}]
5960 endclass
5961 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005962 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005963
5964 # One of the interface variables is of different type
5965 lines =<< trim END
5966 vim9script
5967
5968 interface Intf
5969 this.var1: list<dict<number>>
5970 this.var2: list<dict<number>>
5971 this.var3: list<dict<number>>
5972 endinterface
5973
5974 class A
5975 this.v1: list<list<number>> = [[0]]
5976 this.var3: list<dict<string>>
5977 endclass
5978
5979 class B extends A
5980 this.v2: list<list<number>> = [[0]]
5981 this.var2 = [{b: 20}]
5982 endclass
5983
5984 class C extends B implements Intf
5985 this.v3: list<list<number>> = [[0]]
5986 this.var1 = [{a: 10}]
5987 endclass
5988 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005989 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 +02005990enddef
5991
5992" Test for extending an interface with duplicate variables and methods
5993def Test_interface_extends_with_dup_members()
5994 var lines =<< trim END
5995 vim9script
5996 interface A
5997 this.n1: number
5998 def Foo1(): number
5999 endinterface
6000 interface B extends A
6001 this.n2: number
6002 this.n1: number
6003 def Foo2(): number
6004 def Foo1(): number
6005 endinterface
6006 class C implements B
6007 this.n1 = 10
6008 this.n2 = 20
6009 def Foo1(): number
6010 return 30
6011 enddef
6012 def Foo2(): number
6013 return 40
6014 enddef
6015 endclass
6016 def T1(a: A)
6017 assert_equal(10, a.n1)
6018 assert_equal(30, a.Foo1())
6019 enddef
6020 def T2(b: B)
6021 assert_equal(10, b.n1)
6022 assert_equal(20, b.n2)
6023 assert_equal(30, b.Foo1())
6024 assert_equal(40, b.Foo2())
6025 enddef
6026 var c = C.new()
6027 T1(c)
6028 T2(c)
6029 END
6030 v9.CheckSourceSuccess(lines)
6031enddef
6032
6033" Test for using "any" type for a variable in a sub-class while it has a
6034" concrete type in the interface
6035def Test_implements_using_var_type_any()
6036 var lines =<< trim END
6037 vim9script
6038 interface A
6039 this.val: list<dict<string>>
6040 endinterface
6041 class B implements A
6042 this.val = [{a: '1'}, {b: '2'}]
6043 endclass
6044 var b = B.new()
6045 assert_equal([{a: '1'}, {b: '2'}], b.val)
6046 END
6047 v9.CheckSourceSuccess(lines)
6048
6049 # initialize instance variable using a different type
6050 lines =<< trim END
6051 vim9script
6052 interface A
6053 this.val: list<dict<string>>
6054 endinterface
6055 class B implements A
6056 this.val = {a: 1, b: 2}
6057 endclass
6058 var b = B.new()
6059 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006060 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02006061enddef
6062
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006063" Test for assigning to a member variable in a nested class
6064def Test_nested_object_assignment()
6065 var lines =<< trim END
6066 vim9script
6067
6068 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006069 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006070 endclass
6071
6072 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006073 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006074 endclass
6075
6076 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006077 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006078 endclass
6079
6080 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006081 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006082 endclass
6083
6084 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006085 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006086 enddef
6087
6088 var d = D.new()
6089 T(d)
6090 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02006091 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02006092enddef
6093
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02006094" Test for calling methods using a null object
6095def Test_null_object_method_call()
6096 # Calling a object method using a null object in script context
6097 var lines =<< trim END
6098 vim9script
6099
6100 class C
6101 def Foo()
6102 assert_report('This method should not be executed')
6103 enddef
6104 endclass
6105
6106 var o: C
6107 o.Foo()
6108 END
6109 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
6110
6111 # Calling a object method using a null object in def function context
6112 lines =<< trim END
6113 vim9script
6114
6115 class C
6116 def Foo()
6117 assert_report('This method should not be executed')
6118 enddef
6119 endclass
6120
6121 def T()
6122 var o: C
6123 o.Foo()
6124 enddef
6125 T()
6126 END
6127 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6128
6129 # Calling a object method through another class method using a null object in
6130 # script context
6131 lines =<< trim END
6132 vim9script
6133
6134 class C
6135 def Foo()
6136 assert_report('This method should not be executed')
6137 enddef
6138
6139 static def Bar(o_any: any)
6140 var o_typed: C = o_any
6141 o_typed.Foo()
6142 enddef
6143 endclass
6144
6145 var o: C
6146 C.Bar(o)
6147 END
6148 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6149
6150 # Calling a object method through another class method using a null object in
6151 # def function context
6152 lines =<< trim END
6153 vim9script
6154
6155 class C
6156 def Foo()
6157 assert_report('This method should not be executed')
6158 enddef
6159
6160 static def Bar(o_any: any)
6161 var o_typed: C = o_any
6162 o_typed.Foo()
6163 enddef
6164 endclass
6165
6166 def T()
6167 var o: C
6168 C.Bar(o)
6169 enddef
6170 T()
6171 END
6172 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
6173enddef
6174
6175" Test for using a dict as an object member
6176def Test_dict_object_member()
6177 var lines =<< trim END
6178 vim9script
6179
6180 class Context
6181 public this.state: dict<number> = {}
6182 def GetState(): dict<number>
6183 return this.state
6184 enddef
6185 endclass
6186
6187 var ctx = Context.new()
6188 ctx.state->extend({a: 1})
6189 ctx.state['b'] = 2
6190 assert_equal({a: 1, b: 2}, ctx.GetState())
6191
6192 def F()
6193 ctx.state['c'] = 3
6194 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
6195 enddef
6196 F()
6197 assert_equal(3, ctx.state.c)
6198 ctx.state.c = 4
6199 assert_equal(4, ctx.state.c)
6200 END
6201 v9.CheckSourceSuccess(lines)
6202enddef
6203
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02006204" The following test was failing after 9.0.1914. This was caused by using a
6205" freed object from a previous method call.
6206def Test_freed_object_from_previous_method_call()
6207 var lines =<< trim END
6208 vim9script
6209
6210 class Context
6211 endclass
6212
6213 class Result
6214 endclass
6215
6216 def Failure(): Result
6217 return Result.new()
6218 enddef
6219
6220 def GetResult(ctx: Context): Result
6221 return Failure()
6222 enddef
6223
6224 def Test_GetResult()
6225 var ctx = Context.new()
6226 var result = GetResult(ctx)
6227 enddef
6228
6229 Test_GetResult()
6230 END
6231 v9.CheckSourceSuccess(lines)
6232enddef
6233
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02006234" Test for duplicate object and class variable
6235def Test_duplicate_variable()
6236 # Object variable name is same as the class variable name
6237 var lines =<< trim END
6238 vim9script
6239 class A
6240 public static sval: number
6241 public this.sval: number
6242 endclass
6243 var a = A.new()
6244 END
6245 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6246
6247 # Duplicate variable name and calling a class method
6248 lines =<< trim END
6249 vim9script
6250 class A
6251 public static sval: number
6252 public this.sval: number
6253 def F1()
6254 echo this.sval
6255 enddef
6256 static def F2()
6257 echo sval
6258 enddef
6259 endclass
6260 A.F2()
6261 END
6262 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6263
6264 # Duplicate variable with an empty constructor
6265 lines =<< trim END
6266 vim9script
6267 class A
6268 public static sval: number
6269 public this.sval: number
6270 def new()
6271 enddef
6272 endclass
6273 var a = A.new()
6274 END
6275 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
6276enddef
6277
6278" Test for using a reserved keyword as a variable name
6279def Test_reserved_varname()
6280 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
6281 'null_function', 'null_list', 'null_partial', 'null_string',
6282 'null_channel', 'null_job', 'super', 'this']
6283
6284 var lines =<< trim eval END
6285 vim9script
6286 class C
6287 public this.{kword}: list<number> = [1, 2, 3]
6288 endclass
6289 var o = C.new()
6290 END
6291 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6292
6293 lines =<< trim eval END
6294 vim9script
6295 class C
6296 public this.{kword}: list<number> = [1, 2, 3]
6297 def new()
6298 enddef
6299 endclass
6300 var o = C.new()
6301 END
6302 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6303
6304 lines =<< trim eval END
6305 vim9script
6306 class C
6307 public this.{kword}: list<number> = [1, 2, 3]
6308 def new()
6309 enddef
6310 def F()
6311 echo this.{kword}
6312 enddef
6313 endclass
6314 var o = C.new()
6315 o.F()
6316 END
6317 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
6318 endfor
6319enddef
6320
Yegappan Lakshmananf3b68d42023-09-29 22:50:02 +02006321" Test for checking the type of the arguments and the return value of a object
6322" method in an extended class.
6323def Test_extended_obj_method_type_check()
6324 var lines =<< trim END
6325 vim9script
6326
6327 class A
6328 endclass
6329 class B extends A
6330 endclass
6331 class C extends B
6332 endclass
6333
6334 class Foo
6335 def Doit(p: B): B
6336 return B.new()
6337 enddef
6338 endclass
6339
6340 class Bar extends Foo
6341 def Doit(p: A): C
6342 return C.new()
6343 enddef
6344 endclass
6345 END
6346 v9.CheckSourceSuccess(lines)
6347
6348 lines =<< trim END
6349 vim9script
6350
6351 class A
6352 endclass
6353 class B extends A
6354 endclass
6355 class C extends B
6356 endclass
6357
6358 class Foo
6359 def Doit(p: B): B
6360 return B.new()
6361 enddef
6362 endclass
6363
6364 class Bar extends Foo
6365 def Doit(p: C): B
6366 return B.new()
6367 enddef
6368 endclass
6369 END
6370 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<C>): object<B>', 20)
6371
6372 lines =<< trim END
6373 vim9script
6374
6375 class A
6376 endclass
6377 class B extends A
6378 endclass
6379 class C extends B
6380 endclass
6381
6382 class Foo
6383 def Doit(p: B): B
6384 return B.new()
6385 enddef
6386 endclass
6387
6388 class Bar extends Foo
6389 def Doit(p: B): A
6390 return A.new()
6391 enddef
6392 endclass
6393 END
6394 v9.CheckSourceFailure(lines, 'E1383: Method "Doit": type mismatch, expected func(object<B>): object<B> but got func(object<B>): object<A>', 20)
6395enddef
6396
Bram Moolenaar00b28d62022-12-08 15:32:33 +00006397" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker