blob: c643457ccacb69afd615128385c28b9179fa4303 [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.
3483def Test_object_lockvar()
3484 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
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003518" Test for a private object method
3519def Test_private_object_method()
3520 # Try calling a private method using an object (at the script level)
3521 var lines =<< trim END
3522 vim9script
3523
3524 class A
3525 def _Foo(): number
3526 return 1234
3527 enddef
3528 endclass
3529 var a = A.new()
3530 a._Foo()
3531 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003532 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003533
3534 # Try calling a private method using an object (from a def function)
3535 lines =<< trim END
3536 vim9script
3537
3538 class A
3539 def _Foo(): number
3540 return 1234
3541 enddef
3542 endclass
3543 def T()
3544 var a = A.new()
3545 a._Foo()
3546 enddef
3547 T()
3548 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003549 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003550
3551 # Use a private method from another object method (in script context)
3552 lines =<< trim END
3553 vim9script
3554
3555 class A
3556 def _Foo(): number
3557 return 1234
3558 enddef
3559 def Bar(): number
3560 return this._Foo()
3561 enddef
3562 endclass
3563 var a = A.new()
3564 assert_equal(1234, a.Bar())
3565 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003566 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003567
3568 # Use a private method from another object method (def function context)
3569 lines =<< trim END
3570 vim9script
3571
3572 class A
3573 def _Foo(): number
3574 return 1234
3575 enddef
3576 def Bar(): number
3577 return this._Foo()
3578 enddef
3579 endclass
3580 def T()
3581 var a = A.new()
3582 assert_equal(1234, a.Bar())
3583 enddef
3584 T()
3585 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003586 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003587
3588 # Try calling a private method without the "this" prefix
3589 lines =<< trim END
3590 vim9script
3591
3592 class A
3593 def _Foo(): number
3594 return 1234
3595 enddef
3596 def Bar(): number
3597 return _Foo()
3598 enddef
3599 endclass
3600 var a = A.new()
3601 a.Bar()
3602 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003603 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003604
3605 # Try calling a private method using the class name
3606 lines =<< trim END
3607 vim9script
3608
3609 class A
3610 def _Foo(): number
3611 return 1234
3612 enddef
3613 endclass
3614 A._Foo()
3615 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003616 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003617
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003618 # Define two private methods with the same name
3619 lines =<< trim END
3620 vim9script
3621
3622 class A
3623 def _Foo()
3624 enddef
3625 def _Foo()
3626 enddef
3627 endclass
3628 var a = A.new()
3629 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003630 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003631
3632 # Define a private method and a object method with the same name
3633 lines =<< trim END
3634 vim9script
3635
3636 class A
3637 def _Foo()
3638 enddef
3639 def Foo()
3640 enddef
3641 endclass
3642 var a = A.new()
3643 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003644 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003645
3646 # Define an object method and a private method with the same name
3647 lines =<< trim END
3648 vim9script
3649
3650 class A
3651 def Foo()
3652 enddef
3653 def _Foo()
3654 enddef
3655 endclass
3656 var a = A.new()
3657 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003658 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003659
3660 # Call a public method and a private method from a private method
3661 lines =<< trim END
3662 vim9script
3663
3664 class A
3665 def Foo(): number
3666 return 100
3667 enddef
3668 def _Bar(): number
3669 return 200
3670 enddef
3671 def _Baz()
3672 assert_equal(100, this.Foo())
3673 assert_equal(200, this._Bar())
3674 enddef
3675 def T()
3676 this._Baz()
3677 enddef
3678 endclass
3679 var a = A.new()
3680 a.T()
3681 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003682 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003683
3684 # Try calling a private method from another class
3685 lines =<< trim END
3686 vim9script
3687
3688 class A
3689 def _Foo(): number
3690 return 100
3691 enddef
3692 endclass
3693 class B
3694 def Foo(): number
3695 var a = A.new()
3696 a._Foo()
3697 enddef
3698 endclass
3699 var b = B.new()
3700 b.Foo()
3701 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003702 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003703
3704 # Call a private object method from a child class object method
3705 lines =<< trim END
3706 vim9script
3707 class A
3708 def _Foo(): number
3709 return 1234
3710 enddef
3711 endclass
3712 class B extends A
3713 def Bar()
3714 enddef
3715 endclass
3716 class C extends B
3717 def Baz(): number
3718 return this._Foo()
3719 enddef
3720 endclass
3721 var c = C.new()
3722 assert_equal(1234, c.Baz())
3723 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003724 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003725
3726 # Call a private object method from a child class object
3727 lines =<< trim END
3728 vim9script
3729 class A
3730 def _Foo(): number
3731 return 1234
3732 enddef
3733 endclass
3734 class B extends A
3735 def Bar()
3736 enddef
3737 endclass
3738 class C extends B
3739 def Baz(): number
3740 enddef
3741 endclass
3742 var c = C.new()
3743 assert_equal(1234, c._Foo())
3744 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003745 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003746
3747 # Using "_" prefix in a method name should fail outside of a class
3748 lines =<< trim END
3749 vim9script
3750 def _Foo(): number
3751 return 1234
3752 enddef
3753 var a = _Foo()
3754 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003755 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003756enddef
3757
3758" Test for an private class method
3759def Test_private_class_method()
3760 # Try calling a class private method (at the script level)
3761 var lines =<< trim END
3762 vim9script
3763
3764 class A
3765 static def _Foo(): number
3766 return 1234
3767 enddef
3768 endclass
3769 A._Foo()
3770 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003771 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 8)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003772
3773 # Try calling a class private method (from a def function)
3774 lines =<< trim END
3775 vim9script
3776
3777 class A
3778 static def _Foo(): number
3779 return 1234
3780 enddef
3781 endclass
3782 def T()
3783 A._Foo()
3784 enddef
3785 T()
3786 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003787 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003788
3789 # Try calling a class private method using an object (at the script level)
3790 lines =<< trim END
3791 vim9script
3792
3793 class A
3794 static def _Foo(): number
3795 return 1234
3796 enddef
3797 endclass
3798 var a = A.new()
3799 a._Foo()
3800 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003801 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 9)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003802
3803 # Try calling a class private method using an object (from a def function)
3804 lines =<< trim END
3805 vim9script
3806
3807 class A
3808 static def _Foo(): number
3809 return 1234
3810 enddef
3811 endclass
3812 def T()
3813 var a = A.new()
3814 a._Foo()
3815 enddef
3816 T()
3817 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003818 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo', 2)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003819
3820 # Use a class private method from an object method
3821 lines =<< trim END
3822 vim9script
3823
3824 class A
3825 static def _Foo(): number
3826 return 1234
3827 enddef
3828 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003829 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003830 enddef
3831 endclass
3832 var a = A.new()
3833 a.Bar()
3834 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003835 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003836
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003837 # Use a class private method from another class private method without the
3838 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003839 lines =<< trim END
3840 vim9script
3841
3842 class A
3843 static def _Foo1(): number
3844 return 1234
3845 enddef
3846 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003847 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003848 enddef
3849 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003850 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003851 enddef
3852 endclass
3853 var a = A.new()
3854 a.Bar()
3855 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003856 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003857
3858 # Declare a class method and a class private method with the same name
3859 lines =<< trim END
3860 vim9script
3861
3862 class A
3863 static def _Foo()
3864 enddef
3865 static def Foo()
3866 enddef
3867 endclass
3868 var a = A.new()
3869 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003870 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 7)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003871
3872 # Try calling a class private method from another class
3873 lines =<< trim END
3874 vim9script
3875
3876 class A
3877 static def _Foo(): number
3878 return 1234
3879 enddef
3880 endclass
3881 class B
3882 def Foo(): number
3883 return A._Foo()
3884 enddef
3885 endclass
3886 var b = B.new()
3887 assert_equal(1234, b.Foo())
3888 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003889 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003890
3891 # Call a private class method from a child class object method
3892 lines =<< trim END
3893 vim9script
3894 class A
3895 static def _Foo(): number
3896 return 1234
3897 enddef
3898 endclass
3899 class B extends A
3900 def Bar()
3901 enddef
3902 endclass
3903 class C extends B
3904 def Baz(): number
3905 return A._Foo()
3906 enddef
3907 endclass
3908 var c = C.new()
3909 assert_equal(1234, c.Baz())
3910 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003911 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003912
3913 # Call a private class method from a child class private class method
3914 lines =<< trim END
3915 vim9script
3916 class A
3917 static def _Foo(): number
3918 return 1234
3919 enddef
3920 endclass
3921 class B extends A
3922 def Bar()
3923 enddef
3924 endclass
3925 class C extends B
3926 static def Baz(): number
3927 return A._Foo()
3928 enddef
3929 endclass
3930 assert_equal(1234, C.Baz())
3931 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003932 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()', 1)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003933
3934 # Call a private class method from a child class object
3935 lines =<< trim END
3936 vim9script
3937 class A
3938 static def _Foo(): number
3939 return 1234
3940 enddef
3941 endclass
3942 class B extends A
3943 def Bar()
3944 enddef
3945 endclass
3946 class C extends B
3947 def Baz(): number
3948 enddef
3949 endclass
3950 var c = C.new()
3951 assert_equal(1234, C._Foo())
3952 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02003953 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo', 16)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003954enddef
3955
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003956" Test for using the return value of a class/object method as a function
3957" argument.
3958def Test_objmethod_funcarg()
3959 var lines =<< trim END
3960 vim9script
3961
3962 class C
3963 def Foo(): string
3964 return 'foo'
3965 enddef
3966 endclass
3967
3968 def Bar(a: number, s: string): string
3969 return s
3970 enddef
3971
3972 def Baz(c: C)
3973 assert_equal('foo', Bar(10, c.Foo()))
3974 enddef
3975
3976 var t = C.new()
3977 Baz(t)
3978 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003979 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003980
3981 lines =<< trim END
3982 vim9script
3983
3984 class C
3985 static def Foo(): string
3986 return 'foo'
3987 enddef
3988 endclass
3989
3990 def Bar(a: number, s: string): string
3991 return s
3992 enddef
3993
3994 def Baz()
3995 assert_equal('foo', Bar(10, C.Foo()))
3996 enddef
3997
3998 Baz()
3999 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004000 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02004001enddef
4002
Ernie Raelcf138d42023-09-06 20:45:03 +02004003def Test_static_inheritence()
4004 # subclasses get their own static copy
4005 var lines =<< trim END
4006 vim9script
4007
4008 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004009 static _svar: number
4010 this._mvar: number
4011 def new()
4012 _svar = 1
4013 this._mvar = 101
4014 enddef
4015 def AccessObject(): number
4016 return this._mvar
4017 enddef
4018 def AccessStaticThroughObject(): number
4019 return _svar
4020 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004021 endclass
4022
4023 class B extends A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004024 def new()
4025 this._mvar = 102
4026 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004027 endclass
4028
4029 class C extends B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004030 def new()
4031 this._mvar = 103
4032 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004033
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004034 def AccessPrivateStaticThroughClassName(): number
4035 assert_equal(1, A._svar)
4036 return 444
4037 enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02004038 endclass
4039
4040 var oa = A.new()
4041 var ob = B.new()
4042 var oc = C.new()
4043 assert_equal(101, oa.AccessObject())
4044 assert_equal(102, ob.AccessObject())
4045 assert_equal(103, oc.AccessObject())
4046
RestorerZ7fe8f432023-09-24 23:21:24 +02004047 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private variable: _svar')
Ernie Raelcf138d42023-09-06 20:45:03 +02004048
4049 # verify object properly resolves to correct static
4050 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004051 assert_equal(1, ob.AccessStaticThroughObject())
4052 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02004053 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004054 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02004055enddef
4056
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004057" Test for declaring duplicate object and class members
4058def Test_dup_member_variable()
4059 # Duplicate member variable
4060 var lines =<< trim END
4061 vim9script
4062 class C
4063 this.val = 10
4064 this.val = 20
4065 endclass
4066 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004067 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004068
4069 # Duplicate private member variable
4070 lines =<< trim END
4071 vim9script
4072 class C
4073 this._val = 10
4074 this._val = 20
4075 endclass
4076 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004077 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004078
4079 # Duplicate public member variable
4080 lines =<< trim END
4081 vim9script
4082 class C
4083 public this.val = 10
4084 public this.val = 20
4085 endclass
4086 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004087 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004088
4089 # Duplicate private member variable
4090 lines =<< trim END
4091 vim9script
4092 class C
4093 this.val = 10
4094 this._val = 20
4095 endclass
4096 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004097 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004098
4099 # Duplicate public and private member variable
4100 lines =<< trim END
4101 vim9script
4102 class C
4103 this._val = 20
4104 public this.val = 10
4105 endclass
4106 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004107 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004108
4109 # Duplicate class member variable
4110 lines =<< trim END
4111 vim9script
4112 class C
4113 static s: string = "abc"
4114 static _s: string = "def"
4115 endclass
4116 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004117 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004118
4119 # Duplicate public and private class member variable
4120 lines =<< trim END
4121 vim9script
4122 class C
4123 public static s: string = "abc"
4124 static _s: string = "def"
4125 endclass
4126 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004127 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _s', 4)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004128
4129 # Duplicate class and object member variable
4130 lines =<< trim END
4131 vim9script
4132 class C
4133 static val = 10
4134 this.val = 20
4135 def new()
4136 enddef
4137 endclass
4138 var c = C.new()
4139 assert_equal(10, C.val)
4140 assert_equal(20, c.val)
4141 END
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02004142 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 4)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004143
4144 # Duplicate object member variable in a derived class
4145 lines =<< trim END
4146 vim9script
4147 class A
4148 this.val = 10
4149 endclass
4150 class B extends A
4151 endclass
4152 class C extends B
4153 this.val = 20
4154 endclass
4155 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004156 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004157
4158 # Duplicate object private member variable in a derived class
4159 lines =<< trim END
4160 vim9script
4161 class A
4162 this._val = 10
4163 endclass
4164 class B extends A
4165 endclass
4166 class C extends B
4167 this._val = 20
4168 endclass
4169 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004170 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004171
4172 # Duplicate object private member variable in a derived class
4173 lines =<< trim END
4174 vim9script
4175 class A
4176 this.val = 10
4177 endclass
4178 class B extends A
4179 endclass
4180 class C extends B
4181 this._val = 20
4182 endclass
4183 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004184 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: _val', 9)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004185
4186 # Duplicate object member variable in a derived class
4187 lines =<< trim END
4188 vim9script
4189 class A
4190 this._val = 10
4191 endclass
4192 class B extends A
4193 endclass
4194 class C extends B
4195 this.val = 20
4196 endclass
4197 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004198 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: val', 9)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004199
4200 # Two member variables with a common prefix
4201 lines =<< trim END
4202 vim9script
4203 class A
4204 public static svar2: number
4205 public static svar: number
4206 endclass
4207 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004208 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004209enddef
4210
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004211" Test for accessing a private member outside a class in a def function
4212def Test_private_member_access_outside_class()
4213 # private object member variable
4214 var lines =<< trim END
4215 vim9script
4216 class A
4217 this._val = 10
4218 def GetVal(): number
4219 return this._val
4220 enddef
4221 endclass
4222 def T()
4223 var a = A.new()
4224 a._val = 20
4225 enddef
4226 T()
4227 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004228 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004229
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004230 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004231 lines =<< trim END
4232 vim9script
4233 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004234 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004235 endclass
4236 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004237 var a = A.new()
4238 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004239 enddef
4240 T()
4241 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004242 v9.CheckSourceFailure(lines, 'E1326: Variable not found on object "A": _a', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004243
4244 # private static member variable
4245 lines =<< trim END
4246 vim9script
4247 class A
4248 static _val = 10
4249 endclass
4250 def T()
4251 var a = A.new()
4252 var x = a._val
4253 enddef
4254 T()
4255 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004256 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004257
4258 # private static member variable
4259 lines =<< trim END
4260 vim9script
4261 class A
4262 static _val = 10
4263 endclass
4264 def T()
4265 var a = A.new()
4266 a._val = 3
4267 enddef
4268 T()
4269 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004270 v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2)
Ernie Rael18143d32023-09-04 22:30:41 +02004271
4272 # private static class variable
4273 lines =<< trim END
4274 vim9script
4275 class A
4276 static _val = 10
4277 endclass
4278 def T()
4279 var x = A._val
4280 enddef
4281 T()
4282 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004283 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1)
Ernie Rael18143d32023-09-04 22:30:41 +02004284
4285 # private static class variable
4286 lines =<< trim END
4287 vim9script
4288 class A
4289 static _val = 10
4290 endclass
4291 def T()
4292 A._val = 3
4293 enddef
4294 T()
4295 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004296 v9.CheckSourceFailure(lines, 'E1333: Cannot access private variable: _val', 1)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004297enddef
4298
4299" Test for changing the member access of an interface in a implementation class
4300def Test_change_interface_member_access()
4301 var lines =<< trim END
4302 vim9script
4303 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004304 this.val: number
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004305 endinterface
4306 class B implements A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02004307 public this.val = 10
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004308 endclass
4309 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004310 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004311
4312 lines =<< trim END
4313 vim9script
4314 interface A
4315 this.val: number
4316 endinterface
4317 class B implements A
4318 public this.val = 10
4319 endclass
4320 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004321 v9.CheckSourceFailure(lines, 'E1367: Access level of variable "val" of interface "A" is different', 7)
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004322enddef
4323
4324" Test for trying to change a readonly member from a def function
4325def Test_readonly_member_change_in_def_func()
4326 var lines =<< trim END
4327 vim9script
4328 class A
4329 this.val: number
4330 endclass
4331 def T()
4332 var a = A.new()
4333 a.val = 20
4334 enddef
4335 T()
4336 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004337 v9.CheckSourceFailure(lines, 'E1335: Variable "val" in class "A" is not writable', 2)
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004338enddef
4339
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004340" Test for reading and writing a class member from a def function
4341def Test_modify_class_member_from_def_function()
4342 var lines =<< trim END
4343 vim9script
4344 class A
4345 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004346 public static var2: list<number> = [1, 2]
4347 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004348 static _priv_var4: number = 40
4349 endclass
4350 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004351 assert_equal([1, 2], A.var2)
4352 assert_equal({a: 1, b: 2}, A.var3)
4353 A.var2 = [3, 4]
4354 A.var3 = {c: 3, d: 4}
4355 assert_equal([3, 4], A.var2)
4356 assert_equal({c: 3, d: 4}, A.var3)
RestorerZ7fe8f432023-09-24 23:21:24 +02004357 assert_fails('echo A._priv_var4', 'E1333: Cannot access private variable: _priv_var4')
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004358 enddef
4359 T()
4360 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004361 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004362enddef
4363
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004364" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004365def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004366 var lines =<< trim END
4367 vim9script
4368 class A
4369 public static svar1: list<number> = [1]
4370 public static svar2: list<number> = [2]
4371 endclass
4372
4373 A.svar1->add(3)
4374 A.svar2->add(4)
4375 assert_equal([1, 3], A.svar1)
4376 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004377
4378 def Foo()
4379 A.svar1->add(7)
4380 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004381 assert_equal([1, 3, 7], A.svar1)
4382 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004383 enddef
4384 Foo()
4385 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004386 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004387
4388 # Cannot read from a class variable using an object in script context
4389 lines =<< trim END
4390 vim9script
4391 class A
4392 public this.var1: number
4393 public static svar2: list<number> = [1]
4394 endclass
4395
4396 var a = A.new()
4397 echo a.svar2
4398 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004399 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004400
4401 # Cannot write to a class variable using an object in script context
4402 lines =<< trim END
4403 vim9script
4404 class A
4405 public this.var1: number
4406 public static svar2: list<number> = [1]
4407 endclass
4408
4409 var a = A.new()
4410 a.svar2 = [2]
4411 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004412 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004413
4414 # Cannot read from a class variable using an object in def method context
4415 lines =<< trim END
4416 vim9script
4417 class A
4418 public this.var1: number
4419 public static svar2: list<number> = [1]
4420 endclass
4421
4422 def T()
4423 var a = A.new()
4424 echo a.svar2
4425 enddef
4426 T()
4427 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004428 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004429
4430 # Cannot write to a class variable using an object in def method context
4431 lines =<< trim END
4432 vim9script
4433 class A
4434 public this.var1: number
4435 public static svar2: list<number> = [1]
4436 endclass
4437
4438 def T()
4439 var a = A.new()
4440 a.svar2 = [2]
4441 enddef
4442 T()
4443 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004444 v9.CheckSourceFailure(lines, 'E1375: Class variable "svar2" accessible only using class "A"', 2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004445enddef
4446
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004447" Test for using a interface method using a child object
4448def Test_interface_method_from_child()
4449 var lines =<< trim END
4450 vim9script
4451
4452 interface A
4453 def Foo(): string
4454 endinterface
4455
4456 class B implements A
4457 def Foo(): string
4458 return 'foo'
4459 enddef
4460 endclass
4461
4462 class C extends B
4463 def Bar(): string
4464 return 'bar'
4465 enddef
4466 endclass
4467
4468 def T1(a: A)
4469 assert_equal('foo', a.Foo())
4470 enddef
4471
4472 def T2(b: B)
4473 assert_equal('foo', b.Foo())
4474 enddef
4475
4476 var c = C.new()
4477 T1(c)
4478 T2(c)
4479 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004480 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004481enddef
4482
4483" Test for using an interface method using a child object when it is overridden
4484" by the child class.
4485" FIXME: This test fails.
4486" def Test_interface_overridden_method_from_child()
4487" var lines =<< trim END
4488" vim9script
4489"
4490" interface A
4491" def Foo(): string
4492" endinterface
4493"
4494" class B implements A
4495" def Foo(): string
4496" return 'b-foo'
4497" enddef
4498" endclass
4499"
4500" class C extends B
4501" def Bar(): string
4502" return 'bar'
4503" enddef
4504" def Foo(): string
4505" return 'c-foo'
4506" enddef
4507" endclass
4508"
4509" def T1(a: A)
4510" assert_equal('c-foo', a.Foo())
4511" enddef
4512"
4513" def T2(b: B)
4514" assert_equal('c-foo', b.Foo())
4515" enddef
4516"
4517" var c = C.new()
4518" T1(c)
4519" T2(c)
4520" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004521" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004522" enddef
4523
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004524" Test for abstract methods
4525def Test_abstract_method()
4526 # Use two abstract methods
4527 var lines =<< trim END
4528 vim9script
4529 abstract class A
4530 def M1(): number
4531 return 10
4532 enddef
4533 abstract def M2(): number
4534 abstract def M3(): number
4535 endclass
4536 class B extends A
4537 def M2(): number
4538 return 20
4539 enddef
4540 def M3(): number
4541 return 30
4542 enddef
4543 endclass
4544 var b = B.new()
4545 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
4546 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004547 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004548
4549 # Don't define an abstract method
4550 lines =<< trim END
4551 vim9script
4552 abstract class A
4553 abstract def Foo()
4554 endclass
4555 class B extends A
4556 endclass
4557 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004558 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented', 6)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004559
4560 # Use abstract method in a concrete class
4561 lines =<< trim END
4562 vim9script
4563 class A
4564 abstract def Foo()
4565 endclass
4566 class B extends A
4567 endclass
4568 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004569 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004570
4571 # Use abstract method in an interface
4572 lines =<< trim END
4573 vim9script
4574 interface A
4575 abstract def Foo()
4576 endinterface
4577 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004578 def Foo()
4579 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004580 endclass
4581 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004582 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004583
4584 # Abbreviate the "abstract" keyword
4585 lines =<< trim END
4586 vim9script
4587 class A
4588 abs def Foo()
4589 endclass
4590 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004591 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004592
4593 # Use "abstract" with a member variable
4594 lines =<< trim END
4595 vim9script
4596 abstract class A
4597 abstract this.val = 10
4598 endclass
4599 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004600 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"', 3)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004601
4602 # Use a static abstract method
4603 lines =<< trim END
4604 vim9script
4605 abstract class A
4606 abstract static def Foo(): number
4607 endclass
4608 class B extends A
4609 static def Foo(): number
4610 return 4
4611 enddef
4612 endclass
4613 assert_equal(4, B.Foo())
4614 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004615 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004616
4617 # Type mismatch between abstract method and concrete method
4618 lines =<< trim END
4619 vim9script
4620 abstract class A
4621 abstract def Foo(a: string, b: number): list<number>
4622 endclass
4623 class B extends A
4624 def Foo(a: number, b: string): list<string>
4625 return []
4626 enddef
4627 endclass
4628 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004629 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 +02004630
4631 # Use an abstract class to invoke an abstract method
4632 # FIXME: This should fail
4633 lines =<< trim END
4634 vim9script
4635 abstract class A
4636 abstract static def Foo()
4637 endclass
4638 A.Foo()
4639 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004640 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004641
4642 # Invoke an abstract method from a def function
4643 lines =<< trim END
4644 vim9script
4645 abstract class A
4646 abstract def Foo(): list<number>
4647 endclass
4648 class B extends A
4649 def Foo(): list<number>
4650 return [3, 5]
4651 enddef
4652 endclass
4653 def Bar(c: B)
4654 assert_equal([3, 5], c.Foo())
4655 enddef
4656 var b = B.new()
4657 Bar(b)
4658 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004659 v9.CheckSourceSuccess(lines)
4660enddef
4661
4662" Test for calling a class method from a subclass
4663def Test_class_method_call_from_subclass()
4664 # class method call from a subclass
4665 var lines =<< trim END
4666 vim9script
4667
4668 class A
4669 static def Foo()
4670 echo "foo"
4671 enddef
4672 endclass
4673
4674 class B extends A
4675 def Bar()
4676 Foo()
4677 enddef
4678 endclass
4679
4680 var b = B.new()
4681 b.Bar()
4682 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004683 v9.CheckSourceFailure(lines, 'E1384: Class method "Foo" accessible only inside class "A"', 1)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004684enddef
4685
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004686" Test for calling a class method using an object in a def function context and
4687" script context.
4688def Test_class_method_call_using_object()
4689 # script context
4690 var lines =<< trim END
4691 vim9script
4692 class A
4693 static def Foo(): list<string>
4694 return ['a', 'b']
4695 enddef
4696 def Bar()
4697 assert_equal(['a', 'b'], A.Foo())
4698 assert_equal(['a', 'b'], Foo())
4699 enddef
4700 endclass
4701
4702 def T()
4703 assert_equal(['a', 'b'], A.Foo())
4704 var t_a = A.new()
4705 t_a.Bar()
4706 enddef
4707
4708 assert_equal(['a', 'b'], A.Foo())
4709 var a = A.new()
4710 a.Bar()
4711 T()
4712 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004713 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004714
4715 # script context
4716 lines =<< trim END
4717 vim9script
4718 class A
4719 static def Foo(): string
4720 return 'foo'
4721 enddef
4722 endclass
4723
4724 var a = A.new()
4725 assert_equal('foo', a.Foo())
4726 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004727 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 9)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004728
4729 # def function context
4730 lines =<< trim END
4731 vim9script
4732 class A
4733 static def Foo(): string
4734 return 'foo'
4735 enddef
4736 endclass
4737
4738 def T()
4739 var a = A.new()
4740 assert_equal('foo', a.Foo())
4741 enddef
4742 T()
4743 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004744 v9.CheckSourceFailure(lines, 'E1385: Class method "Foo" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004745enddef
4746
4747def Test_class_variable()
4748 var lines =<< trim END
4749 vim9script
4750
4751 class A
4752 public static val: number = 10
4753 static def ClassFunc()
4754 assert_equal(10, val)
4755 enddef
4756 def ObjFunc()
4757 assert_equal(10, val)
4758 enddef
4759 endclass
4760
4761 class B extends A
4762 endclass
4763
4764 assert_equal(10, A.val)
4765 A.ClassFunc()
4766 var a = A.new()
4767 a.ObjFunc()
4768 var b = B.new()
4769 b.ObjFunc()
4770
4771 def T1(a1: A)
4772 a1.ObjFunc()
4773 A.ClassFunc()
4774 enddef
4775 T1(b)
4776
4777 A.val = 20
4778 assert_equal(20, A.val)
4779 END
4780 v9.CheckSourceSuccess(lines)
4781
4782 # Modifying a parent class variable from a child class method
4783 lines =<< trim END
4784 vim9script
4785
4786 class A
4787 static val: number = 10
4788 endclass
4789
4790 class B extends A
4791 static def ClassFunc()
4792 val = 20
4793 enddef
4794 endclass
4795 B.ClassFunc()
4796 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004797 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004798
4799 # Reading a parent class variable from a child class method
4800 lines =<< trim END
4801 vim9script
4802
4803 class A
4804 static val: number = 10
4805 endclass
4806
4807 class B extends A
4808 static def ClassFunc()
4809 var i = val
4810 enddef
4811 endclass
4812 B.ClassFunc()
4813 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004814 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004815
4816 # Modifying a parent class variable from a child object method
4817 lines =<< trim END
4818 vim9script
4819
4820 class A
4821 static val: number = 10
4822 endclass
4823
4824 class B extends A
4825 def ObjFunc()
4826 val = 20
4827 enddef
4828 endclass
4829 var b = B.new()
4830 b.ObjFunc()
4831 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004832 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004833
4834 # Reading a parent class variable from a child object method
4835 lines =<< trim END
4836 vim9script
4837
4838 class A
4839 static val: number = 10
4840 endclass
4841
4842 class B extends A
4843 def ObjFunc()
4844 var i = val
4845 enddef
4846 endclass
4847 var b = B.new()
4848 b.ObjFunc()
4849 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004850 v9.CheckSourceFailure(lines, 'E1374: Class variable "val" accessible only inside class "A"', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004851
4852 # Modifying a class variable using an object at script level
4853 lines =<< trim END
4854 vim9script
4855
4856 class A
4857 static val: number = 10
4858 endclass
4859 var a = A.new()
4860 a.val = 20
4861 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004862 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004863
4864 # Reading a class variable using an object at script level
4865 lines =<< trim END
4866 vim9script
4867
4868 class A
4869 static val: number = 10
4870 endclass
4871 var a = A.new()
4872 var i = a.val
4873 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004874 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004875
4876 # Modifying a class variable using an object at function level
4877 lines =<< trim END
4878 vim9script
4879
4880 class A
4881 static val: number = 10
4882 endclass
4883
4884 def T()
4885 var a = A.new()
4886 a.val = 20
4887 enddef
4888 T()
4889 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004890 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004891
4892 # Reading a class variable using an object at function level
4893 lines =<< trim END
4894 vim9script
4895
4896 class A
4897 static val: number = 10
4898 endclass
4899 def T()
4900 var a = A.new()
4901 var i = a.val
4902 enddef
4903 T()
4904 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02004905 v9.CheckSourceFailure(lines, 'E1375: Class variable "val" accessible only using class "A"', 2)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004906enddef
4907
4908" Test for using a duplicate class method and class variable in a child class
4909def Test_dup_class_member()
4910 # duplicate class variable, class method and overridden object method
4911 var lines =<< trim END
4912 vim9script
4913 class A
4914 static sval = 100
4915 static def Check()
4916 assert_equal(100, sval)
4917 enddef
4918 def GetVal(): number
4919 return sval
4920 enddef
4921 endclass
4922
4923 class B extends A
4924 static sval = 200
4925 static def Check()
4926 assert_equal(200, sval)
4927 enddef
4928 def GetVal(): number
4929 return sval
4930 enddef
4931 endclass
4932
4933 def T1(aa: A): number
4934 return aa.GetVal()
4935 enddef
4936
4937 def T2(bb: B): number
4938 return bb.GetVal()
4939 enddef
4940
4941 assert_equal(100, A.sval)
4942 assert_equal(200, B.sval)
4943 var a = A.new()
4944 assert_equal(100, a.GetVal())
4945 var b = B.new()
4946 assert_equal(200, b.GetVal())
4947 assert_equal(200, T1(b))
4948 assert_equal(200, T2(b))
4949 END
4950 v9.CheckSourceSuccess(lines)
4951
4952 # duplicate class variable and class method
4953 lines =<< trim END
4954 vim9script
4955 class A
4956 static sval = 100
4957 static def Check()
4958 assert_equal(100, sval)
4959 enddef
4960 def GetVal(): number
4961 return sval
4962 enddef
4963 endclass
4964
4965 class B extends A
4966 static sval = 200
4967 static def Check()
4968 assert_equal(200, sval)
4969 enddef
4970 endclass
4971
4972 def T1(aa: A): number
4973 return aa.GetVal()
4974 enddef
4975
4976 def T2(bb: B): number
4977 return bb.GetVal()
4978 enddef
4979
4980 assert_equal(100, A.sval)
4981 assert_equal(200, B.sval)
4982 var a = A.new()
4983 assert_equal(100, a.GetVal())
4984 var b = B.new()
4985 assert_equal(100, b.GetVal())
4986 assert_equal(100, T1(b))
4987 assert_equal(100, T2(b))
4988 END
4989 v9.CheckSourceSuccess(lines)
4990enddef
4991
4992" Test for calling an instance method using the class
4993def Test_instance_method_call_using_class()
4994 # Invoke an object method using a class in script context
4995 var lines =<< trim END
4996 vim9script
4997 class A
4998 def Foo()
4999 echo "foo"
5000 enddef
5001 endclass
5002 A.Foo()
5003 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005004 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 7)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005005
5006 # Invoke an object method using a class in def function context
5007 lines =<< trim END
5008 vim9script
5009 class A
5010 def Foo()
5011 echo "foo"
5012 enddef
5013 endclass
5014 def T()
5015 A.Foo()
5016 enddef
5017 T()
5018 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005019 v9.CheckSourceFailure(lines, 'E1386: Object method "Foo" accessible only using class "A" object', 1)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005020enddef
5021
5022" Test for duplicate class method and instance method
5023def Test_dup_classmethod_objmethod()
5024 # Duplicate instance method
5025 var lines =<< trim END
5026 vim9script
5027 class A
5028 static def Foo()
5029 enddef
5030 def Foo()
5031 enddef
5032 endclass
5033 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005034 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005035
5036 # Duplicate private instance method
5037 lines =<< trim END
5038 vim9script
5039 class A
5040 static def Foo()
5041 enddef
5042 def _Foo()
5043 enddef
5044 endclass
5045 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005046 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005047
5048 # Duplicate class method
5049 lines =<< trim END
5050 vim9script
5051 class A
5052 def Foo()
5053 enddef
5054 static def Foo()
5055 enddef
5056 endclass
5057 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005058 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005059
5060 # Duplicate private class method
5061 lines =<< trim END
5062 vim9script
5063 class A
5064 def Foo()
5065 enddef
5066 static def _Foo()
5067 enddef
5068 endclass
5069 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005070 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005071
5072 # Duplicate private class and object method
5073 lines =<< trim END
5074 vim9script
5075 class A
5076 def _Foo()
5077 enddef
5078 static def _Foo()
5079 enddef
5080 endclass
5081 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005082 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo', 6)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005083enddef
5084
5085" Test for an instance method access level comparison with parent instance
5086" methods.
5087def Test_instance_method_access_level()
5088 # Private method in subclass
5089 var lines =<< trim END
5090 vim9script
5091 class A
5092 def Foo()
5093 enddef
5094 endclass
5095 class B extends A
5096 endclass
5097 class C extends B
5098 def _Foo()
5099 enddef
5100 endclass
5101 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005102 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005103
5104 # Public method in subclass
5105 lines =<< trim END
5106 vim9script
5107 class A
5108 def _Foo()
5109 enddef
5110 endclass
5111 class B extends A
5112 endclass
5113 class C extends B
5114 def Foo()
5115 enddef
5116 endclass
5117 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005118 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"', 11)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02005119enddef
5120
5121def Test_extend_empty_class()
5122 var lines =<< trim END
5123 vim9script
5124 class A
5125 endclass
5126 class B extends A
5127 endclass
5128 class C extends B
5129 public static rw_class_var = 1
5130 public this.rw_obj_var = 2
5131 static def ClassMethod(): number
5132 return 3
5133 enddef
5134 def ObjMethod(): number
5135 return 4
5136 enddef
5137 endclass
5138 assert_equal(1, C.rw_class_var)
5139 assert_equal(3, C.ClassMethod())
5140 var c = C.new()
5141 assert_equal(2, c.rw_obj_var)
5142 assert_equal(4, c.ObjMethod())
5143 END
5144 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005145enddef
5146
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005147" A interface cannot have a static variable or a static method or a private
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005148" variable or a private method or a public variable
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005149def Test_interface_with_unsupported_members()
5150 var lines =<< trim END
5151 vim9script
5152 interface A
5153 static num: number
5154 endinterface
5155 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005156 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005157
5158 lines =<< trim END
5159 vim9script
5160 interface A
5161 static _num: number
5162 endinterface
5163 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005164 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005165
5166 lines =<< trim END
5167 vim9script
5168 interface A
5169 public static num: number
5170 endinterface
5171 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005172 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005173
5174 lines =<< trim END
5175 vim9script
5176 interface A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005177 public static num: number
5178 endinterface
5179 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005180 v9.CheckSourceFailure(lines, 'E1387: Public variable not supported in an interface', 3)
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005181
5182 lines =<< trim END
5183 vim9script
5184 interface A
5185 static _num: number
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005186 endinterface
5187 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005188 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005189
5190 lines =<< trim END
5191 vim9script
5192 interface A
5193 static def Foo(d: dict<any>): list<string>
5194 endinterface
5195 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005196 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005197
5198 lines =<< trim END
5199 vim9script
5200 interface A
5201 static def _Foo(d: dict<any>): list<string>
5202 endinterface
5203 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005204 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005205
5206 lines =<< trim END
5207 vim9script
5208 interface A
5209 this._Foo: list<string>
5210 endinterface
5211 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005212 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005213
5214 lines =<< trim END
5215 vim9script
5216 interface A
5217 def _Foo(d: dict<any>): list<string>
5218 endinterface
5219 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005220 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface', 3)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005221enddef
5222
5223" Test for extending an interface
5224def Test_extend_interface()
5225 var lines =<< trim END
5226 vim9script
5227 interface A
5228 this.var1: list<string>
5229 def Foo()
5230 endinterface
5231 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005232 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005233 def Bar()
5234 endinterface
5235 class C implements A, B
5236 this.var1 = [1, 2]
5237 def Foo()
5238 enddef
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005239 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005240 def Bar()
5241 enddef
5242 endclass
5243 END
5244 v9.CheckSourceSuccess(lines)
5245
5246 lines =<< trim END
5247 vim9script
5248 interface A
5249 def Foo()
5250 endinterface
5251 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005252 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005253 endinterface
5254 class C implements A, B
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005255 this.var2 = {a: '1'}
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005256 endclass
5257 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005258 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented', 10)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005259
5260 lines =<< trim END
5261 vim9script
5262 interface A
5263 def Foo()
5264 endinterface
5265 interface B extends A
Yegappan Lakshmanan2dede3d2023-09-27 19:02:01 +02005266 this.var2: dict<string>
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005267 endinterface
5268 class C implements A, B
5269 def Foo()
5270 enddef
5271 endclass
5272 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005273 v9.CheckSourceFailure(lines, 'E1348: Variable "var2" of interface "B" is not implemented', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005274
5275 # interface cannot extend a class
5276 lines =<< trim END
5277 vim9script
5278 class A
5279 endclass
5280 interface B extends A
5281 endinterface
5282 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005283 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005284
5285 # class cannot extend an interface
5286 lines =<< trim END
5287 vim9script
5288 interface A
5289 endinterface
5290 class B extends A
5291 endclass
5292 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005293 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A', 5)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005294
5295 # interface cannot implement another interface
5296 lines =<< trim END
5297 vim9script
5298 interface A
5299 endinterface
5300 interface B implements A
5301 endinterface
5302 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005303 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"', 4)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005304
5305 # interface cannot extend multiple interfaces
5306 lines =<< trim END
5307 vim9script
5308 interface A
5309 endinterface
5310 interface B
5311 endinterface
5312 interface C extends A, B
5313 endinterface
5314 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005315 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B', 6)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005316
5317 # Variable type in an extended interface is of different type
5318 lines =<< trim END
5319 vim9script
5320 interface A
5321 this.val1: number
5322 endinterface
5323 interface B extends A
5324 this.val2: string
5325 endinterface
5326 interface C extends B
5327 this.val1: string
5328 this.val2: number
5329 endinterface
5330 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005331 v9.CheckSourceFailure(lines, 'E1382: Variable "val1": type mismatch, expected number but got string', 11)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005332enddef
5333
5334" Test for a child class implementing an interface when some of the methods are
5335" defined in the parent class.
5336def Test_child_class_implements_interface()
5337 var lines =<< trim END
5338 vim9script
5339
5340 interface Intf
5341 def F1(): list<list<number>>
5342 def F2(): list<list<number>>
5343 def F3(): list<list<number>>
5344 this.var1: list<dict<number>>
5345 this.var2: list<dict<number>>
5346 this.var3: list<dict<number>>
5347 endinterface
5348
5349 class A
5350 def A1()
5351 enddef
5352 def F3(): list<list<number>>
5353 return [[3]]
5354 enddef
5355 this.v1: list<list<number>> = [[0]]
5356 this.var3 = [{c: 30}]
5357 endclass
5358
5359 class B extends A
5360 def B1()
5361 enddef
5362 def F2(): list<list<number>>
5363 return [[2]]
5364 enddef
5365 this.v2: list<list<number>> = [[0]]
5366 this.var2 = [{b: 20}]
5367 endclass
5368
5369 class C extends B implements Intf
5370 def C1()
5371 enddef
5372 def F1(): list<list<number>>
5373 return [[1]]
5374 enddef
5375 this.v3: list<list<number>> = [[0]]
5376 this.var1 = [{a: 10}]
5377 endclass
5378
5379 def T(if: Intf)
5380 assert_equal([[1]], if.F1())
5381 assert_equal([[2]], if.F2())
5382 assert_equal([[3]], if.F3())
5383 assert_equal([{a: 10}], if.var1)
5384 assert_equal([{b: 20}], if.var2)
5385 assert_equal([{c: 30}], if.var3)
5386 enddef
5387
5388 var c = C.new()
5389 T(c)
5390 assert_equal([[1]], c.F1())
5391 assert_equal([[2]], c.F2())
5392 assert_equal([[3]], c.F3())
5393 assert_equal([{a: 10}], c.var1)
5394 assert_equal([{b: 20}], c.var2)
5395 assert_equal([{c: 30}], c.var3)
5396 END
5397 v9.CheckSourceSuccess(lines)
5398
5399 # One of the interface methods is not found
5400 lines =<< trim END
5401 vim9script
5402
5403 interface Intf
5404 def F1()
5405 def F2()
5406 def F3()
5407 endinterface
5408
5409 class A
5410 def A1()
5411 enddef
5412 endclass
5413
5414 class B extends A
5415 def B1()
5416 enddef
5417 def F2()
5418 enddef
5419 endclass
5420
5421 class C extends B implements Intf
5422 def C1()
5423 enddef
5424 def F1()
5425 enddef
5426 endclass
5427 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005428 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented', 26)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005429
5430 # One of the interface methods is of different type
5431 lines =<< trim END
5432 vim9script
5433
5434 interface Intf
5435 def F1()
5436 def F2()
5437 def F3()
5438 endinterface
5439
5440 class A
5441 def F3(): number
5442 return 0
5443 enddef
5444 def A1()
5445 enddef
5446 endclass
5447
5448 class B extends A
5449 def B1()
5450 enddef
5451 def F2()
5452 enddef
5453 endclass
5454
5455 class C extends B implements Intf
5456 def C1()
5457 enddef
5458 def F1()
5459 enddef
5460 endclass
5461 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005462 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number', 29)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005463
5464 # One of the interface variables is not present
5465 lines =<< trim END
5466 vim9script
5467
5468 interface Intf
5469 this.var1: list<dict<number>>
5470 this.var2: list<dict<number>>
5471 this.var3: list<dict<number>>
5472 endinterface
5473
5474 class A
5475 this.v1: list<list<number>> = [[0]]
5476 endclass
5477
5478 class B extends A
5479 this.v2: list<list<number>> = [[0]]
5480 this.var2 = [{b: 20}]
5481 endclass
5482
5483 class C extends B implements Intf
5484 this.v3: list<list<number>> = [[0]]
5485 this.var1 = [{a: 10}]
5486 endclass
5487 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005488 v9.CheckSourceFailure(lines, 'E1348: Variable "var3" of interface "Intf" is not implemented', 21)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005489
5490 # One of the interface variables is of different type
5491 lines =<< trim END
5492 vim9script
5493
5494 interface Intf
5495 this.var1: list<dict<number>>
5496 this.var2: list<dict<number>>
5497 this.var3: list<dict<number>>
5498 endinterface
5499
5500 class A
5501 this.v1: list<list<number>> = [[0]]
5502 this.var3: list<dict<string>>
5503 endclass
5504
5505 class B extends A
5506 this.v2: list<list<number>> = [[0]]
5507 this.var2 = [{b: 20}]
5508 endclass
5509
5510 class C extends B implements Intf
5511 this.v3: list<list<number>> = [[0]]
5512 this.var1 = [{a: 10}]
5513 endclass
5514 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005515 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 +02005516enddef
5517
5518" Test for extending an interface with duplicate variables and methods
5519def Test_interface_extends_with_dup_members()
5520 var lines =<< trim END
5521 vim9script
5522 interface A
5523 this.n1: number
5524 def Foo1(): number
5525 endinterface
5526 interface B extends A
5527 this.n2: number
5528 this.n1: number
5529 def Foo2(): number
5530 def Foo1(): number
5531 endinterface
5532 class C implements B
5533 this.n1 = 10
5534 this.n2 = 20
5535 def Foo1(): number
5536 return 30
5537 enddef
5538 def Foo2(): number
5539 return 40
5540 enddef
5541 endclass
5542 def T1(a: A)
5543 assert_equal(10, a.n1)
5544 assert_equal(30, a.Foo1())
5545 enddef
5546 def T2(b: B)
5547 assert_equal(10, b.n1)
5548 assert_equal(20, b.n2)
5549 assert_equal(30, b.Foo1())
5550 assert_equal(40, b.Foo2())
5551 enddef
5552 var c = C.new()
5553 T1(c)
5554 T2(c)
5555 END
5556 v9.CheckSourceSuccess(lines)
5557enddef
5558
5559" Test for using "any" type for a variable in a sub-class while it has a
5560" concrete type in the interface
5561def Test_implements_using_var_type_any()
5562 var lines =<< trim END
5563 vim9script
5564 interface A
5565 this.val: list<dict<string>>
5566 endinterface
5567 class B implements A
5568 this.val = [{a: '1'}, {b: '2'}]
5569 endclass
5570 var b = B.new()
5571 assert_equal([{a: '1'}, {b: '2'}], b.val)
5572 END
5573 v9.CheckSourceSuccess(lines)
5574
5575 # initialize instance variable using a different type
5576 lines =<< trim END
5577 vim9script
5578 interface A
5579 this.val: list<dict<string>>
5580 endinterface
5581 class B implements A
5582 this.val = {a: 1, b: 2}
5583 endclass
5584 var b = B.new()
5585 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005586 v9.CheckSourceFailure(lines, 'E1382: Variable "val": type mismatch, expected list<dict<string>> but got dict<number>', 1)
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005587enddef
5588
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005589" Test for assigning to a member variable in a nested class
5590def Test_nested_object_assignment()
5591 var lines =<< trim END
5592 vim9script
5593
5594 class A
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005595 this.value: number
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005596 endclass
5597
5598 class B
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005599 this.a: A = A.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005600 endclass
5601
5602 class C
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005603 this.b: B = B.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005604 endclass
5605
5606 class D
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005607 this.c: C = C.new()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005608 endclass
5609
5610 def T(da: D)
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005611 da.c.b.a.value = 10
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005612 enddef
5613
5614 var d = D.new()
5615 T(d)
5616 END
Yegappan Lakshmananb90e3bc2023-09-28 23:06:48 +02005617 v9.CheckSourceFailure(lines, 'E1335: Variable "value" in class "A" is not writable', 1)
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005618enddef
5619
Yegappan Lakshmanan1db15142023-09-19 20:34:05 +02005620" Test for calling methods using a null object
5621def Test_null_object_method_call()
5622 # Calling a object method using a null object in script context
5623 var lines =<< trim END
5624 vim9script
5625
5626 class C
5627 def Foo()
5628 assert_report('This method should not be executed')
5629 enddef
5630 endclass
5631
5632 var o: C
5633 o.Foo()
5634 END
5635 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 10)
5636
5637 # Calling a object method using a null object in def function context
5638 lines =<< trim END
5639 vim9script
5640
5641 class C
5642 def Foo()
5643 assert_report('This method should not be executed')
5644 enddef
5645 endclass
5646
5647 def T()
5648 var o: C
5649 o.Foo()
5650 enddef
5651 T()
5652 END
5653 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
5654
5655 # Calling a object method through another class method using a null object in
5656 # script context
5657 lines =<< trim END
5658 vim9script
5659
5660 class C
5661 def Foo()
5662 assert_report('This method should not be executed')
5663 enddef
5664
5665 static def Bar(o_any: any)
5666 var o_typed: C = o_any
5667 o_typed.Foo()
5668 enddef
5669 endclass
5670
5671 var o: C
5672 C.Bar(o)
5673 END
5674 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
5675
5676 # Calling a object method through another class method using a null object in
5677 # def function context
5678 lines =<< trim END
5679 vim9script
5680
5681 class C
5682 def Foo()
5683 assert_report('This method should not be executed')
5684 enddef
5685
5686 static def Bar(o_any: any)
5687 var o_typed: C = o_any
5688 o_typed.Foo()
5689 enddef
5690 endclass
5691
5692 def T()
5693 var o: C
5694 C.Bar(o)
5695 enddef
5696 T()
5697 END
5698 v9.CheckSourceFailure(lines, 'E1360: Using a null object', 2)
5699enddef
5700
5701" Test for using a dict as an object member
5702def Test_dict_object_member()
5703 var lines =<< trim END
5704 vim9script
5705
5706 class Context
5707 public this.state: dict<number> = {}
5708 def GetState(): dict<number>
5709 return this.state
5710 enddef
5711 endclass
5712
5713 var ctx = Context.new()
5714 ctx.state->extend({a: 1})
5715 ctx.state['b'] = 2
5716 assert_equal({a: 1, b: 2}, ctx.GetState())
5717
5718 def F()
5719 ctx.state['c'] = 3
5720 assert_equal({a: 1, b: 2, c: 3}, ctx.GetState())
5721 enddef
5722 F()
5723 assert_equal(3, ctx.state.c)
5724 ctx.state.c = 4
5725 assert_equal(4, ctx.state.c)
5726 END
5727 v9.CheckSourceSuccess(lines)
5728enddef
5729
Yegappan Lakshmanan7398f362023-09-24 23:09:10 +02005730" The following test was failing after 9.0.1914. This was caused by using a
5731" freed object from a previous method call.
5732def Test_freed_object_from_previous_method_call()
5733 var lines =<< trim END
5734 vim9script
5735
5736 class Context
5737 endclass
5738
5739 class Result
5740 endclass
5741
5742 def Failure(): Result
5743 return Result.new()
5744 enddef
5745
5746 def GetResult(ctx: Context): Result
5747 return Failure()
5748 enddef
5749
5750 def Test_GetResult()
5751 var ctx = Context.new()
5752 var result = GetResult(ctx)
5753 enddef
5754
5755 Test_GetResult()
5756 END
5757 v9.CheckSourceSuccess(lines)
5758enddef
5759
Yegappan Lakshmananf057aca2023-09-28 22:28:15 +02005760" Test for duplicate object and class variable
5761def Test_duplicate_variable()
5762 # Object variable name is same as the class variable name
5763 var lines =<< trim END
5764 vim9script
5765 class A
5766 public static sval: number
5767 public this.sval: number
5768 endclass
5769 var a = A.new()
5770 END
5771 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
5772
5773 # Duplicate variable name and calling a class method
5774 lines =<< trim END
5775 vim9script
5776 class A
5777 public static sval: number
5778 public this.sval: number
5779 def F1()
5780 echo this.sval
5781 enddef
5782 static def F2()
5783 echo sval
5784 enddef
5785 endclass
5786 A.F2()
5787 END
5788 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
5789
5790 # Duplicate variable with an empty constructor
5791 lines =<< trim END
5792 vim9script
5793 class A
5794 public static sval: number
5795 public this.sval: number
5796 def new()
5797 enddef
5798 endclass
5799 var a = A.new()
5800 END
5801 v9.CheckSourceFailure(lines, 'E1369: Duplicate variable: sval', 4)
5802enddef
5803
5804" Test for using a reserved keyword as a variable name
5805def Test_reserved_varname()
5806 for kword in ['true', 'false', 'null', 'null_blob', 'null_dict',
5807 'null_function', 'null_list', 'null_partial', 'null_string',
5808 'null_channel', 'null_job', 'super', 'this']
5809
5810 var lines =<< trim eval END
5811 vim9script
5812 class C
5813 public this.{kword}: list<number> = [1, 2, 3]
5814 endclass
5815 var o = C.new()
5816 END
5817 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
5818
5819 lines =<< trim eval END
5820 vim9script
5821 class C
5822 public this.{kword}: list<number> = [1, 2, 3]
5823 def new()
5824 enddef
5825 endclass
5826 var o = C.new()
5827 END
5828 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
5829
5830 lines =<< trim eval END
5831 vim9script
5832 class C
5833 public this.{kword}: list<number> = [1, 2, 3]
5834 def new()
5835 enddef
5836 def F()
5837 echo this.{kword}
5838 enddef
5839 endclass
5840 var o = C.new()
5841 o.F()
5842 END
5843 v9.CheckSourceFailure(lines, $'E1034: Cannot use reserved name {kword}', 3)
5844 endfor
5845enddef
5846
Bram Moolenaar00b28d62022-12-08 15:32:33 +00005847" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker